blob: 3e778bb69f36a2280360de6670ce304d3766f0dd [file] [log] [blame]
Jingwen Chen30f5aaa2020-11-19 05:38:02 -05001// Copyright 2020 Google Inc. All rights reserved.
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 bazel
16
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000017import (
18 "fmt"
Jingwen Chen63930982021-03-24 10:04:33 -040019 "path/filepath"
Liz Kammera060c452021-03-24 10:14:47 -040020 "regexp"
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000021 "sort"
22)
Jingwen Chen5d864492021-02-24 07:20:12 -050023
Jingwen Chen73850672020-12-14 08:25:34 -050024// BazelTargetModuleProperties contain properties and metadata used for
25// Blueprint to BUILD file conversion.
26type BazelTargetModuleProperties struct {
27 // The Bazel rule class for this target.
Liz Kammerfc46bc12021-02-19 11:06:17 -050028 Rule_class string `blueprint:"mutated"`
Jingwen Chen40067de2021-01-26 21:58:43 -050029
30 // The target label for the bzl file containing the definition of the rule class.
Liz Kammerfc46bc12021-02-19 11:06:17 -050031 Bzl_load_location string `blueprint:"mutated"`
Jingwen Chen73850672020-12-14 08:25:34 -050032}
Liz Kammer356f7d42021-01-26 09:18:53 -050033
Jingwen Chenfb4692a2021-02-07 10:05:16 -050034const BazelTargetModuleNamePrefix = "__bp2build__"
35
Liz Kammera060c452021-03-24 10:14:47 -040036var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
37
Jingwen Chen38e62642021-04-19 05:00:15 +000038// Label is used to represent a Bazel compatible Label. Also stores the original
39// bp text to support string replacement.
Liz Kammer356f7d42021-01-26 09:18:53 -050040type Label struct {
Jingwen Chen38e62642021-04-19 05:00:15 +000041 // The string representation of a Bazel target label. This can be a relative
42 // or fully qualified label. These labels are used for generating BUILD
43 // files with bp2build.
44 Label string
45
46 // The original Soong/Blueprint module name that the label was derived from.
47 // This is used for replacing references to the original name with the new
48 // label, for example in genrule cmds.
49 //
50 // While there is a reversible 1:1 mapping from the module name to Bazel
51 // label with bp2build that could make computing the original module name
52 // from the label automatic, it is not the case for handcrafted targets,
53 // where modules can have a custom label mapping through the { bazel_module:
54 // { label: <label> } } property.
55 //
56 // With handcrafted labels, those modules don't go through bp2build
57 // conversion, but relies on handcrafted targets in the source tree.
58 OriginalModuleName string
Liz Kammer356f7d42021-01-26 09:18:53 -050059}
60
61// LabelList is used to represent a list of Bazel labels.
62type LabelList struct {
63 Includes []Label
64 Excludes []Label
65}
66
Jingwen Chen63930982021-03-24 10:04:33 -040067// uniqueParentDirectories returns a list of the unique parent directories for
68// all files in ll.Includes.
69func (ll *LabelList) uniqueParentDirectories() []string {
70 dirMap := map[string]bool{}
71 for _, label := range ll.Includes {
72 dirMap[filepath.Dir(label.Label)] = true
73 }
74 dirs := []string{}
75 for dir := range dirMap {
76 dirs = append(dirs, dir)
77 }
78 return dirs
79}
80
Liz Kammer356f7d42021-01-26 09:18:53 -050081// Append appends the fields of other labelList to the corresponding fields of ll.
82func (ll *LabelList) Append(other LabelList) {
83 if len(ll.Includes) > 0 || len(other.Includes) > 0 {
84 ll.Includes = append(ll.Includes, other.Includes...)
85 }
86 if len(ll.Excludes) > 0 || len(other.Excludes) > 0 {
87 ll.Excludes = append(other.Excludes, other.Excludes...)
88 }
89}
Jingwen Chen5d864492021-02-24 07:20:12 -050090
Jingwen Chened9c17d2021-04-13 07:14:55 +000091// UniqueSortedBazelLabels takes a []Label and deduplicates the labels, and returns
92// the slice in a sorted order.
93func UniqueSortedBazelLabels(originalLabels []Label) []Label {
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000094 uniqueLabelsSet := make(map[Label]bool)
95 for _, l := range originalLabels {
96 uniqueLabelsSet[l] = true
97 }
98 var uniqueLabels []Label
99 for l, _ := range uniqueLabelsSet {
100 uniqueLabels = append(uniqueLabels, l)
101 }
102 sort.SliceStable(uniqueLabels, func(i, j int) bool {
103 return uniqueLabels[i].Label < uniqueLabels[j].Label
104 })
105 return uniqueLabels
106}
107
108func UniqueBazelLabelList(originalLabelList LabelList) LabelList {
109 var uniqueLabelList LabelList
Jingwen Chened9c17d2021-04-13 07:14:55 +0000110 uniqueLabelList.Includes = UniqueSortedBazelLabels(originalLabelList.Includes)
111 uniqueLabelList.Excludes = UniqueSortedBazelLabels(originalLabelList.Excludes)
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000112 return uniqueLabelList
113}
114
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000115// Subtract needle from haystack
116func SubtractStrings(haystack []string, needle []string) []string {
117 // This is really a set
118 remainder := make(map[string]bool)
119
120 for _, s := range haystack {
121 remainder[s] = true
122 }
123 for _, s := range needle {
124 delete(remainder, s)
125 }
126
127 var strings []string
128 for s, _ := range remainder {
129 strings = append(strings, s)
130 }
131
132 sort.SliceStable(strings, func(i, j int) bool {
133 return strings[i] < strings[j]
134 })
135
136 return strings
137}
138
139// Subtract needle from haystack
140func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
141 // This is really a set
142 remainder := make(map[Label]bool)
143
144 for _, label := range haystack {
145 remainder[label] = true
146 }
147 for _, label := range needle {
148 delete(remainder, label)
149 }
150
151 var labels []Label
152 for label, _ := range remainder {
153 labels = append(labels, label)
154 }
155
156 sort.SliceStable(labels, func(i, j int) bool {
157 return labels[i].Label < labels[j].Label
158 })
159
160 return labels
161}
162
Chris Parsons484e50a2021-05-13 15:13:04 -0400163// Appends two LabelLists, returning the combined list.
164func AppendBazelLabelLists(a LabelList, b LabelList) LabelList {
165 var result LabelList
166 result.Includes = append(a.Includes, b.Includes...)
167 result.Excludes = append(a.Excludes, b.Excludes...)
168 return result
169}
170
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000171// Subtract needle from haystack
172func SubtractBazelLabelList(haystack LabelList, needle LabelList) LabelList {
173 var result LabelList
174 result.Includes = SubtractBazelLabels(haystack.Includes, needle.Includes)
175 // NOTE: Excludes are intentionally not subtracted
176 result.Excludes = haystack.Excludes
177 return result
178}
179
Jingwen Chen07027912021-03-15 06:02:43 -0400180const (
Jingwen Chen91220d72021-03-24 02:18:33 -0400181 // ArchType names in arch.go
Jingwen Chen07027912021-03-15 06:02:43 -0400182 ARCH_ARM = "arm"
183 ARCH_ARM64 = "arm64"
Jingwen Chen91220d72021-03-24 02:18:33 -0400184 ARCH_X86 = "x86"
185 ARCH_X86_64 = "x86_64"
186
187 // OsType names in arch.go
188 OS_ANDROID = "android"
189 OS_DARWIN = "darwin"
190 OS_FUCHSIA = "fuchsia"
191 OS_LINUX = "linux_glibc"
192 OS_LINUX_BIONIC = "linux_bionic"
193 OS_WINDOWS = "windows"
Jingwen Chene32e9e02021-04-23 09:17:24 +0000194
195 // This is the string representation of the default condition wherever a
196 // configurable attribute is used in a select statement, i.e.
197 // //conditions:default for Bazel.
198 //
199 // This is consistently named "conditions_default" to mirror the Soong
200 // config variable default key in an Android.bp file, although there's no
201 // integration with Soong config variables (yet).
202 CONDITIONS_DEFAULT = "conditions_default"
Jingwen Chen07027912021-03-15 06:02:43 -0400203)
204
205var (
Jingwen Chenc1c26502021-04-05 10:35:13 +0000206 // These are the list of OSes and architectures with a Bazel config_setting
207 // and constraint value equivalent. These exist in arch.go, but the android
208 // package depends on the bazel package, so a cyclic dependency prevents
209 // using those variables here.
Jingwen Chen91220d72021-03-24 02:18:33 -0400210
211 // A map of architectures to the Bazel label of the constraint_value
212 // for the @platforms//cpu:cpu constraint_setting
213 PlatformArchMap = map[string]string{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000214 ARCH_ARM: "//build/bazel/platforms/arch:arm",
215 ARCH_ARM64: "//build/bazel/platforms/arch:arm64",
216 ARCH_X86: "//build/bazel/platforms/arch:x86",
217 ARCH_X86_64: "//build/bazel/platforms/arch:x86_64",
218 CONDITIONS_DEFAULT: "//conditions:default", // The default condition of as arch select map.
Jingwen Chen91220d72021-03-24 02:18:33 -0400219 }
220
221 // A map of target operating systems to the Bazel label of the
222 // constraint_value for the @platforms//os:os constraint_setting
223 PlatformOsMap = map[string]string{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000224 OS_ANDROID: "//build/bazel/platforms/os:android",
225 OS_DARWIN: "//build/bazel/platforms/os:darwin",
226 OS_FUCHSIA: "//build/bazel/platforms/os:fuchsia",
227 OS_LINUX: "//build/bazel/platforms/os:linux",
228 OS_LINUX_BIONIC: "//build/bazel/platforms/os:linux_bionic",
229 OS_WINDOWS: "//build/bazel/platforms/os:windows",
230 CONDITIONS_DEFAULT: "//conditions:default", // The default condition of an os select map.
Jingwen Chen91220d72021-03-24 02:18:33 -0400231 }
Jingwen Chen07027912021-03-15 06:02:43 -0400232)
233
Jingwen Chenc1c26502021-04-05 10:35:13 +0000234type Attribute interface {
235 HasConfigurableValues() bool
236}
237
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200238// Represents an attribute whose value is a single label
239type LabelAttribute struct {
Lukacs T. Berki598dd002021-05-05 09:00:01 +0200240 Value Label
241 X86 Label
242 X86_64 Label
243 Arm Label
244 Arm64 Label
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200245}
246
Lukacs T. Berki598dd002021-05-05 09:00:01 +0200247func (attr *LabelAttribute) GetValueForArch(arch string) Label {
248 switch arch {
249 case ARCH_ARM:
250 return attr.Arm
251 case ARCH_ARM64:
252 return attr.Arm64
253 case ARCH_X86:
254 return attr.X86
255 case ARCH_X86_64:
256 return attr.X86_64
257 case CONDITIONS_DEFAULT:
258 return attr.Value
259 default:
260 panic("Invalid arch type")
261 }
262}
263
264func (attr *LabelAttribute) SetValueForArch(arch string, value Label) {
265 switch arch {
266 case ARCH_ARM:
267 attr.Arm = value
268 case ARCH_ARM64:
269 attr.Arm64 = value
270 case ARCH_X86:
271 attr.X86 = value
272 case ARCH_X86_64:
273 attr.X86_64 = value
274 default:
275 panic("Invalid arch type")
276 }
277}
278
279func (attr LabelAttribute) HasConfigurableValues() bool {
280 return attr.Arm.Label != "" || attr.Arm64.Label != "" || attr.X86.Label != "" || attr.X86_64.Label != ""
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200281}
282
Jingwen Chen07027912021-03-15 06:02:43 -0400283// Arch-specific label_list typed Bazel attribute values. This should correspond
284// to the types of architectures supported for compilation in arch.go.
285type labelListArchValues struct {
286 X86 LabelList
287 X86_64 LabelList
288 Arm LabelList
289 Arm64 LabelList
Jingwen Chen91220d72021-03-24 02:18:33 -0400290 Common LabelList
Jingwen Chene32e9e02021-04-23 09:17:24 +0000291
292 ConditionsDefault LabelList
Jingwen Chen91220d72021-03-24 02:18:33 -0400293}
294
295type labelListOsValues struct {
296 Android LabelList
297 Darwin LabelList
298 Fuchsia LabelList
299 Linux LabelList
300 LinuxBionic LabelList
301 Windows LabelList
Jingwen Chene32e9e02021-04-23 09:17:24 +0000302
303 ConditionsDefault LabelList
Jingwen Chen07027912021-03-15 06:02:43 -0400304}
305
306// LabelListAttribute is used to represent a list of Bazel labels as an
307// attribute.
308type LabelListAttribute struct {
309 // The non-arch specific attribute label list Value. Required.
310 Value LabelList
311
312 // The arch-specific attribute label list values. Optional. If used, these
313 // are generated in a select statement and appended to the non-arch specific
314 // label list Value.
315 ArchValues labelListArchValues
Jingwen Chen91220d72021-03-24 02:18:33 -0400316
317 // The os-specific attribute label list values. Optional. If used, these
318 // are generated in a select statement and appended to the non-os specific
319 // label list Value.
320 OsValues labelListOsValues
Jingwen Chen07027912021-03-15 06:02:43 -0400321}
322
323// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
324func MakeLabelListAttribute(value LabelList) LabelListAttribute {
325 return LabelListAttribute{Value: UniqueBazelLabelList(value)}
326}
327
Jingwen Chened9c17d2021-04-13 07:14:55 +0000328// Append all values, including os and arch specific ones, from another
Jingwen Chen63930982021-03-24 10:04:33 -0400329// LabelListAttribute to this LabelListAttribute.
330func (attrs *LabelListAttribute) Append(other LabelListAttribute) {
331 for arch := range PlatformArchMap {
332 this := attrs.GetValueForArch(arch)
333 that := other.GetValueForArch(arch)
334 this.Append(that)
335 attrs.SetValueForArch(arch, this)
336 }
337
338 for os := range PlatformOsMap {
339 this := attrs.GetValueForOS(os)
340 that := other.GetValueForOS(os)
341 this.Append(that)
342 attrs.SetValueForOS(os, this)
343 }
344
345 attrs.Value.Append(other.Value)
346}
347
Jingwen Chen07027912021-03-15 06:02:43 -0400348// HasArchSpecificValues returns true if the attribute contains
349// architecture-specific label_list values.
Jingwen Chenc1c26502021-04-05 10:35:13 +0000350func (attrs LabelListAttribute) HasConfigurableValues() bool {
351 for arch := range PlatformArchMap {
Jingwen Chen91220d72021-03-24 02:18:33 -0400352 if len(attrs.GetValueForArch(arch).Includes) > 0 {
353 return true
354 }
355 }
356
Jingwen Chenc1c26502021-04-05 10:35:13 +0000357 for os := range PlatformOsMap {
Jingwen Chen91220d72021-03-24 02:18:33 -0400358 if len(attrs.GetValueForOS(os).Includes) > 0 {
Jingwen Chen07027912021-03-15 06:02:43 -0400359 return true
360 }
361 }
362 return false
363}
364
Jingwen Chen91220d72021-03-24 02:18:33 -0400365func (attrs *LabelListAttribute) archValuePtrs() map[string]*LabelList {
366 return map[string]*LabelList{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000367 ARCH_X86: &attrs.ArchValues.X86,
368 ARCH_X86_64: &attrs.ArchValues.X86_64,
369 ARCH_ARM: &attrs.ArchValues.Arm,
370 ARCH_ARM64: &attrs.ArchValues.Arm64,
371 CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault,
Jingwen Chen91220d72021-03-24 02:18:33 -0400372 }
373}
374
Jingwen Chen07027912021-03-15 06:02:43 -0400375// GetValueForArch returns the label_list attribute value for an architecture.
376func (attrs *LabelListAttribute) GetValueForArch(arch string) LabelList {
Jingwen Chen91220d72021-03-24 02:18:33 -0400377 var v *LabelList
378 if v = attrs.archValuePtrs()[arch]; v == nil {
Jingwen Chen07027912021-03-15 06:02:43 -0400379 panic(fmt.Errorf("Unknown arch: %s", arch))
380 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400381 return *v
Jingwen Chen07027912021-03-15 06:02:43 -0400382}
383
384// SetValueForArch sets the label_list attribute value for an architecture.
385func (attrs *LabelListAttribute) SetValueForArch(arch string, value LabelList) {
Jingwen Chen91220d72021-03-24 02:18:33 -0400386 var v *LabelList
387 if v = attrs.archValuePtrs()[arch]; v == nil {
Jingwen Chen07027912021-03-15 06:02:43 -0400388 panic(fmt.Errorf("Unknown arch: %s", arch))
389 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400390 *v = value
391}
392
393func (attrs *LabelListAttribute) osValuePtrs() map[string]*LabelList {
394 return map[string]*LabelList{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000395 OS_ANDROID: &attrs.OsValues.Android,
396 OS_DARWIN: &attrs.OsValues.Darwin,
397 OS_FUCHSIA: &attrs.OsValues.Fuchsia,
398 OS_LINUX: &attrs.OsValues.Linux,
399 OS_LINUX_BIONIC: &attrs.OsValues.LinuxBionic,
400 OS_WINDOWS: &attrs.OsValues.Windows,
401 CONDITIONS_DEFAULT: &attrs.OsValues.ConditionsDefault,
Jingwen Chen91220d72021-03-24 02:18:33 -0400402 }
403}
404
405// GetValueForOS returns the label_list attribute value for an OS target.
406func (attrs *LabelListAttribute) GetValueForOS(os string) LabelList {
407 var v *LabelList
408 if v = attrs.osValuePtrs()[os]; v == nil {
409 panic(fmt.Errorf("Unknown os: %s", os))
410 }
411 return *v
412}
413
414// SetValueForArch sets the label_list attribute value for an OS target.
415func (attrs *LabelListAttribute) SetValueForOS(os string, value LabelList) {
416 var v *LabelList
417 if v = attrs.osValuePtrs()[os]; v == nil {
418 panic(fmt.Errorf("Unknown os: %s", os))
419 }
420 *v = value
Jingwen Chen07027912021-03-15 06:02:43 -0400421}
422
Jingwen Chen5d864492021-02-24 07:20:12 -0500423// StringListAttribute corresponds to the string_list Bazel attribute type with
424// support for additional metadata, like configurations.
425type StringListAttribute struct {
426 // The base value of the string list attribute.
427 Value []string
428
Jingwen Chenc1c26502021-04-05 10:35:13 +0000429 // The arch-specific attribute string list values. Optional. If used, these
430 // are generated in a select statement and appended to the non-arch specific
431 // label list Value.
Jingwen Chen5d864492021-02-24 07:20:12 -0500432 ArchValues stringListArchValues
Jingwen Chenc1c26502021-04-05 10:35:13 +0000433
434 // The os-specific attribute string list values. Optional. If used, these
435 // are generated in a select statement and appended to the non-os specific
436 // label list Value.
437 OsValues stringListOsValues
Jingwen Chen5d864492021-02-24 07:20:12 -0500438}
439
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000440// MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value.
441func MakeStringListAttribute(value []string) StringListAttribute {
442 // NOTE: These strings are not necessarily unique or sorted.
443 return StringListAttribute{Value: value}
444}
445
Jingwen Chen5d864492021-02-24 07:20:12 -0500446// Arch-specific string_list typed Bazel attribute values. This should correspond
447// to the types of architectures supported for compilation in arch.go.
448type stringListArchValues struct {
Jingwen Chen07027912021-03-15 06:02:43 -0400449 X86 []string
450 X86_64 []string
451 Arm []string
452 Arm64 []string
Jingwen Chen91220d72021-03-24 02:18:33 -0400453 Common []string
Jingwen Chene32e9e02021-04-23 09:17:24 +0000454
455 ConditionsDefault []string
Jingwen Chen5d864492021-02-24 07:20:12 -0500456}
457
Jingwen Chenc1c26502021-04-05 10:35:13 +0000458type stringListOsValues struct {
459 Android []string
460 Darwin []string
461 Fuchsia []string
462 Linux []string
463 LinuxBionic []string
464 Windows []string
Jingwen Chene32e9e02021-04-23 09:17:24 +0000465
466 ConditionsDefault []string
Jingwen Chenc1c26502021-04-05 10:35:13 +0000467}
468
Jingwen Chen91220d72021-03-24 02:18:33 -0400469// HasConfigurableValues returns true if the attribute contains
Jingwen Chen5d864492021-02-24 07:20:12 -0500470// architecture-specific string_list values.
Jingwen Chenc1c26502021-04-05 10:35:13 +0000471func (attrs StringListAttribute) HasConfigurableValues() bool {
472 for arch := range PlatformArchMap {
Jingwen Chen5d864492021-02-24 07:20:12 -0500473 if len(attrs.GetValueForArch(arch)) > 0 {
474 return true
475 }
476 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000477
478 for os := range PlatformOsMap {
479 if len(attrs.GetValueForOS(os)) > 0 {
480 return true
481 }
482 }
Jingwen Chen5d864492021-02-24 07:20:12 -0500483 return false
484}
485
Jingwen Chen91220d72021-03-24 02:18:33 -0400486func (attrs *StringListAttribute) archValuePtrs() map[string]*[]string {
487 return map[string]*[]string{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000488 ARCH_X86: &attrs.ArchValues.X86,
489 ARCH_X86_64: &attrs.ArchValues.X86_64,
490 ARCH_ARM: &attrs.ArchValues.Arm,
491 ARCH_ARM64: &attrs.ArchValues.Arm64,
492 CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault,
Jingwen Chen91220d72021-03-24 02:18:33 -0400493 }
494}
495
Jingwen Chen5d864492021-02-24 07:20:12 -0500496// GetValueForArch returns the string_list attribute value for an architecture.
497func (attrs *StringListAttribute) GetValueForArch(arch string) []string {
Jingwen Chen91220d72021-03-24 02:18:33 -0400498 var v *[]string
499 if v = attrs.archValuePtrs()[arch]; v == nil {
Jingwen Chen5d864492021-02-24 07:20:12 -0500500 panic(fmt.Errorf("Unknown arch: %s", arch))
501 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400502 return *v
Jingwen Chen5d864492021-02-24 07:20:12 -0500503}
504
505// SetValueForArch sets the string_list attribute value for an architecture.
506func (attrs *StringListAttribute) SetValueForArch(arch string, value []string) {
Jingwen Chen91220d72021-03-24 02:18:33 -0400507 var v *[]string
508 if v = attrs.archValuePtrs()[arch]; v == nil {
Jingwen Chen5d864492021-02-24 07:20:12 -0500509 panic(fmt.Errorf("Unknown arch: %s", arch))
510 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400511 *v = value
Jingwen Chen5d864492021-02-24 07:20:12 -0500512}
Liz Kammera060c452021-03-24 10:14:47 -0400513
Jingwen Chenc1c26502021-04-05 10:35:13 +0000514func (attrs *StringListAttribute) osValuePtrs() map[string]*[]string {
515 return map[string]*[]string{
Jingwen Chene32e9e02021-04-23 09:17:24 +0000516 OS_ANDROID: &attrs.OsValues.Android,
517 OS_DARWIN: &attrs.OsValues.Darwin,
518 OS_FUCHSIA: &attrs.OsValues.Fuchsia,
519 OS_LINUX: &attrs.OsValues.Linux,
520 OS_LINUX_BIONIC: &attrs.OsValues.LinuxBionic,
521 OS_WINDOWS: &attrs.OsValues.Windows,
522 CONDITIONS_DEFAULT: &attrs.OsValues.ConditionsDefault,
Jingwen Chenc1c26502021-04-05 10:35:13 +0000523 }
524}
525
526// GetValueForOS returns the string_list attribute value for an OS target.
527func (attrs *StringListAttribute) GetValueForOS(os string) []string {
528 var v *[]string
529 if v = attrs.osValuePtrs()[os]; v == nil {
530 panic(fmt.Errorf("Unknown os: %s", os))
531 }
532 return *v
533}
534
535// SetValueForArch sets the string_list attribute value for an OS target.
536func (attrs *StringListAttribute) SetValueForOS(os string, value []string) {
537 var v *[]string
538 if v = attrs.osValuePtrs()[os]; v == nil {
539 panic(fmt.Errorf("Unknown os: %s", os))
540 }
541 *v = value
542}
543
Jingwen Chened9c17d2021-04-13 07:14:55 +0000544// Append appends all values, including os and arch specific ones, from another
545// StringListAttribute to this StringListAttribute
546func (attrs *StringListAttribute) Append(other StringListAttribute) {
547 for arch := range PlatformArchMap {
548 this := attrs.GetValueForArch(arch)
549 that := other.GetValueForArch(arch)
550 this = append(this, that...)
551 attrs.SetValueForArch(arch, this)
552 }
553
554 for os := range PlatformOsMap {
555 this := attrs.GetValueForOS(os)
556 that := other.GetValueForOS(os)
557 this = append(this, that...)
558 attrs.SetValueForOS(os, this)
559 }
560
561 attrs.Value = append(attrs.Value, other.Value...)
562}
563
Liz Kammera060c452021-03-24 10:14:47 -0400564// TryVariableSubstitution, replace string substitution formatting within each string in slice with
565// Starlark string.format compatible tag for productVariable.
566func TryVariableSubstitutions(slice []string, productVariable string) ([]string, bool) {
567 ret := make([]string, 0, len(slice))
568 changesMade := false
569 for _, s := range slice {
570 newS, changed := TryVariableSubstitution(s, productVariable)
571 ret = append(ret, newS)
572 changesMade = changesMade || changed
573 }
574 return ret, changesMade
575}
576
577// TryVariableSubstitution, replace string substitution formatting within s with Starlark
578// string.format compatible tag for productVariable.
579func TryVariableSubstitution(s string, productVariable string) (string, bool) {
580 sub := productVariableSubstitutionPattern.ReplaceAllString(s, "{"+productVariable+"}")
581 return sub, s != sub
582}