| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 1 | // Copyright (C) 2019 The Android Open Source Project | 
|  | 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 |  | 
|  | 15 | package sdk | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "fmt" | 
| Martin Stjernholm | 191c25f | 2020-09-10 00:40:37 +0100 | [diff] [blame] | 19 | "reflect" | 
|  | 20 | "strings" | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 21 |  | 
|  | 22 | "android/soong/android" | 
|  | 23 | ) | 
|  | 24 |  | 
|  | 25 | type bpPropertySet struct { | 
|  | 26 | properties map[string]interface{} | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 27 | tags       map[string]android.BpPropertyTag | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 28 | comments   map[string]string | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 29 | order      []string | 
|  | 30 | } | 
|  | 31 |  | 
|  | 32 | var _ android.BpPropertySet = (*bpPropertySet)(nil) | 
|  | 33 |  | 
|  | 34 | func (s *bpPropertySet) init() { | 
|  | 35 | s.properties = make(map[string]interface{}) | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 36 | s.tags = make(map[string]android.BpPropertyTag) | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 37 | } | 
|  | 38 |  | 
| Martin Stjernholm | 191c25f | 2020-09-10 00:40:37 +0100 | [diff] [blame] | 39 | // Converts the given value, which is assumed to be a struct, to a | 
|  | 40 | // bpPropertySet. | 
|  | 41 | func convertToPropertySet(value reflect.Value) *bpPropertySet { | 
|  | 42 | res := newPropertySet() | 
|  | 43 | structType := value.Type() | 
|  | 44 |  | 
|  | 45 | for i := 0; i < structType.NumField(); i++ { | 
|  | 46 | field := structType.Field(i) | 
|  | 47 | fieldVal := value.Field(i) | 
|  | 48 |  | 
|  | 49 | switch fieldVal.Type().Kind() { | 
|  | 50 | case reflect.Ptr: | 
|  | 51 | if fieldVal.IsNil() { | 
|  | 52 | continue // nil pointer means the property isn't set. | 
|  | 53 | } | 
|  | 54 | fieldVal = fieldVal.Elem() | 
|  | 55 | case reflect.Slice: | 
|  | 56 | if fieldVal.IsNil() { | 
|  | 57 | continue // Ignore a nil slice (but not one with length zero). | 
|  | 58 | } | 
|  | 59 | } | 
|  | 60 |  | 
|  | 61 | if fieldVal.Type().Kind() == reflect.Struct { | 
|  | 62 | fieldVal = fieldVal.Addr() // Avoid struct copy below. | 
|  | 63 | } | 
|  | 64 | res.AddProperty(strings.ToLower(field.Name), fieldVal.Interface()) | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | return res | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | // Converts the given value to something that can be set in a property. | 
|  | 71 | func coercePropertyValue(value interface{}) interface{} { | 
|  | 72 | val := reflect.ValueOf(value) | 
|  | 73 | switch val.Kind() { | 
|  | 74 | case reflect.Struct: | 
|  | 75 | // convertToPropertySet requires an addressable struct, and this is probably | 
|  | 76 | // a mistake. | 
|  | 77 | panic(fmt.Sprintf("Value is a struct, not a pointer to one: %v", value)) | 
|  | 78 | case reflect.Ptr: | 
|  | 79 | if _, ok := value.(*bpPropertySet); !ok { | 
|  | 80 | derefValue := reflect.Indirect(val) | 
|  | 81 | if derefValue.Kind() != reflect.Struct { | 
|  | 82 | panic(fmt.Sprintf("A pointer must be to a struct, got: %v", value)) | 
|  | 83 | } | 
|  | 84 | return convertToPropertySet(derefValue) | 
|  | 85 | } | 
|  | 86 | } | 
|  | 87 | return value | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | // Merges the fields of the given property set into s. | 
|  | 91 | func (s *bpPropertySet) mergePropertySet(propSet *bpPropertySet) { | 
|  | 92 | for _, name := range propSet.order { | 
|  | 93 | if tag, ok := propSet.tags[name]; ok { | 
|  | 94 | s.AddPropertyWithTag(name, propSet.properties[name], tag) | 
|  | 95 | } else { | 
|  | 96 | s.AddProperty(name, propSet.properties[name]) | 
|  | 97 | } | 
|  | 98 | } | 
|  | 99 | } | 
|  | 100 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 101 | func (s *bpPropertySet) AddProperty(name string, value interface{}) { | 
| Martin Stjernholm | 191c25f | 2020-09-10 00:40:37 +0100 | [diff] [blame] | 102 | value = coercePropertyValue(value) | 
|  | 103 |  | 
|  | 104 | if propSetValue, ok := value.(*bpPropertySet); ok { | 
|  | 105 | if curValue, ok := s.properties[name]; ok { | 
|  | 106 | if curSet, ok := curValue.(*bpPropertySet); ok { | 
|  | 107 | curSet.mergePropertySet(propSetValue) | 
|  | 108 | return | 
|  | 109 | } | 
|  | 110 | // If the current value isn't a property set we got conflicting types. | 
|  | 111 | // Continue down to the check below to complain about it. | 
|  | 112 | } | 
|  | 113 | } | 
|  | 114 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 115 | if s.properties[name] != nil { | 
| Paul Duffin | 109c2ad | 2020-03-02 16:29:11 +0000 | [diff] [blame] | 116 | panic(fmt.Sprintf("Property %q already exists in property set", name)) | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 117 | } | 
|  | 118 |  | 
|  | 119 | s.properties[name] = value | 
|  | 120 | s.order = append(s.order, name) | 
|  | 121 | } | 
|  | 122 |  | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 123 | func (s *bpPropertySet) AddPropertyWithTag(name string, value interface{}, tag android.BpPropertyTag) { | 
|  | 124 | s.AddProperty(name, value) | 
|  | 125 | s.tags[name] = tag | 
|  | 126 | } | 
|  | 127 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 128 | func (s *bpPropertySet) AddPropertySet(name string) android.BpPropertySet { | 
| Martin Stjernholm | 191c25f | 2020-09-10 00:40:37 +0100 | [diff] [blame] | 129 | s.AddProperty(name, newPropertySet()) | 
|  | 130 | return s.properties[name].(android.BpPropertySet) | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 131 | } | 
|  | 132 |  | 
|  | 133 | func (s *bpPropertySet) getValue(name string) interface{} { | 
|  | 134 | return s.properties[name] | 
|  | 135 | } | 
|  | 136 |  | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 137 | func (s *bpPropertySet) getOptionalValue(name string) (interface{}, bool) { | 
|  | 138 | value, ok := s.properties[name] | 
|  | 139 | return value, ok | 
|  | 140 | } | 
|  | 141 |  | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 142 | func (s *bpPropertySet) getTag(name string) interface{} { | 
|  | 143 | return s.tags[name] | 
|  | 144 | } | 
|  | 145 |  | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 146 | func (s *bpPropertySet) AddCommentForProperty(name, text string) { | 
|  | 147 | if s.comments == nil { | 
|  | 148 | s.comments = map[string]string{} | 
|  | 149 | } | 
|  | 150 | s.comments[name] = strings.TrimSpace(text) | 
|  | 151 | } | 
|  | 152 |  | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 153 | func (s *bpPropertySet) transformContents(transformer bpPropertyTransformer) { | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 154 | var newOrder []string | 
|  | 155 | for _, name := range s.order { | 
|  | 156 | value := s.properties[name] | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 157 | tag := s.tags[name] | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 158 | var newValue interface{} | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 159 | var newTag android.BpPropertyTag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 160 | if propertySet, ok := value.(*bpPropertySet); ok { | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 161 | var newPropertySet *bpPropertySet | 
|  | 162 | newPropertySet, newTag = transformPropertySet(transformer, name, propertySet, tag) | 
|  | 163 | if newPropertySet == nil { | 
|  | 164 | newValue = nil | 
|  | 165 | } else { | 
|  | 166 | newValue = newPropertySet | 
|  | 167 | } | 
| Paul Duffin | cc72e98 | 2020-01-14 15:53:11 +0000 | [diff] [blame] | 168 | } else { | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 169 | newValue, newTag = transformer.transformProperty(name, value, tag) | 
| Paul Duffin | cc72e98 | 2020-01-14 15:53:11 +0000 | [diff] [blame] | 170 | } | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 171 |  | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 172 | if newValue == nil { | 
|  | 173 | // Delete the property from the map and exclude it from the new order. | 
|  | 174 | delete(s.properties, name) | 
|  | 175 | } else { | 
|  | 176 | // Update the property in the map and add the name to the new order list. | 
|  | 177 | s.properties[name] = newValue | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 178 | s.tags[name] = newTag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 179 | newOrder = append(newOrder, name) | 
|  | 180 | } | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 181 | } | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 182 | s.order = newOrder | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 183 | } | 
|  | 184 |  | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 185 | func transformPropertySet(transformer bpPropertyTransformer, name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { | 
| Paul Duffin | 180a006 | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 186 | newPropertySet, newTag := transformer.transformPropertySetBeforeContents(name, propertySet, tag) | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 187 | if newPropertySet != nil { | 
|  | 188 | newPropertySet.transformContents(transformer) | 
| Paul Duffin | 180a006 | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 189 |  | 
|  | 190 | newPropertySet, newTag = transformer.transformPropertySetAfterContents(name, newPropertySet, newTag) | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 191 | } | 
|  | 192 | return newPropertySet, newTag | 
|  | 193 | } | 
|  | 194 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 195 | func (s *bpPropertySet) setProperty(name string, value interface{}) { | 
|  | 196 | if s.properties[name] == nil { | 
|  | 197 | s.AddProperty(name, value) | 
|  | 198 | } else { | 
|  | 199 | s.properties[name] = value | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 200 | s.tags[name] = nil | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 201 | } | 
|  | 202 | } | 
|  | 203 |  | 
| Paul Duffin | 83ad956 | 2021-05-10 23:49:04 +0100 | [diff] [blame] | 204 | func (s *bpPropertySet) removeProperty(name string) { | 
|  | 205 | delete(s.properties, name) | 
|  | 206 | delete(s.tags, name) | 
|  | 207 | _, s.order = android.RemoveFromList(name, s.order) | 
|  | 208 | } | 
|  | 209 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 210 | func (s *bpPropertySet) insertAfter(position string, name string, value interface{}) { | 
|  | 211 | if s.properties[name] != nil { | 
|  | 212 | panic("Property %q already exists in property set") | 
|  | 213 | } | 
|  | 214 |  | 
|  | 215 | // Add the name to the end of the order, to ensure it has necessary capacity | 
|  | 216 | // and to handle the case when the position does not exist. | 
|  | 217 | s.order = append(s.order, name) | 
|  | 218 |  | 
|  | 219 | // Search through the order for the item that matches supplied position. If | 
|  | 220 | // found then insert the name of the new property after it. | 
|  | 221 | for i, v := range s.order { | 
|  | 222 | if v == position { | 
|  | 223 | // Copy the items after the one where the new property should be inserted. | 
|  | 224 | copy(s.order[i+2:], s.order[i+1:]) | 
|  | 225 | // Insert the item in the list. | 
|  | 226 | s.order[i+1] = name | 
|  | 227 | } | 
|  | 228 | } | 
|  | 229 |  | 
|  | 230 | s.properties[name] = value | 
|  | 231 | } | 
|  | 232 |  | 
|  | 233 | type bpModule struct { | 
| Paul Duffin | cc72e98 | 2020-01-14 15:53:11 +0000 | [diff] [blame] | 234 | *bpPropertySet | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 235 | moduleType string | 
|  | 236 | } | 
|  | 237 |  | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 238 | func (m *bpModule) ModuleType() string { | 
|  | 239 | return m.moduleType | 
|  | 240 | } | 
|  | 241 |  | 
|  | 242 | func (m *bpModule) Name() string { | 
|  | 243 | name, hasName := m.getOptionalValue("name") | 
|  | 244 | if hasName { | 
|  | 245 | return name.(string) | 
|  | 246 | } else { | 
|  | 247 | return "" | 
|  | 248 | } | 
|  | 249 | } | 
|  | 250 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 251 | var _ android.BpModule = (*bpModule)(nil) | 
|  | 252 |  | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 253 | type bpPropertyTransformer interface { | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 254 | // Transform the property set, returning the new property set/tag to insert back into the | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 255 | // parent property set (or module if this is the top level property set). | 
|  | 256 | // | 
|  | 257 | // This will be called before transforming the properties in the supplied set. | 
|  | 258 | // | 
|  | 259 | // The name will be "" for the top level property set. | 
|  | 260 | // | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 261 | // Returning (nil, ...) will cause the property set to be removed. | 
| Paul Duffin | 180a006 | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 262 | transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) | 
|  | 263 |  | 
|  | 264 | // Transform the property set, returning the new property set/tag to insert back into the | 
|  | 265 | // parent property set (or module if this is the top level property set). | 
|  | 266 | // | 
|  | 267 | // This will be called after transforming the properties in the supplied set. | 
|  | 268 | // | 
|  | 269 | // The name will be "" for the top level property set. | 
|  | 270 | // | 
|  | 271 | // Returning (nil, ...) will cause the property set to be removed. | 
|  | 272 | transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 273 |  | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 274 | // Transform a property, return the new value/tag to insert back into the property set. | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 275 | // | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 276 | // Returning (nil, ...) will cause the property to be removed. | 
|  | 277 | transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 278 | } | 
|  | 279 |  | 
|  | 280 | // Interface for transforming bpModule objects. | 
|  | 281 | type bpTransformer interface { | 
|  | 282 | // Transform the module, returning the result. | 
|  | 283 | // | 
|  | 284 | // The method can either create a new module and return that, or modify the supplied module | 
|  | 285 | // in place and return that. | 
|  | 286 | // | 
|  | 287 | // After this returns the transformer is applied to the contents of the returned module. | 
|  | 288 | transformModule(module *bpModule) *bpModule | 
|  | 289 |  | 
|  | 290 | bpPropertyTransformer | 
|  | 291 | } | 
|  | 292 |  | 
|  | 293 | type identityTransformation struct{} | 
|  | 294 |  | 
|  | 295 | var _ bpTransformer = (*identityTransformation)(nil) | 
|  | 296 |  | 
|  | 297 | func (t identityTransformation) transformModule(module *bpModule) *bpModule { | 
|  | 298 | return module | 
|  | 299 | } | 
|  | 300 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 301 | func (t identityTransformation) transformPropertySetBeforeContents(_ string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { | 
| Paul Duffin | 180a006 | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 302 | return propertySet, tag | 
|  | 303 | } | 
|  | 304 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 305 | func (t identityTransformation) transformPropertySetAfterContents(_ string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 306 | return propertySet, tag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 307 | } | 
|  | 308 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 309 | func (t identityTransformation) transformProperty(_ string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 310 | return value, tag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 311 | } | 
|  | 312 |  | 
| Paul Duffin | cc72e98 | 2020-01-14 15:53:11 +0000 | [diff] [blame] | 313 | func (m *bpModule) deepCopy() *bpModule { | 
| Sam Delmerico | 3588136 | 2023-06-30 14:40:10 -0400 | [diff] [blame] | 314 | return transformModule(m, deepCopyTransformer) | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 315 | } | 
|  | 316 |  | 
| Sam Delmerico | 3588136 | 2023-06-30 14:40:10 -0400 | [diff] [blame] | 317 | func transformModule(m *bpModule, transformer bpTransformer) *bpModule { | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 318 | transformedModule := transformer.transformModule(m) | 
| Sam Delmerico | 3588136 | 2023-06-30 14:40:10 -0400 | [diff] [blame] | 319 | if transformedModule != nil { | 
|  | 320 | // Copy the contents of the returned property set into the module and then transform that. | 
|  | 321 | transformedModule.bpPropertySet, _ = transformPropertySet(transformer, "", transformedModule.bpPropertySet, nil) | 
|  | 322 | } | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 323 | return transformedModule | 
|  | 324 | } | 
|  | 325 |  | 
| Paul Duffin | 180a006 | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 326 | type deepCopyTransformation struct { | 
|  | 327 | identityTransformation | 
|  | 328 | } | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 329 |  | 
|  | 330 | func (t deepCopyTransformation) transformModule(module *bpModule) *bpModule { | 
|  | 331 | // Take a shallow copy of the module. Any mutable property values will be copied by the | 
|  | 332 | // transformer. | 
|  | 333 | moduleCopy := *module | 
|  | 334 | return &moduleCopy | 
|  | 335 | } | 
|  | 336 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 337 | func (t deepCopyTransformation) transformPropertySetBeforeContents(_ string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 338 | // Create a shallow copy of the properties map. Any mutable property values will be copied by the | 
|  | 339 | // transformer. | 
|  | 340 | propertiesCopy := make(map[string]interface{}) | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 341 | for propertyName, value := range propertySet.properties { | 
|  | 342 | propertiesCopy[propertyName] = value | 
|  | 343 | } | 
|  | 344 |  | 
|  | 345 | // Ditto for tags map. | 
|  | 346 | tagsCopy := make(map[string]android.BpPropertyTag) | 
|  | 347 | for propertyName, propertyTag := range propertySet.tags { | 
|  | 348 | tagsCopy[propertyName] = propertyTag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 349 | } | 
|  | 350 |  | 
|  | 351 | // Create a new property set. | 
|  | 352 | return &bpPropertySet{ | 
|  | 353 | properties: propertiesCopy, | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 354 | tags:       tagsCopy, | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 355 | order:      append([]string(nil), propertySet.order...), | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 356 | }, tag | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 357 | } | 
|  | 358 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 359 | func (t deepCopyTransformation) transformProperty(_ string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 360 | // Copy string slice, otherwise return value. | 
|  | 361 | if values, ok := value.([]string); ok { | 
|  | 362 | valuesCopy := make([]string, len(values)) | 
|  | 363 | copy(valuesCopy, values) | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 364 | return valuesCopy, tag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 365 | } | 
| Paul Duffin | 5b511a2 | 2020-01-15 14:23:52 +0000 | [diff] [blame] | 366 | return value, tag | 
| Paul Duffin | b4d9c1f | 2020-01-15 11:52:11 +0000 | [diff] [blame] | 367 | } | 
|  | 368 |  | 
|  | 369 | var deepCopyTransformer bpTransformer = deepCopyTransformation{} | 
|  | 370 |  | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 371 | // A .bp file | 
|  | 372 | type bpFile struct { | 
|  | 373 | modules map[string]*bpModule | 
|  | 374 | order   []*bpModule | 
|  | 375 | } | 
|  | 376 |  | 
| Paul Duffin | b01ac4b | 2022-05-24 20:10:05 +0000 | [diff] [blame] | 377 | // AddModule adds a module to this. | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 378 | // | 
|  | 379 | // The module must have had its "name" property set to a string value that | 
|  | 380 | // is unique within this file. | 
|  | 381 | func (f *bpFile) AddModule(module android.BpModule) { | 
|  | 382 | m := module.(*bpModule) | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 383 | moduleType := module.ModuleType() | 
|  | 384 | name := m.Name() | 
|  | 385 | hasName := true | 
|  | 386 | if name == "" { | 
|  | 387 | // Use a prefixed module type as the name instead just in case this is something like a package | 
|  | 388 | // of namespace module which does not require a name. | 
|  | 389 | name = "#" + moduleType | 
|  | 390 | hasName = false | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 391 | } | 
| Paul Duffin | 0df4968 | 2021-05-07 01:10:01 +0100 | [diff] [blame] | 392 |  | 
|  | 393 | if f.modules[name] != nil { | 
|  | 394 | if hasName { | 
|  | 395 | panic(fmt.Sprintf("Module %q already exists in bp file", name)) | 
|  | 396 | } else { | 
|  | 397 | panic(fmt.Sprintf("Unnamed module type %q already exists in bp file", moduleType)) | 
|  | 398 | } | 
|  | 399 | } | 
|  | 400 |  | 
|  | 401 | f.modules[name] = m | 
|  | 402 | f.order = append(f.order, m) | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 403 | } | 
|  | 404 |  | 
|  | 405 | func (f *bpFile) newModule(moduleType string) *bpModule { | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 406 | return newModule(moduleType) | 
|  | 407 | } | 
|  | 408 |  | 
|  | 409 | func newModule(moduleType string) *bpModule { | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 410 | module := &bpModule{ | 
| Paul Duffin | cc72e98 | 2020-01-14 15:53:11 +0000 | [diff] [blame] | 411 | moduleType:    moduleType, | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 412 | bpPropertySet: newPropertySet(), | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 413 | } | 
| Paul Duffin | b645ec8 | 2019-11-27 17:43:54 +0000 | [diff] [blame] | 414 | return module | 
|  | 415 | } | 
| Paul Duffin | 047fdca | 2020-02-21 16:06:25 +0000 | [diff] [blame] | 416 |  | 
|  | 417 | func newPropertySet() *bpPropertySet { | 
|  | 418 | set := &bpPropertySet{} | 
|  | 419 | set.init() | 
|  | 420 | return set | 
|  | 421 | } |