blob: 19fb70dab97947be124b25c31e6e8ac1cb33c4cc [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
54func (s *bpPropertySet) copy() bpPropertySet {
55 propertiesCopy := make(map[string]interface{})
56 for p, v := range s.properties {
57 propertiesCopy[p] = v
58 }
59
60 return bpPropertySet{
61 properties: propertiesCopy,
62 order: append([]string(nil), s.order...),
63 }
64}
65
66func (s *bpPropertySet) setProperty(name string, value interface{}) {
67 if s.properties[name] == nil {
68 s.AddProperty(name, value)
69 } else {
70 s.properties[name] = value
71 }
72}
73
74func (s *bpPropertySet) insertAfter(position string, name string, value interface{}) {
75 if s.properties[name] != nil {
76 panic("Property %q already exists in property set")
77 }
78
79 // Add the name to the end of the order, to ensure it has necessary capacity
80 // and to handle the case when the position does not exist.
81 s.order = append(s.order, name)
82
83 // Search through the order for the item that matches supplied position. If
84 // found then insert the name of the new property after it.
85 for i, v := range s.order {
86 if v == position {
87 // Copy the items after the one where the new property should be inserted.
88 copy(s.order[i+2:], s.order[i+1:])
89 // Insert the item in the list.
90 s.order[i+1] = name
91 }
92 }
93
94 s.properties[name] = value
95}
96
97type bpModule struct {
98 bpPropertySet
99 moduleType string
100}
101
102var _ android.BpModule = (*bpModule)(nil)
103
104func (m *bpModule) copy() *bpModule {
105 return &bpModule{
106 bpPropertySet: m.bpPropertySet.copy(),
107 moduleType: m.moduleType,
108 }
109}
110
111// A .bp file
112type bpFile struct {
113 modules map[string]*bpModule
114 order []*bpModule
115}
116
117// Add a module.
118//
119// The module must have had its "name" property set to a string value that
120// is unique within this file.
121func (f *bpFile) AddModule(module android.BpModule) {
122 m := module.(*bpModule)
123 if name, ok := m.getValue("name").(string); ok {
124 if f.modules[name] != nil {
125 panic(fmt.Sprintf("Module %q already exists in bp file", name))
126 }
127
128 f.modules[name] = m
129 f.order = append(f.order, m)
130 } else {
131 panic("Module does not have a name property, or it is not a string")
132 }
133}
134
135func (f *bpFile) newModule(moduleType string) *bpModule {
136 module := &bpModule{
137 moduleType: moduleType,
138 }
139 (&module.bpPropertySet).init()
140 return module
141}