1*9e94795aSAndroid Build Coastguard Worker// Copyright 2021 Google LLC 2*9e94795aSAndroid Build Coastguard Worker// 3*9e94795aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*9e94795aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*9e94795aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*9e94795aSAndroid Build Coastguard Worker// 7*9e94795aSAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*9e94795aSAndroid Build Coastguard Worker// 9*9e94795aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*9e94795aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*9e94795aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e94795aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*9e94795aSAndroid Build Coastguard Worker// limitations under the License. 14*9e94795aSAndroid Build Coastguard Worker 15*9e94795aSAndroid Build Coastguard Workerpackage compliance 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Workerimport ( 18*9e94795aSAndroid Build Coastguard Worker "fmt" 19*9e94795aSAndroid Build Coastguard Worker "strings" 20*9e94795aSAndroid Build Coastguard Worker) 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Worker// LicenseConditionSet identifies sets of license conditions. 23*9e94795aSAndroid Build Coastguard Workertype LicenseConditionSet LicenseCondition 24*9e94795aSAndroid Build Coastguard Worker 25*9e94795aSAndroid Build Coastguard Worker// AllLicenseConditions is the set of all recognized license conditions. 26*9e94795aSAndroid Build Coastguard Workerconst AllLicenseConditions = LicenseConditionSet(LicenseConditionMask) 27*9e94795aSAndroid Build Coastguard Worker 28*9e94795aSAndroid Build Coastguard Worker// NewLicenseConditionSet returns a set containing exactly the elements of 29*9e94795aSAndroid Build Coastguard Worker// `conditions`. 30*9e94795aSAndroid Build Coastguard Workerfunc NewLicenseConditionSet(conditions ...LicenseCondition) LicenseConditionSet { 31*9e94795aSAndroid Build Coastguard Worker cs := LicenseConditionSet(0x00) 32*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 33*9e94795aSAndroid Build Coastguard Worker cs |= LicenseConditionSet(lc) 34*9e94795aSAndroid Build Coastguard Worker } 35*9e94795aSAndroid Build Coastguard Worker return cs 36*9e94795aSAndroid Build Coastguard Worker} 37*9e94795aSAndroid Build Coastguard Worker 38*9e94795aSAndroid Build Coastguard Worker// Plus returns a new set containing all of the elements of `cs` and all of the 39*9e94795aSAndroid Build Coastguard Worker// `conditions`. 40*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Plus(conditions ...LicenseCondition) LicenseConditionSet { 41*9e94795aSAndroid Build Coastguard Worker result := cs 42*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 43*9e94795aSAndroid Build Coastguard Worker result |= LicenseConditionSet(lc) 44*9e94795aSAndroid Build Coastguard Worker } 45*9e94795aSAndroid Build Coastguard Worker return result 46*9e94795aSAndroid Build Coastguard Worker} 47*9e94795aSAndroid Build Coastguard Worker 48*9e94795aSAndroid Build Coastguard Worker// Union returns a new set containing all of the elements of `cs` and all of the 49*9e94795aSAndroid Build Coastguard Worker// elements of the `other` sets. 50*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Union(other ...LicenseConditionSet) LicenseConditionSet { 51*9e94795aSAndroid Build Coastguard Worker result := cs 52*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 53*9e94795aSAndroid Build Coastguard Worker result |= ls 54*9e94795aSAndroid Build Coastguard Worker } 55*9e94795aSAndroid Build Coastguard Worker return result 56*9e94795aSAndroid Build Coastguard Worker} 57*9e94795aSAndroid Build Coastguard Worker 58*9e94795aSAndroid Build Coastguard Worker// MatchingAny returns the subset of `cs` equal to any of the `conditions`. 59*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) MatchingAny(conditions ...LicenseCondition) LicenseConditionSet { 60*9e94795aSAndroid Build Coastguard Worker result := LicenseConditionSet(0x00) 61*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 62*9e94795aSAndroid Build Coastguard Worker result |= cs & LicenseConditionSet(lc) 63*9e94795aSAndroid Build Coastguard Worker } 64*9e94795aSAndroid Build Coastguard Worker return result 65*9e94795aSAndroid Build Coastguard Worker} 66*9e94795aSAndroid Build Coastguard Worker 67*9e94795aSAndroid Build Coastguard Worker// MatchingAnySet returns the subset of `cs` that are members of any of the 68*9e94795aSAndroid Build Coastguard Worker// `other` sets. 69*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) MatchingAnySet(other ...LicenseConditionSet) LicenseConditionSet { 70*9e94795aSAndroid Build Coastguard Worker result := LicenseConditionSet(0x00) 71*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 72*9e94795aSAndroid Build Coastguard Worker result |= cs & ls 73*9e94795aSAndroid Build Coastguard Worker } 74*9e94795aSAndroid Build Coastguard Worker return result 75*9e94795aSAndroid Build Coastguard Worker} 76*9e94795aSAndroid Build Coastguard Worker 77*9e94795aSAndroid Build Coastguard Worker// HasAny returns true when `cs` contains at least one of the `conditions`. 78*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) HasAny(conditions ...LicenseCondition) bool { 79*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 80*9e94795aSAndroid Build Coastguard Worker if 0x0000 != (cs & LicenseConditionSet(lc)) { 81*9e94795aSAndroid Build Coastguard Worker return true 82*9e94795aSAndroid Build Coastguard Worker } 83*9e94795aSAndroid Build Coastguard Worker } 84*9e94795aSAndroid Build Coastguard Worker return false 85*9e94795aSAndroid Build Coastguard Worker} 86*9e94795aSAndroid Build Coastguard Worker 87*9e94795aSAndroid Build Coastguard Worker// MatchesAnySet returns true when `cs` has a non-empty intersection with at 88*9e94795aSAndroid Build Coastguard Worker// least one of the `other` condition sets. 89*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) MatchesAnySet(other ...LicenseConditionSet) bool { 90*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 91*9e94795aSAndroid Build Coastguard Worker if 0x0000 != (cs & ls) { 92*9e94795aSAndroid Build Coastguard Worker return true 93*9e94795aSAndroid Build Coastguard Worker } 94*9e94795aSAndroid Build Coastguard Worker } 95*9e94795aSAndroid Build Coastguard Worker return false 96*9e94795aSAndroid Build Coastguard Worker} 97*9e94795aSAndroid Build Coastguard Worker 98*9e94795aSAndroid Build Coastguard Worker// HasAll returns true when `cs` contains every one of the `conditions`. 99*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) HasAll(conditions ...LicenseCondition) bool { 100*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 101*9e94795aSAndroid Build Coastguard Worker if 0x0000 == (cs & LicenseConditionSet(lc)) { 102*9e94795aSAndroid Build Coastguard Worker return false 103*9e94795aSAndroid Build Coastguard Worker } 104*9e94795aSAndroid Build Coastguard Worker } 105*9e94795aSAndroid Build Coastguard Worker return true 106*9e94795aSAndroid Build Coastguard Worker} 107*9e94795aSAndroid Build Coastguard Worker 108*9e94795aSAndroid Build Coastguard Worker// MatchesEverySet returns true when `cs` has a non-empty intersection with 109*9e94795aSAndroid Build Coastguard Worker// each of the `other` condition sets. 110*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) MatchesEverySet(other ...LicenseConditionSet) bool { 111*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 112*9e94795aSAndroid Build Coastguard Worker if 0x0000 == (cs & ls) { 113*9e94795aSAndroid Build Coastguard Worker return false 114*9e94795aSAndroid Build Coastguard Worker } 115*9e94795aSAndroid Build Coastguard Worker } 116*9e94795aSAndroid Build Coastguard Worker return true 117*9e94795aSAndroid Build Coastguard Worker} 118*9e94795aSAndroid Build Coastguard Worker 119*9e94795aSAndroid Build Coastguard Worker// Intersection returns the subset of `cs` that are members of every `other` 120*9e94795aSAndroid Build Coastguard Worker// set. 121*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Intersection(other ...LicenseConditionSet) LicenseConditionSet { 122*9e94795aSAndroid Build Coastguard Worker result := cs 123*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 124*9e94795aSAndroid Build Coastguard Worker result &= ls 125*9e94795aSAndroid Build Coastguard Worker } 126*9e94795aSAndroid Build Coastguard Worker return result 127*9e94795aSAndroid Build Coastguard Worker} 128*9e94795aSAndroid Build Coastguard Worker 129*9e94795aSAndroid Build Coastguard Worker// Minus returns the subset of `cs` that are not equaal to any `conditions`. 130*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Minus(conditions ...LicenseCondition) LicenseConditionSet { 131*9e94795aSAndroid Build Coastguard Worker result := cs 132*9e94795aSAndroid Build Coastguard Worker for _, lc := range conditions { 133*9e94795aSAndroid Build Coastguard Worker result &^= LicenseConditionSet(lc) 134*9e94795aSAndroid Build Coastguard Worker } 135*9e94795aSAndroid Build Coastguard Worker return result 136*9e94795aSAndroid Build Coastguard Worker} 137*9e94795aSAndroid Build Coastguard Worker 138*9e94795aSAndroid Build Coastguard Worker// Difference returns the subset of `cs` that are not members of any `other` 139*9e94795aSAndroid Build Coastguard Worker// set. 140*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Difference(other ...LicenseConditionSet) LicenseConditionSet { 141*9e94795aSAndroid Build Coastguard Worker result := cs 142*9e94795aSAndroid Build Coastguard Worker for _, ls := range other { 143*9e94795aSAndroid Build Coastguard Worker result &^= ls 144*9e94795aSAndroid Build Coastguard Worker } 145*9e94795aSAndroid Build Coastguard Worker return result 146*9e94795aSAndroid Build Coastguard Worker} 147*9e94795aSAndroid Build Coastguard Worker 148*9e94795aSAndroid Build Coastguard Worker// Len returns the number of license conditions in the set. 149*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Len() int { 150*9e94795aSAndroid Build Coastguard Worker size := 0 151*9e94795aSAndroid Build Coastguard Worker for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { 152*9e94795aSAndroid Build Coastguard Worker if 0x00 != (cs & lc) { 153*9e94795aSAndroid Build Coastguard Worker size++ 154*9e94795aSAndroid Build Coastguard Worker } 155*9e94795aSAndroid Build Coastguard Worker } 156*9e94795aSAndroid Build Coastguard Worker return size 157*9e94795aSAndroid Build Coastguard Worker} 158*9e94795aSAndroid Build Coastguard Worker 159*9e94795aSAndroid Build Coastguard Worker// AsList returns an array of the license conditions in the set. 160*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) AsList() []LicenseCondition { 161*9e94795aSAndroid Build Coastguard Worker result := make([]LicenseCondition, 0, cs.Len()) 162*9e94795aSAndroid Build Coastguard Worker for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { 163*9e94795aSAndroid Build Coastguard Worker if 0x00 != (cs & lc) { 164*9e94795aSAndroid Build Coastguard Worker result = append(result, LicenseCondition(lc)) 165*9e94795aSAndroid Build Coastguard Worker } 166*9e94795aSAndroid Build Coastguard Worker } 167*9e94795aSAndroid Build Coastguard Worker return result 168*9e94795aSAndroid Build Coastguard Worker} 169*9e94795aSAndroid Build Coastguard Worker 170*9e94795aSAndroid Build Coastguard Worker// Names returns an array of the names of the license conditions in the set. 171*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) Names() []string { 172*9e94795aSAndroid Build Coastguard Worker result := make([]string, 0, cs.Len()) 173*9e94795aSAndroid Build Coastguard Worker for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 { 174*9e94795aSAndroid Build Coastguard Worker if 0x00 != (cs & lc) { 175*9e94795aSAndroid Build Coastguard Worker result = append(result, LicenseCondition(lc).Name()) 176*9e94795aSAndroid Build Coastguard Worker } 177*9e94795aSAndroid Build Coastguard Worker } 178*9e94795aSAndroid Build Coastguard Worker return result 179*9e94795aSAndroid Build Coastguard Worker} 180*9e94795aSAndroid Build Coastguard Worker 181*9e94795aSAndroid Build Coastguard Worker// IsEmpty returns true when the set contains no license conditions. 182*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) IsEmpty() bool { 183*9e94795aSAndroid Build Coastguard Worker return 0x00 == (cs & AllLicenseConditions) 184*9e94795aSAndroid Build Coastguard Worker} 185*9e94795aSAndroid Build Coastguard Worker 186*9e94795aSAndroid Build Coastguard Worker// String returns a human-readable string representation of the set. 187*9e94795aSAndroid Build Coastguard Workerfunc (cs LicenseConditionSet) String() string { 188*9e94795aSAndroid Build Coastguard Worker return fmt.Sprintf("{%s}", strings.Join(cs.Names(), "|")) 189*9e94795aSAndroid Build Coastguard Worker} 190