blob: 947bb9604096f15d3cee71dcb83f77f2754dfc2d [file] [log] [blame]
Bob Badour9ee7d032021-10-25 16:51:48 -07001// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package compliance
16
17import (
18 "fmt"
19)
20
21// SourceSharePrivacyConflict describes an individual conflict between a source-sharing
22// condition and a source privacy condition
23type SourceSharePrivacyConflict struct {
24 SourceNode *TargetNode
25 ShareCondition LicenseCondition
26 PrivacyCondition LicenseCondition
27}
28
29// Error returns a string describing the conflict.
30func (conflict SourceSharePrivacyConflict) Error() string {
Bob Badour103eb0f2022-01-10 13:50:57 -080031 return fmt.Sprintf("%s %s and must share from %s condition\n", conflict.SourceNode.name,
32 conflict.PrivacyCondition.Name(), conflict.ShareCondition.Name())
Bob Badour9ee7d032021-10-25 16:51:48 -070033}
34
35// IsEqualTo returns true when `conflict` and `other` describe the same conflict.
36func (conflict SourceSharePrivacyConflict) IsEqualTo(other SourceSharePrivacyConflict) bool {
37 return conflict.SourceNode.name == other.SourceNode.name &&
Bob Badour103eb0f2022-01-10 13:50:57 -080038 conflict.ShareCondition == other.ShareCondition &&
39 conflict.PrivacyCondition == other.PrivacyCondition
Bob Badour9ee7d032021-10-25 16:51:48 -070040}
41
42// ConflictingSharedPrivateSource lists all of the targets where conflicting conditions to
43// share the source and to keep the source private apply to the target.
44func ConflictingSharedPrivateSource(lg *LicenseGraph) []SourceSharePrivacyConflict {
Bob Badour9ee7d032021-10-25 16:51:48 -070045
Bob Badour103eb0f2022-01-10 13:50:57 -080046 ResolveTopDownConditions(lg)
Bob Badour9ee7d032021-10-25 16:51:48 -070047 // combined is the combination of source-sharing and source privacy.
Bob Badour103eb0f2022-01-10 13:50:57 -080048 combined := WalkActionsForCondition(lg, ImpliesShared.Union(ImpliesPrivate))
Bob Badour9ee7d032021-10-25 16:51:48 -070049
50 // size is the size of the result
51 size := 0
Bob Badour085a2c22022-09-21 19:36:59 -070052 for actsOn, cs := range combined {
53 if actsOn.pure && !actsOn.LicenseConditions().MatchesAnySet(ImpliesShared) {
54 // no need to share code to build "a distribution medium"
55 continue
56 }
Bob Badour103eb0f2022-01-10 13:50:57 -080057 size += cs.Intersection(ImpliesShared).Len() * cs.Intersection(ImpliesPrivate).Len()
Bob Badour9ee7d032021-10-25 16:51:48 -070058 }
59 if size == 0 {
Bob Badour103eb0f2022-01-10 13:50:57 -080060 return nil
Bob Badour9ee7d032021-10-25 16:51:48 -070061 }
62 result := make([]SourceSharePrivacyConflict, 0, size)
Bob Badour103eb0f2022-01-10 13:50:57 -080063 for actsOn, cs := range combined {
Bob Badour085a2c22022-09-21 19:36:59 -070064 if actsOn.pure { // no need to share code for "a distribution medium"
65 continue
66 }
Bob Badour103eb0f2022-01-10 13:50:57 -080067 pconditions := cs.Intersection(ImpliesPrivate).AsList()
68 ssconditions := cs.Intersection(ImpliesShared).AsList()
Bob Badour9ee7d032021-10-25 16:51:48 -070069
70 // report all conflicting condition combinations
71 for _, p := range pconditions {
72 for _, ss := range ssconditions {
73 result = append(result, SourceSharePrivacyConflict{actsOn, ss, p})
74 }
75 }
76 }
77 return result
78}