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
20	"github.com/google/blueprint"
21)
22
23type moduleType struct {
24	name    string
25	factory ModuleFactory
26}
27
28var moduleTypes []moduleType
29
30type singleton struct {
31	name    string
32	factory blueprint.SingletonFactory
33}
34
35var singletons []singleton
36var preSingletons []singleton
37
38type mutator struct {
39	name            string
40	bottomUpMutator blueprint.BottomUpMutator
41	topDownMutator  blueprint.TopDownMutator
42	parallel        bool
43}
44
45type ModuleFactory func() Module
46
47// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
48// into a blueprint.Module and a list of property structs
49func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
50	return func() (blueprint.Module, []interface{}) {
51		module := factory()
52		return module, module.GetProperties()
53	}
54}
55
56type SingletonFactory func() Singleton
57
58// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
59// a Singleton into a blueprint.Singleton
60func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory {
61	return func() blueprint.Singleton {
62		singleton := factory()
63		if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
64			registerSingletonMakeVarsProvider(makevars)
65		}
66		return &singletonAdaptor{Singleton: singleton}
67	}
68}
69
70func RegisterModuleType(name string, factory ModuleFactory) {
71	moduleTypes = append(moduleTypes, moduleType{name, factory})
72}
73
74func RegisterSingletonType(name string, factory SingletonFactory) {
75	singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)})
76}
77
78func RegisterPreSingletonType(name string, factory SingletonFactory) {
79	preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)})
80}
81
82type Context struct {
83	*blueprint.Context
84}
85
86func NewContext() *Context {
87	ctx := &Context{blueprint.NewContext()}
88	ctx.SetSrcDir(absSrcDir)
89	return ctx
90}
91
92func (ctx *Context) Register() {
93	for _, t := range preSingletons {
94		ctx.RegisterPreSingletonType(t.name, t.factory)
95	}
96
97	for _, t := range moduleTypes {
98		ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
99	}
100
101	for _, t := range singletons {
102		ctx.RegisterSingletonType(t.name, t.factory)
103	}
104
105	registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
106
107	// Register phony just before makevars so it can write out its phony rules as Make rules
108	ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory))
109
110	// Register makevars after other singletons so they can export values through makevars
111	ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
112
113	// Register env last so that it can track all used environment variables
114	ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton))
115}
116
117func ModuleTypeFactories() map[string]ModuleFactory {
118	ret := make(map[string]ModuleFactory)
119	for _, t := range moduleTypes {
120		ret[t.name] = t.factory
121	}
122	return ret
123}
124
125// Interface for registering build components.
126//
127// Provided to allow registration of build components to be shared between the runtime
128// and test environments.
129type RegistrationContext interface {
130	RegisterModuleType(name string, factory ModuleFactory)
131	RegisterSingletonType(name string, factory SingletonFactory)
132	PreArchMutators(f RegisterMutatorFunc)
133
134	// Register pre arch mutators that are hard coded into mutator.go.
135	//
136	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
137	HardCodedPreArchMutators(f RegisterMutatorFunc)
138
139	PreDepsMutators(f RegisterMutatorFunc)
140	PostDepsMutators(f RegisterMutatorFunc)
141	FinalDepsMutators(f RegisterMutatorFunc)
142}
143
144// Used to register build components from an init() method, e.g.
145//
146// init() {
147//   RegisterBuildComponents(android.InitRegistrationContext)
148// }
149//
150// func RegisterBuildComponents(ctx android.RegistrationContext) {
151//   ctx.RegisterModuleType(...)
152//   ...
153// }
154//
155// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
156// allows it to be used to initialize test context, e.g.
157//
158//   ctx := android.NewTestContext()
159//   RegisterBuildComponents(ctx)
160var InitRegistrationContext RegistrationContext = &initRegistrationContext{
161	moduleTypes:    make(map[string]ModuleFactory),
162	singletonTypes: make(map[string]SingletonFactory),
163}
164
165// Make sure the TestContext implements RegistrationContext.
166var _ RegistrationContext = (*TestContext)(nil)
167
168type initRegistrationContext struct {
169	moduleTypes    map[string]ModuleFactory
170	singletonTypes map[string]SingletonFactory
171}
172
173func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
174	if _, present := ctx.moduleTypes[name]; present {
175		panic(fmt.Sprintf("module type %q is already registered", name))
176	}
177	ctx.moduleTypes[name] = factory
178	RegisterModuleType(name, factory)
179}
180
181func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
182	if _, present := ctx.singletonTypes[name]; present {
183		panic(fmt.Sprintf("singleton type %q is already registered", name))
184	}
185	ctx.singletonTypes[name] = factory
186	RegisterSingletonType(name, factory)
187}
188
189func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
190	PreArchMutators(f)
191}
192
193func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
194	// Nothing to do as the mutators are hard code in preArch in mutator.go
195}
196
197func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
198	PreDepsMutators(f)
199}
200
201func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
202	PostDepsMutators(f)
203}
204
205func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
206	FinalDepsMutators(f)
207}
208