1// Copyright 2015 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 android
16
17import (
18	"fmt"
19	"reflect"
20
21	"github.com/google/blueprint"
22)
23
24// A sortable component is one whose registration order affects the order in which it is executed
25// and so affects the behavior of the build system. As a result it is important for the order in
26// which they are registered during tests to match the order used at runtime and so the test
27// infrastructure will sort them to match.
28//
29// The sortable components are mutators, singletons and pre-singletons. Module types are not
30// sortable because their order of registration does not affect the runtime behavior.
31type sortableComponent interface {
32	// componentName returns the name of the component.
33	//
34	// Uniquely identifies the components within the set of components used at runtimr and during
35	// tests.
36	componentName() string
37
38	// register registers this component in the supplied context.
39	register(ctx *Context)
40}
41
42type sortableComponents []sortableComponent
43
44// registerAll registers all components in this slice with the supplied context.
45func (r sortableComponents) registerAll(ctx *Context) {
46	for _, c := range r {
47		c.register(ctx)
48	}
49}
50
51type moduleType struct {
52	name    string
53	factory ModuleFactory
54}
55
56func (t moduleType) register(ctx *Context) {
57	ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
58}
59
60var moduleTypes []moduleType
61var moduleTypesForDocs = map[string]reflect.Value{}
62
63type singleton struct {
64	// True if this should be registered as a pre-singleton, false otherwise.
65	pre bool
66
67	name    string
68	factory SingletonFactory
69}
70
71func newSingleton(name string, factory SingletonFactory) singleton {
72	return singleton{false, name, factory}
73}
74
75func newPreSingleton(name string, factory SingletonFactory) singleton {
76	return singleton{true, name, factory}
77}
78
79func (s singleton) componentName() string {
80	return s.name
81}
82
83func (s singleton) register(ctx *Context) {
84	adaptor := SingletonFactoryAdaptor(ctx, s.factory)
85	if s.pre {
86		ctx.RegisterPreSingletonType(s.name, adaptor)
87	} else {
88		ctx.RegisterSingletonType(s.name, adaptor)
89	}
90}
91
92var _ sortableComponent = singleton{}
93
94var singletons sortableComponents
95var preSingletons sortableComponents
96
97type mutator struct {
98	name            string
99	bottomUpMutator blueprint.BottomUpMutator
100	topDownMutator  blueprint.TopDownMutator
101	parallel        bool
102}
103
104var _ sortableComponent = &mutator{}
105
106type ModuleFactory func() Module
107
108// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
109// into a blueprint.Module and a list of property structs
110func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
111	return func() (blueprint.Module, []interface{}) {
112		module := factory()
113		return module, module.GetProperties()
114	}
115}
116
117type SingletonFactory func() Singleton
118
119// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
120// a Singleton into a blueprint.Singleton
121func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
122	return func() blueprint.Singleton {
123		singleton := factory()
124		if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
125			registerSingletonMakeVarsProvider(ctx.config, makevars)
126		}
127		return &singletonAdaptor{Singleton: singleton}
128	}
129}
130
131func RegisterModuleType(name string, factory ModuleFactory) {
132	moduleTypes = append(moduleTypes, moduleType{name, factory})
133	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
134}
135
136// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
137// function that has documentation for the module type.  It is normally called automatically
138// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
139// override the factory method used for documentation, for example if the method passed to
140// RegisterModuleType was a lambda.
141func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
142	moduleTypesForDocs[name] = factory
143}
144
145func RegisterSingletonType(name string, factory SingletonFactory) {
146	singletons = append(singletons, newSingleton(name, factory))
147}
148
149func RegisterPreSingletonType(name string, factory SingletonFactory) {
150	preSingletons = append(preSingletons, newPreSingleton(name, factory))
151}
152
153type Context struct {
154	*blueprint.Context
155	config Config
156}
157
158func NewContext(config Config) *Context {
159	ctx := &Context{blueprint.NewContext(), config}
160	ctx.SetSrcDir(absSrcDir)
161	return ctx
162}
163
164// RegisterForBazelConversion registers an alternate shadow pipeline of
165// singletons, module types and mutators to register for converting Blueprint
166// files to semantically equivalent BUILD files.
167func (ctx *Context) RegisterForBazelConversion() {
168	for _, t := range moduleTypes {
169		t.register(ctx)
170	}
171
172	// Required for SingletonModule types, even though we are not using them.
173	for _, t := range singletons {
174		t.register(ctx)
175	}
176
177	bp2buildMutatorList := []RegisterMutatorFunc{}
178	for t, f := range bp2buildMutators {
179		ctx.config.bp2buildModuleTypeConfig[t] = true
180		bp2buildMutatorList = append(bp2buildMutatorList, f)
181	}
182
183	RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutatorList)
184}
185
186// Register the pipeline of singletons, module types, and mutators for
187// generating build.ninja and other files for Kati, from Android.bp files.
188func (ctx *Context) Register() {
189	preSingletons.registerAll(ctx)
190
191	for _, t := range moduleTypes {
192		t.register(ctx)
193	}
194
195	if ctx.config.BazelContext.BazelEnabled() {
196		// Hydrate the configuration of bp2build-enabled module types. This is
197		// required as a signal to identify which modules should be deferred to
198		// Bazel in mixed builds, if it is enabled.
199		for t, _ := range bp2buildMutators {
200			ctx.config.bp2buildModuleTypeConfig[t] = true
201		}
202	}
203
204	mutators := collateGloballyRegisteredMutators()
205	mutators.registerAll(ctx)
206
207	singletons := collateGloballyRegisteredSingletons()
208	singletons.registerAll(ctx)
209}
210
211func collateGloballyRegisteredSingletons() sortableComponents {
212	allSingletons := append(sortableComponents(nil), singletons...)
213	allSingletons = append(allSingletons,
214		singleton{false, "bazeldeps", BazelSingleton},
215
216		// Register phony just before makevars so it can write out its phony rules as Make rules
217		singleton{false, "phony", phonySingletonFactory},
218
219		// Register makevars after other singletons so they can export values through makevars
220		singleton{false, "makevars", makeVarsSingletonFunc},
221
222		// Register env and ninjadeps last so that they can track all used environment variables and
223		// Ninja file dependencies stored in the config.
224		singleton{false, "ninjadeps", ninjaDepsSingletonFactory},
225	)
226
227	return allSingletons
228}
229
230func ModuleTypeFactories() map[string]ModuleFactory {
231	ret := make(map[string]ModuleFactory)
232	for _, t := range moduleTypes {
233		ret[t.name] = t.factory
234	}
235	return ret
236}
237
238func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
239	return moduleTypesForDocs
240}
241
242// Interface for registering build components.
243//
244// Provided to allow registration of build components to be shared between the runtime
245// and test environments.
246type RegistrationContext interface {
247	RegisterModuleType(name string, factory ModuleFactory)
248	RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
249	RegisterPreSingletonType(name string, factory SingletonFactory)
250	RegisterSingletonType(name string, factory SingletonFactory)
251	PreArchMutators(f RegisterMutatorFunc)
252
253	// Register pre arch mutators that are hard coded into mutator.go.
254	//
255	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
256	HardCodedPreArchMutators(f RegisterMutatorFunc)
257
258	PreDepsMutators(f RegisterMutatorFunc)
259	PostDepsMutators(f RegisterMutatorFunc)
260	FinalDepsMutators(f RegisterMutatorFunc)
261}
262
263// Used to register build components from an init() method, e.g.
264//
265// init() {
266//   RegisterBuildComponents(android.InitRegistrationContext)
267// }
268//
269// func RegisterBuildComponents(ctx android.RegistrationContext) {
270//   ctx.RegisterModuleType(...)
271//   ...
272// }
273//
274// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
275// allows it to be used to initialize test context, e.g.
276//
277//   ctx := android.NewTestContext(config)
278//   RegisterBuildComponents(ctx)
279var InitRegistrationContext RegistrationContext = &initRegistrationContext{
280	moduleTypes:       make(map[string]ModuleFactory),
281	singletonTypes:    make(map[string]SingletonFactory),
282	preSingletonTypes: make(map[string]SingletonFactory),
283}
284
285// Make sure the TestContext implements RegistrationContext.
286var _ RegistrationContext = (*TestContext)(nil)
287
288type initRegistrationContext struct {
289	moduleTypes        map[string]ModuleFactory
290	singletonTypes     map[string]SingletonFactory
291	preSingletonTypes  map[string]SingletonFactory
292	moduleTypesForDocs map[string]reflect.Value
293}
294
295func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
296	if _, present := ctx.moduleTypes[name]; present {
297		panic(fmt.Sprintf("module type %q is already registered", name))
298	}
299	ctx.moduleTypes[name] = factory
300	RegisterModuleType(name, factory)
301	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
302}
303
304func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
305	s, m := SingletonModuleFactoryAdaptor(name, factory)
306	ctx.RegisterSingletonType(name, s)
307	ctx.RegisterModuleType(name, m)
308	// Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
309	// SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
310	// factory method.
311	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
312}
313
314func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
315	if _, present := ctx.singletonTypes[name]; present {
316		panic(fmt.Sprintf("singleton type %q is already registered", name))
317	}
318	ctx.singletonTypes[name] = factory
319	RegisterSingletonType(name, factory)
320}
321
322func (ctx *initRegistrationContext) RegisterPreSingletonType(name string, factory SingletonFactory) {
323	if _, present := ctx.preSingletonTypes[name]; present {
324		panic(fmt.Sprintf("pre singleton type %q is already registered", name))
325	}
326	ctx.preSingletonTypes[name] = factory
327	RegisterPreSingletonType(name, factory)
328}
329
330func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
331	PreArchMutators(f)
332}
333
334func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
335	// Nothing to do as the mutators are hard code in preArch in mutator.go
336}
337
338func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
339	PreDepsMutators(f)
340}
341
342func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
343	PostDepsMutators(f)
344}
345
346func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
347	FinalDepsMutators(f)
348}
349