blob: ae06a09dd5036b825b99da3469c9c0180625f456 [file] [log] [blame]
Paul Duffinb645ec82019-11-27 17:43:54 +00001// 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
15package sdk
16
17import (
18 "fmt"
19
20 "android/soong/android"
21)
22
23type bpPropertySet struct {
24 properties map[string]interface{}
25 order []string
26}
27
28var _ android.BpPropertySet = (*bpPropertySet)(nil)
29
30func (s *bpPropertySet) init() {
31 s.properties = make(map[string]interface{})
32}
33
34func (s *bpPropertySet) AddProperty(name string, value interface{}) {
35 if s.properties[name] != nil {
36 panic("Property %q already exists in property set")
37 }
38
39 s.properties[name] = value
40 s.order = append(s.order, name)
41}
42
43func (s *bpPropertySet) AddPropertySet(name string) android.BpPropertySet {
44 set := &bpPropertySet{}
45 set.init()
46 s.AddProperty(name, set)
47 return set
48}
49
50func (s *bpPropertySet) getValue(name string) interface{} {
51 return s.properties[name]
52}
53
Paul Duffincc72e982020-01-14 15:53:11 +000054func (s *bpPropertySet) deepCopy() *bpPropertySet {
Paul Duffinb645ec82019-11-27 17:43:54 +000055 propertiesCopy := make(map[string]interface{})
56 for p, v := range s.properties {
Paul Duffincc72e982020-01-14 15:53:11 +000057 var valueCopy interface{}
58 if ps, ok := v.(*bpPropertySet); ok {
59 valueCopy = ps.deepCopy()
60 } else if values, ok := v.([]string); ok {
61 valuesCopy := make([]string, len(values))
62 copy(valuesCopy, values)
63 valueCopy = valuesCopy
64 } else {
65 valueCopy = v
66 }
67 propertiesCopy[p] = valueCopy
Paul Duffinb645ec82019-11-27 17:43:54 +000068 }
69
Paul Duffincc72e982020-01-14 15:53:11 +000070 return &bpPropertySet{
Paul Duffinb645ec82019-11-27 17:43:54 +000071 properties: propertiesCopy,
72 order: append([]string(nil), s.order...),
73 }
74}
75
76func (s *bpPropertySet) setProperty(name string, value interface{}) {
77 if s.properties[name] == nil {
78 s.AddProperty(name, value)
79 } else {
80 s.properties[name] = value
81 }
82}
83
84func (s *bpPropertySet) insertAfter(position string, name string, value interface{}) {
85 if s.properties[name] != nil {
86 panic("Property %q already exists in property set")
87 }
88
89 // Add the name to the end of the order, to ensure it has necessary capacity
90 // and to handle the case when the position does not exist.
91 s.order = append(s.order, name)
92
93 // Search through the order for the item that matches supplied position. If
94 // found then insert the name of the new property after it.
95 for i, v := range s.order {
96 if v == position {
97 // Copy the items after the one where the new property should be inserted.
98 copy(s.order[i+2:], s.order[i+1:])
99 // Insert the item in the list.
100 s.order[i+1] = name
101 }
102 }
103
104 s.properties[name] = value
105}
106
107type bpModule struct {
Paul Duffincc72e982020-01-14 15:53:11 +0000108 *bpPropertySet
Paul Duffinb645ec82019-11-27 17:43:54 +0000109 moduleType string
110}
111
112var _ android.BpModule = (*bpModule)(nil)
113
Paul Duffincc72e982020-01-14 15:53:11 +0000114func (m *bpModule) deepCopy() *bpModule {
Paul Duffinb645ec82019-11-27 17:43:54 +0000115 return &bpModule{
Paul Duffincc72e982020-01-14 15:53:11 +0000116 bpPropertySet: m.bpPropertySet.deepCopy(),
Paul Duffinb645ec82019-11-27 17:43:54 +0000117 moduleType: m.moduleType,
118 }
119}
120
121// A .bp file
122type bpFile struct {
123 modules map[string]*bpModule
124 order []*bpModule
125}
126
127// Add a module.
128//
129// The module must have had its "name" property set to a string value that
130// is unique within this file.
131func (f *bpFile) AddModule(module android.BpModule) {
132 m := module.(*bpModule)
133 if name, ok := m.getValue("name").(string); ok {
134 if f.modules[name] != nil {
135 panic(fmt.Sprintf("Module %q already exists in bp file", name))
136 }
137
138 f.modules[name] = m
139 f.order = append(f.order, m)
140 } else {
141 panic("Module does not have a name property, or it is not a string")
142 }
143}
144
145func (f *bpFile) newModule(moduleType string) *bpModule {
146 module := &bpModule{
Paul Duffincc72e982020-01-14 15:53:11 +0000147 moduleType: moduleType,
148 bpPropertySet: &bpPropertySet{},
Paul Duffinb645ec82019-11-27 17:43:54 +0000149 }
Paul Duffincc72e982020-01-14 15:53:11 +0000150 module.bpPropertySet.init()
Paul Duffinb645ec82019-11-27 17:43:54 +0000151 return module
152}