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	"reflect"
19
20	"github.com/google/blueprint"
21	"github.com/google/blueprint/proptools"
22)
23
24// Phases:
25//   run Pre-arch mutators
26//   run archMutator
27//   run Pre-deps mutators
28//   run depsMutator
29//   run PostDeps mutators
30//   run FinalDeps mutators (CreateVariations disallowed in this phase)
31//   continue on to GenerateAndroidBuildActions
32
33func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
34	for _, t := range mutators {
35		var handle blueprint.MutatorHandle
36		if t.bottomUpMutator != nil {
37			handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
38		} else if t.topDownMutator != nil {
39			handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
40		}
41		if t.parallel {
42			handle.Parallel()
43		}
44	}
45}
46
47func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
48	mctx := &registerMutatorsContext{}
49
50	register := func(funcs []RegisterMutatorFunc) {
51		for _, f := range funcs {
52			f(mctx)
53		}
54	}
55
56	register(preArch)
57
58	register(preDeps)
59
60	mctx.BottomUp("deps", depsMutator).Parallel()
61
62	register(postDeps)
63
64	mctx.finalPhase = true
65	register(finalDeps)
66
67	registerMutatorsToContext(ctx, mctx.mutators)
68}
69
70type registerMutatorsContext struct {
71	mutators   []*mutator
72	finalPhase bool
73}
74
75type RegisterMutatorsContext interface {
76	TopDown(name string, m TopDownMutator) MutatorHandle
77	BottomUp(name string, m BottomUpMutator) MutatorHandle
78}
79
80type RegisterMutatorFunc func(RegisterMutatorsContext)
81
82var preArch = []RegisterMutatorFunc{
83	RegisterNamespaceMutator,
84
85	// Check the visibility rules are valid.
86	//
87	// This must run after the package renamer mutators so that any issues found during
88	// validation of the package's default_visibility property are reported using the
89	// correct package name and not the synthetic name.
90	//
91	// This must also be run before defaults mutators as the rules for validation are
92	// different before checking the rules than they are afterwards. e.g.
93	//    visibility: ["//visibility:private", "//visibility:public"]
94	// would be invalid if specified in a module definition but is valid if it results
95	// from something like this:
96	//
97	//    defaults {
98	//        name: "defaults",
99	//        // Be inaccessible outside a package by default.
100	//        visibility: ["//visibility:private"]
101	//    }
102	//
103	//    defaultable_module {
104	//        name: "defaultable_module",
105	//        defaults: ["defaults"],
106	//        // Override the default.
107	//        visibility: ["//visibility:public"]
108	//    }
109	//
110	RegisterVisibilityRuleChecker,
111
112	// Apply properties from defaults modules to the referencing modules.
113	//
114	// Any mutators that are added before this will not see any modules created by
115	// a DefaultableHook.
116	RegisterDefaultsPreArchMutators,
117
118	// Add dependencies on any components so that any component references can be
119	// resolved within the deps mutator.
120	//
121	// Must be run after defaults so it can be used to create dependencies on the
122	// component modules that are creating in a DefaultableHook.
123	//
124	// Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are
125	// renamed. That is so that if a module creates components using a prebuilt module
126	// type that any dependencies (which must use prebuilt_ prefixes) are resolved to
127	// the prebuilt module and not the source module.
128	RegisterComponentsMutator,
129
130	// Create an association between prebuilt modules and their corresponding source
131	// modules (if any).
132	//
133	// Must be run after defaults mutators to ensure that any modules created by
134	// a DefaultableHook can be either a prebuilt or a source module with a matching
135	// prebuilt.
136	RegisterPrebuiltsPreArchMutators,
137
138	// Gather the visibility rules for all modules for us during visibility enforcement.
139	//
140	// This must come after the defaults mutators to ensure that any visibility supplied
141	// in a defaults module has been successfully applied before the rules are gathered.
142	RegisterVisibilityRuleGatherer,
143}
144
145func registerArchMutator(ctx RegisterMutatorsContext) {
146	ctx.BottomUp("os", osMutator).Parallel()
147	ctx.BottomUp("image", imageMutator).Parallel()
148	ctx.BottomUp("arch", archMutator).Parallel()
149}
150
151var preDeps = []RegisterMutatorFunc{
152	registerArchMutator,
153}
154
155var postDeps = []RegisterMutatorFunc{
156	registerPathDepsMutator,
157	RegisterPrebuiltsPostDepsMutators,
158	RegisterVisibilityRuleEnforcer,
159	RegisterNeverallowMutator,
160	RegisterOverridePostDepsMutators,
161}
162
163var finalDeps = []RegisterMutatorFunc{}
164
165func PreArchMutators(f RegisterMutatorFunc) {
166	preArch = append(preArch, f)
167}
168
169func PreDepsMutators(f RegisterMutatorFunc) {
170	preDeps = append(preDeps, f)
171}
172
173func PostDepsMutators(f RegisterMutatorFunc) {
174	postDeps = append(postDeps, f)
175}
176
177func FinalDepsMutators(f RegisterMutatorFunc) {
178	finalDeps = append(finalDeps, f)
179}
180
181type TopDownMutator func(TopDownMutatorContext)
182
183type TopDownMutatorContext interface {
184	BaseModuleContext
185
186	MutatorName() string
187
188	Rename(name string)
189
190	CreateModule(ModuleFactory, ...interface{}) Module
191}
192
193type topDownMutatorContext struct {
194	bp blueprint.TopDownMutatorContext
195	baseModuleContext
196}
197
198type BottomUpMutator func(BottomUpMutatorContext)
199
200type BottomUpMutatorContext interface {
201	BaseModuleContext
202
203	MutatorName() string
204
205	Rename(name string)
206
207	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string)
208	AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
209	CreateVariations(...string) []Module
210	CreateLocalVariations(...string) []Module
211	SetDependencyVariation(string)
212	SetDefaultDependencyVariation(*string)
213	AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
214	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
215	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
216	ReplaceDependencies(string)
217	ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
218	AliasVariation(variationName string)
219}
220
221type bottomUpMutatorContext struct {
222	bp blueprint.BottomUpMutatorContext
223	baseModuleContext
224	finalPhase bool
225}
226
227func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
228	finalPhase := x.finalPhase
229	f := func(ctx blueprint.BottomUpMutatorContext) {
230		if a, ok := ctx.Module().(Module); ok {
231			actx := &bottomUpMutatorContext{
232				bp:                ctx,
233				baseModuleContext: a.base().baseModuleContextFactory(ctx),
234				finalPhase:        finalPhase,
235			}
236			m(actx)
237		}
238	}
239	mutator := &mutator{name: name, bottomUpMutator: f}
240	x.mutators = append(x.mutators, mutator)
241	return mutator
242}
243
244func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
245	f := func(ctx blueprint.TopDownMutatorContext) {
246		if a, ok := ctx.Module().(Module); ok {
247			actx := &topDownMutatorContext{
248				bp:                ctx,
249				baseModuleContext: a.base().baseModuleContextFactory(ctx),
250			}
251			m(actx)
252		}
253	}
254	mutator := &mutator{name: name, topDownMutator: f}
255	x.mutators = append(x.mutators, mutator)
256	return mutator
257}
258
259type MutatorHandle interface {
260	Parallel() MutatorHandle
261}
262
263func (mutator *mutator) Parallel() MutatorHandle {
264	mutator.parallel = true
265	return mutator
266}
267
268func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
269	ctx.BottomUp("component-deps", componentDepsMutator).Parallel()
270}
271
272// A special mutator that runs just prior to the deps mutator to allow the dependencies
273// on component modules to be added so that they can depend directly on a prebuilt
274// module.
275func componentDepsMutator(ctx BottomUpMutatorContext) {
276	if m := ctx.Module(); m.Enabled() {
277		m.ComponentDepsMutator(ctx)
278	}
279}
280
281func depsMutator(ctx BottomUpMutatorContext) {
282	if m := ctx.Module(); m.Enabled() {
283		m.DepsMutator(ctx)
284	}
285}
286
287func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
288	for _, p := range props {
289		err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties,
290			p, nil)
291		if err != nil {
292			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
293				t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
294			} else {
295				panic(err)
296			}
297		}
298	}
299}
300
301func (t *topDownMutatorContext) PrependProperties(props ...interface{}) {
302	for _, p := range props {
303		err := proptools.PrependMatchingProperties(t.Module().base().customizableProperties,
304			p, nil)
305		if err != nil {
306			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
307				t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
308			} else {
309				panic(err)
310			}
311		}
312	}
313}
314
315// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
316// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
317// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
318// non-overridden method has to be forwarded.  There are fewer non-overridden methods, so use the latter.  The following
319// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext.
320
321func (t *topDownMutatorContext) MutatorName() string {
322	return t.bp.MutatorName()
323}
324
325func (t *topDownMutatorContext) Rename(name string) {
326	t.bp.Rename(name)
327	t.Module().base().commonProperties.DebugName = name
328}
329
330func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
331	inherited := []interface{}{&t.Module().base().commonProperties}
332	module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...).(Module)
333
334	if t.Module().base().variableProperties != nil && module.base().variableProperties != nil {
335		src := t.Module().base().variableProperties
336		dst := []interface{}{
337			module.base().variableProperties,
338			// Put an empty copy of the src properties into dst so that properties in src that are not in dst
339			// don't cause a "failed to find property to extend" error.
340			proptools.CloneEmptyProperties(reflect.ValueOf(src)).Interface(),
341		}
342		err := proptools.AppendMatchingProperties(dst, src, nil)
343		if err != nil {
344			panic(err)
345		}
346	}
347
348	return module
349}
350
351func (b *bottomUpMutatorContext) MutatorName() string {
352	return b.bp.MutatorName()
353}
354
355func (b *bottomUpMutatorContext) Rename(name string) {
356	b.bp.Rename(name)
357	b.Module().base().commonProperties.DebugName = name
358}
359
360func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) {
361	b.bp.AddDependency(module, tag, name...)
362}
363
364func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
365	b.bp.AddReverseDependency(module, tag, name)
366}
367
368func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
369	if b.finalPhase {
370		panic("CreateVariations not allowed in FinalDepsMutators")
371	}
372
373	modules := b.bp.CreateVariations(variations...)
374
375	aModules := make([]Module, len(modules))
376	for i := range variations {
377		aModules[i] = modules[i].(Module)
378		base := aModules[i].base()
379		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
380		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
381	}
382
383	return aModules
384}
385
386func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
387	if b.finalPhase {
388		panic("CreateLocalVariations not allowed in FinalDepsMutators")
389	}
390
391	modules := b.bp.CreateLocalVariations(variations...)
392
393	aModules := make([]Module, len(modules))
394	for i := range variations {
395		aModules[i] = modules[i].(Module)
396		base := aModules[i].base()
397		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
398		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
399	}
400
401	return aModules
402}
403
404func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) {
405	b.bp.SetDependencyVariation(variation)
406}
407
408func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
409	b.bp.SetDefaultDependencyVariation(variation)
410}
411
412func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
413	names ...string) {
414
415	b.bp.AddVariationDependencies(variations, tag, names...)
416}
417
418func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
419	tag blueprint.DependencyTag, names ...string) {
420
421	b.bp.AddFarVariationDependencies(variations, tag, names...)
422}
423
424func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) {
425	b.bp.AddInterVariantDependency(tag, from, to)
426}
427
428func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
429	b.bp.ReplaceDependencies(name)
430}
431
432func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
433	b.bp.ReplaceDependenciesIf(name, predicate)
434}
435
436func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
437	b.bp.AliasVariation(variationName)
438}
439