xref: /aosp_15_r20/build/soong/android/mutator.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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	"sync"
19
20	"github.com/google/blueprint"
21)
22
23// Phases:
24//   run Pre-arch mutators
25//   run archMutator
26//   run Pre-deps mutators
27//   run depsMutator
28//   run PostDeps mutators
29//   run FinalDeps mutators (TransitionMutators disallowed in this phase)
30//   continue on to GenerateAndroidBuildActions
31
32// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
33// with the InitRegistrationContext and will be used at runtime.
34func collateGloballyRegisteredMutators() sortableComponents {
35	return collateRegisteredMutators(preArch, preDeps, postDeps, postApex, finalDeps)
36}
37
38// collateRegisteredMutators constructs a single list of mutators from the separate lists.
39func collateRegisteredMutators(preArch, preDeps, postDeps, postApex, finalDeps []RegisterMutatorFunc) sortableComponents {
40	mctx := &registerMutatorsContext{}
41
42	register := func(funcs []RegisterMutatorFunc) {
43		for _, f := range funcs {
44			f(mctx)
45		}
46	}
47
48	register(preArch)
49
50	register(preDeps)
51
52	register([]RegisterMutatorFunc{registerDepsMutator})
53
54	register(postDeps)
55
56	register(postApex)
57
58	mctx.finalPhase = true
59	register(finalDeps)
60
61	return mctx.mutators
62}
63
64type registerMutatorsContext struct {
65	mutators   sortableComponents
66	finalPhase bool
67}
68
69type RegisterMutatorsContext interface {
70	TopDown(name string, m TopDownMutator) MutatorHandle
71	BottomUp(name string, m BottomUpMutator) MutatorHandle
72	BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
73	Transition(name string, m TransitionMutator) TransitionMutatorHandle
74}
75
76type RegisterMutatorFunc func(RegisterMutatorsContext)
77
78var preArch = []RegisterMutatorFunc{
79	RegisterNamespaceMutator,
80
81	// Check the visibility rules are valid.
82	//
83	// This must run after the package renamer mutators so that any issues found during
84	// validation of the package's default_visibility property are reported using the
85	// correct package name and not the synthetic name.
86	//
87	// This must also be run before defaults mutators as the rules for validation are
88	// different before checking the rules than they are afterwards. e.g.
89	//    visibility: ["//visibility:private", "//visibility:public"]
90	// would be invalid if specified in a module definition but is valid if it results
91	// from something like this:
92	//
93	//    defaults {
94	//        name: "defaults",
95	//        // Be inaccessible outside a package by default.
96	//        visibility: ["//visibility:private"]
97	//    }
98	//
99	//    defaultable_module {
100	//        name: "defaultable_module",
101	//        defaults: ["defaults"],
102	//        // Override the default.
103	//        visibility: ["//visibility:public"]
104	//    }
105	//
106	RegisterVisibilityRuleChecker,
107
108	// Record the default_applicable_licenses for each package.
109	//
110	// This must run before the defaults so that defaults modules can pick up the package default.
111	RegisterLicensesPackageMapper,
112
113	// Apply properties from defaults modules to the referencing modules.
114	//
115	// Any mutators that are added before this will not see any modules created by
116	// a DefaultableHook.
117	RegisterDefaultsPreArchMutators,
118
119	// Add dependencies on any components so that any component references can be
120	// resolved within the deps mutator.
121	//
122	// Must be run after defaults so it can be used to create dependencies on the
123	// component modules that are creating in a DefaultableHook.
124	//
125	// Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are
126	// renamed. That is so that if a module creates components using a prebuilt module
127	// type that any dependencies (which must use prebuilt_ prefixes) are resolved to
128	// the prebuilt module and not the source module.
129	RegisterComponentsMutator,
130
131	// Create an association between prebuilt modules and their corresponding source
132	// modules (if any).
133	//
134	// Must be run after defaults mutators to ensure that any modules created by
135	// a DefaultableHook can be either a prebuilt or a source module with a matching
136	// prebuilt.
137	RegisterPrebuiltsPreArchMutators,
138
139	// Gather the licenses properties for all modules for use during expansion and enforcement.
140	//
141	// This must come after the defaults mutators to ensure that any licenses supplied
142	// in a defaults module has been successfully applied before the rules are gathered.
143	RegisterLicensesPropertyGatherer,
144
145	// Gather the visibility rules for all modules for us during visibility enforcement.
146	//
147	// This must come after the defaults mutators to ensure that any visibility supplied
148	// in a defaults module has been successfully applied before the rules are gathered.
149	RegisterVisibilityRuleGatherer,
150}
151
152func registerArchMutator(ctx RegisterMutatorsContext) {
153	ctx.Transition("os", &osTransitionMutator{})
154	ctx.BottomUp("image_begin", imageMutatorBeginMutator)
155	ctx.Transition("image", &imageTransitionMutator{})
156	ctx.Transition("arch", &archTransitionMutator{})
157}
158
159var preDeps = []RegisterMutatorFunc{
160	registerArchMutator,
161}
162
163var postDeps = []RegisterMutatorFunc{
164	registerPathDepsMutator,
165	RegisterPrebuiltsPostDepsMutators,
166	RegisterVisibilityRuleEnforcer,
167	RegisterLicensesDependencyChecker,
168	registerNeverallowMutator,
169	RegisterOverridePostDepsMutators,
170}
171
172var postApex = []RegisterMutatorFunc{}
173
174var finalDeps = []RegisterMutatorFunc{}
175
176func PreArchMutators(f RegisterMutatorFunc) {
177	preArch = append(preArch, f)
178}
179
180func PreDepsMutators(f RegisterMutatorFunc) {
181	preDeps = append(preDeps, f)
182}
183
184func PostDepsMutators(f RegisterMutatorFunc) {
185	postDeps = append(postDeps, f)
186}
187
188func PostApexMutators(f RegisterMutatorFunc) {
189	postApex = append(postApex, f)
190}
191
192func FinalDepsMutators(f RegisterMutatorFunc) {
193	finalDeps = append(finalDeps, f)
194}
195
196type TopDownMutator func(TopDownMutatorContext)
197
198type TopDownMutatorContext interface {
199	BaseModuleContext
200}
201
202type topDownMutatorContext struct {
203	bp blueprint.TopDownMutatorContext
204	baseModuleContext
205}
206
207type BottomUpMutator func(BottomUpMutatorContext)
208
209type BottomUpMutatorContext interface {
210	BaseModuleContext
211
212	// AddDependency adds a dependency to the given module.  It returns a slice of modules for each
213	// dependency (some entries may be nil).
214	//
215	// This method will pause until the new dependencies have had the current mutator called on them.
216	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
217
218	// AddReverseDependency adds a dependency from the destination to the given module.
219	// Does not affect the ordering of the current mutator pass, but will be ordered
220	// correctly for all future mutator passes.  All reverse dependencies for a destination module are
221	// collected until the end of the mutator pass, sorted by name, and then appended to the destination
222	// module's dependency list.  May only  be called by mutators that were marked with
223	// UsesReverseDependencies during registration.
224	AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
225
226	// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
227	// argument to select which variant of the dependency to use.  It returns a slice of modules for
228	// each dependency (some entries may be nil).  A variant of the dependency must exist that matches
229	// all the non-local variations of the current module, plus the variations argument.
230	//
231	// This method will pause until the new dependencies have had the current mutator called on them.
232	AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
233
234	// AddReverseVariationDependency adds a dependency from the named module to the current
235	// module. The given variations will be added to the current module's varations, and then the
236	// result will be used to find the correct variation of the depending module, which must exist.
237	//
238	// Does not affect the ordering of the current mutator pass, but will be ordered
239	// correctly for all future mutator passes.  All reverse dependencies for a destination module are
240	// collected until the end of the mutator pass, sorted by name, and then appended to the destination
241	// module's dependency list.  May only  be called by mutators that were marked with
242	// UsesReverseDependencies during registration.
243	AddReverseVariationDependency([]blueprint.Variation, blueprint.DependencyTag, string)
244
245	// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
246	// variations argument to select which variant of the dependency to use.  It returns a slice of
247	// modules for each dependency (some entries may be nil).  A variant of the dependency must
248	// exist that matches the variations argument, but may also have other variations.
249	// For any unspecified variation the first variant will be used.
250	//
251	// Unlike AddVariationDependencies, the variations of the current module are ignored - the
252	// dependency only needs to match the supplied variations.
253	//
254	// This method will pause until the new dependencies have had the current mutator called on them.
255	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
256
257	// ReplaceDependencies finds all the variants of the module with the specified name, then
258	// replaces all dependencies onto those variants with the current variant of this module.
259	// Replacements don't take effect until after the mutator pass is finished.  May only
260	// be called by mutators that were marked with UsesReplaceDependencies during registration.
261	ReplaceDependencies(string)
262
263	// ReplaceDependenciesIf finds all the variants of the module with the specified name, then
264	// replaces all dependencies onto those variants with the current variant of this module
265	// as long as the supplied predicate returns true.
266	// Replacements don't take effect until after the mutator pass is finished.  May only
267	// be called by mutators that were marked with UsesReplaceDependencies during registration.
268	ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
269
270	// Rename all variants of a module.  The new name is not visible to calls to ModuleName,
271	// AddDependency or OtherModuleName until after this mutator pass is complete.  May only be called
272	// by mutators that were marked with UsesRename during registration.
273	Rename(name string)
274
275	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
276	// the specified property structs to it as if the properties were set in a blueprint file.  May only
277	// be called by mutators that were marked with UsesCreateModule during registration.
278	CreateModule(ModuleFactory, ...interface{}) Module
279}
280
281// An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module
282// for each transition mutator.  bottomUpMutatorContext and topDownMutatorContext are created once for every module
283// for every BottomUp or TopDown mutator.  Use a global pool for each to avoid reallocating every time.
284var (
285	outgoingTransitionContextPool = sync.Pool{
286		New: func() any { return &outgoingTransitionContextImpl{} },
287	}
288	incomingTransitionContextPool = sync.Pool{
289		New: func() any { return &incomingTransitionContextImpl{} },
290	}
291	bottomUpMutatorContextPool = sync.Pool{
292		New: func() any { return &bottomUpMutatorContext{} },
293	}
294
295	topDownMutatorContextPool = sync.Pool{
296		New: func() any { return &topDownMutatorContext{} },
297	}
298)
299
300type bottomUpMutatorContext struct {
301	bp blueprint.BottomUpMutatorContext
302	baseModuleContext
303	finalPhase bool
304}
305
306// callers must immediately follow the call to this function with defer bottomUpMutatorContextPool.Put(mctx).
307func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
308	finalPhase bool) BottomUpMutatorContext {
309
310	moduleContext := a.base().baseModuleContextFactory(ctx)
311	mctx := bottomUpMutatorContextPool.Get().(*bottomUpMutatorContext)
312	*mctx = bottomUpMutatorContext{
313		bp:                ctx,
314		baseModuleContext: moduleContext,
315		finalPhase:        finalPhase,
316	}
317	return mctx
318}
319
320func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
321	finalPhase := x.finalPhase
322	f := func(ctx blueprint.BottomUpMutatorContext) {
323		if a, ok := ctx.Module().(Module); ok {
324			mctx := bottomUpMutatorContextFactory(ctx, a, finalPhase)
325			defer bottomUpMutatorContextPool.Put(mctx)
326			m(mctx)
327		}
328	}
329	mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f}
330	x.mutators = append(x.mutators, mutator)
331	return mutator
332}
333
334func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle {
335	mutator := &mutator{name: name, bottomUpMutator: m}
336	x.mutators = append(x.mutators, mutator)
337	return mutator
338}
339
340type IncomingTransitionContext interface {
341	ArchModuleContext
342	ModuleProviderContext
343	ModuleErrorContext
344
345	// Module returns the target of the dependency edge for which the transition
346	// is being computed
347	Module() Module
348
349	// Config returns the configuration for the build.
350	Config() Config
351
352	DeviceConfig() DeviceConfig
353
354	// IsAddingDependency returns true if the transition is being called while adding a dependency
355	// after the transition mutator has already run, or false if it is being called when the transition
356	// mutator is running.  This should be used sparingly, all uses will have to be removed in order
357	// to support creating variants on demand.
358	IsAddingDependency() bool
359}
360
361type OutgoingTransitionContext interface {
362	ArchModuleContext
363	ModuleProviderContext
364
365	// Module returns the target of the dependency edge for which the transition
366	// is being computed
367	Module() Module
368
369	// DepTag() Returns the dependency tag through which this dependency is
370	// reached
371	DepTag() blueprint.DependencyTag
372
373	// Config returns the configuration for the build.
374	Config() Config
375
376	DeviceConfig() DeviceConfig
377}
378
379// TransitionMutator implements a top-down mechanism where a module tells its
380// direct dependencies what variation they should be built in but the dependency
381// has the final say.
382//
383// When implementing a transition mutator, one needs to implement four methods:
384//   - Split() that tells what variations a module has by itself
385//   - OutgoingTransition() where a module tells what it wants from its
386//     dependency
387//   - IncomingTransition() where a module has the final say about its own
388//     variation
389//   - Mutate() that changes the state of a module depending on its variation
390//
391// That the effective variation of module B when depended on by module A is the
392// composition the outgoing transition of module A and the incoming transition
393// of module B.
394//
395// the outgoing transition should not take the properties of the dependency into
396// account, only those of the module that depends on it. For this reason, the
397// dependency is not even passed into it as an argument. Likewise, the incoming
398// transition should not take the properties of the depending module into
399// account and is thus not informed about it. This makes for a nice
400// decomposition of the decision logic.
401//
402// A given transition mutator only affects its own variation; other variations
403// stay unchanged along the dependency edges.
404//
405// Soong makes sure that all modules are created in the desired variations and
406// that dependency edges are set up correctly. This ensures that "missing
407// variation" errors do not happen and allows for more flexible changes in the
408// value of the variation among dependency edges (as oppposed to bottom-up
409// mutators where if module A in variation X depends on module B and module B
410// has that variation X, A must depend on variation X of B)
411//
412// The limited power of the context objects passed to individual mutators
413// methods also makes it more difficult to shoot oneself in the foot. Complete
414// safety is not guaranteed because no one prevents individual transition
415// mutators from mutating modules in illegal ways and for e.g. Split() or
416// Mutate() to run their own visitations of the transitive dependency of the
417// module and both of these are bad ideas, but it's better than no guardrails at
418// all.
419//
420// This model is pretty close to Bazel's configuration transitions. The mapping
421// between concepts in Soong and Bazel is as follows:
422//   - Module == configured target
423//   - Variant == configuration
424//   - Variation name == configuration flag
425//   - Variation == configuration flag value
426//   - Outgoing transition == attribute transition
427//   - Incoming transition == rule transition
428//
429// The Split() method does not have a Bazel equivalent and Bazel split
430// transitions do not have a Soong equivalent.
431//
432// Mutate() does not make sense in Bazel due to the different models of the
433// two systems: when creating new variations, Soong clones the old module and
434// thus some way is needed to change it state whereas Bazel creates each
435// configuration of a given configured target anew.
436type TransitionMutator interface {
437	// Split returns the set of variations that should be created for a module no
438	// matter who depends on it. Used when Make depends on a particular variation
439	// or when the module knows its variations just based on information given to
440	// it in the Blueprint file. This method should not mutate the module it is
441	// called on.
442	Split(ctx BaseModuleContext) []string
443
444	// OutgoingTransition is called on a module to determine which variation it wants
445	// from its direct dependencies. The dependency itself can override this decision.
446	// This method should not mutate the module itself.
447	OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
448
449	// IncomingTransition is called on a module to determine which variation it should
450	// be in based on the variation modules that depend on it want. This gives the module
451	// a final say about its own variations. This method should not mutate the module
452	// itself.
453	IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
454
455	// Mutate is called after a module was split into multiple variations on each variation.
456	// It should not split the module any further but adding new dependencies is
457	// fine. Unlike all the other methods on TransitionMutator, this method is
458	// allowed to mutate the module.
459	Mutate(ctx BottomUpMutatorContext, variation string)
460}
461
462type androidTransitionMutator struct {
463	finalPhase bool
464	mutator    TransitionMutator
465	name       string
466}
467
468func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
469	if a.finalPhase {
470		panic("TransitionMutator not allowed in FinalDepsMutators")
471	}
472	if m, ok := ctx.Module().(Module); ok {
473		moduleContext := m.base().baseModuleContextFactory(ctx)
474		return a.mutator.Split(&moduleContext)
475	} else {
476		return []string{""}
477	}
478}
479
480type outgoingTransitionContextImpl struct {
481	archModuleContext
482	bp blueprint.OutgoingTransitionContext
483}
484
485func (c *outgoingTransitionContextImpl) Module() Module {
486	return c.bp.Module().(Module)
487}
488
489func (c *outgoingTransitionContextImpl) DepTag() blueprint.DependencyTag {
490	return c.bp.DepTag()
491}
492
493func (c *outgoingTransitionContextImpl) Config() Config {
494	return c.bp.Config().(Config)
495}
496
497func (c *outgoingTransitionContextImpl) DeviceConfig() DeviceConfig {
498	return DeviceConfig{c.bp.Config().(Config).deviceConfig}
499}
500
501func (c *outgoingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
502	return c.bp.Provider(provider)
503}
504
505func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
506	if m, ok := bpctx.Module().(Module); ok {
507		ctx := outgoingTransitionContextPool.Get().(*outgoingTransitionContextImpl)
508		defer outgoingTransitionContextPool.Put(ctx)
509		*ctx = outgoingTransitionContextImpl{
510			archModuleContext: m.base().archModuleContextFactory(bpctx),
511			bp:                bpctx,
512		}
513		return a.mutator.OutgoingTransition(ctx, sourceVariation)
514	} else {
515		return ""
516	}
517}
518
519type incomingTransitionContextImpl struct {
520	archModuleContext
521	bp blueprint.IncomingTransitionContext
522}
523
524func (c *incomingTransitionContextImpl) Module() Module {
525	return c.bp.Module().(Module)
526}
527
528func (c *incomingTransitionContextImpl) Config() Config {
529	return c.bp.Config().(Config)
530}
531
532func (c *incomingTransitionContextImpl) DeviceConfig() DeviceConfig {
533	return DeviceConfig{c.bp.Config().(Config).deviceConfig}
534}
535
536func (c *incomingTransitionContextImpl) IsAddingDependency() bool {
537	return c.bp.IsAddingDependency()
538}
539
540func (c *incomingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
541	return c.bp.Provider(provider)
542}
543
544func (c *incomingTransitionContextImpl) ModuleErrorf(fmt string, args ...interface{}) {
545	c.bp.ModuleErrorf(fmt, args)
546}
547
548func (c *incomingTransitionContextImpl) PropertyErrorf(property, fmt string, args ...interface{}) {
549	c.bp.PropertyErrorf(property, fmt, args)
550}
551
552func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
553	if m, ok := bpctx.Module().(Module); ok {
554		ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl)
555		defer incomingTransitionContextPool.Put(ctx)
556		*ctx = incomingTransitionContextImpl{
557			archModuleContext: m.base().archModuleContextFactory(bpctx),
558			bp:                bpctx,
559		}
560		return a.mutator.IncomingTransition(ctx, incomingVariation)
561	} else {
562		return ""
563	}
564}
565
566func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
567	if am, ok := ctx.Module().(Module); ok {
568		if variation != "" {
569			// TODO: this should really be checking whether the TransitionMutator affected this module, not
570			//  the empty variant, but TransitionMutator has no concept of skipping a module.
571			base := am.base()
572			base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
573			base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
574		}
575
576		mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
577		defer bottomUpMutatorContextPool.Put(mctx)
578		a.mutator.Mutate(mctx, variation)
579	}
580}
581
582func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) TransitionMutatorHandle {
583	atm := &androidTransitionMutator{
584		finalPhase: x.finalPhase,
585		mutator:    m,
586		name:       name,
587	}
588	mutator := &mutator{
589		name:              name,
590		transitionMutator: atm,
591	}
592	x.mutators = append(x.mutators, mutator)
593	return mutator
594}
595
596func (x *registerMutatorsContext) mutatorName(name string) string {
597	return name
598}
599
600func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
601	f := func(ctx blueprint.TopDownMutatorContext) {
602		if a, ok := ctx.Module().(Module); ok {
603			moduleContext := a.base().baseModuleContextFactory(ctx)
604			actx := topDownMutatorContextPool.Get().(*topDownMutatorContext)
605			defer topDownMutatorContextPool.Put(actx)
606			*actx = topDownMutatorContext{
607				bp:                ctx,
608				baseModuleContext: moduleContext,
609			}
610			m(actx)
611		}
612	}
613	mutator := &mutator{name: x.mutatorName(name), topDownMutator: f}
614	x.mutators = append(x.mutators, mutator)
615	return mutator
616}
617
618func (mutator *mutator) componentName() string {
619	return mutator.name
620}
621
622func (mutator *mutator) register(ctx *Context) {
623	blueprintCtx := ctx.Context
624	var handle blueprint.MutatorHandle
625	if mutator.bottomUpMutator != nil {
626		handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
627	} else if mutator.topDownMutator != nil {
628		handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
629	} else if mutator.transitionMutator != nil {
630		handle := blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
631		if mutator.neverFar {
632			handle.NeverFar()
633		}
634	}
635
636	// Forward booleans set on the MutatorHandle to the blueprint.MutatorHandle.
637	if mutator.usesRename {
638		handle.UsesRename()
639	}
640	if mutator.usesReverseDependencies {
641		handle.UsesReverseDependencies()
642	}
643	if mutator.usesReplaceDependencies {
644		handle.UsesReplaceDependencies()
645	}
646	if mutator.usesCreateModule {
647		handle.UsesCreateModule()
648	}
649	if mutator.mutatesDependencies {
650		handle.MutatesDependencies()
651	}
652	if mutator.mutatesGlobalState {
653		handle.MutatesGlobalState()
654	}
655}
656
657type MutatorHandle interface {
658	// Parallel sets the mutator to visit modules in parallel while maintaining ordering.  Calling any
659	// method on the mutator context is thread-safe, but the mutator must handle synchronization
660	// for any modifications to global state or any modules outside the one it was invoked on.
661	// Deprecated: all Mutators are parallel by default.
662	Parallel() MutatorHandle
663
664	// UsesRename marks the mutator as using the BottomUpMutatorContext.Rename method, which prevents
665	// coalescing adjacent mutators into a single mutator pass.
666	UsesRename() MutatorHandle
667
668	// UsesReverseDependencies marks the mutator as using the BottomUpMutatorContext.AddReverseDependency
669	// method, which prevents coalescing adjacent mutators into a single mutator pass.
670	UsesReverseDependencies() MutatorHandle
671
672	// UsesReplaceDependencies marks the mutator as using the BottomUpMutatorContext.ReplaceDependencies
673	// method, which prevents coalescing adjacent mutators into a single mutator pass.
674	UsesReplaceDependencies() MutatorHandle
675
676	// UsesCreateModule marks the mutator as using the BottomUpMutatorContext.CreateModule method,
677	// which prevents coalescing adjacent mutators into a single mutator pass.
678	UsesCreateModule() MutatorHandle
679
680	// MutatesDependencies marks the mutator as modifying properties in dependencies, which prevents
681	// coalescing adjacent mutators into a single mutator pass.
682	MutatesDependencies() MutatorHandle
683
684	// MutatesGlobalState marks the mutator as modifying global state, which prevents coalescing
685	// adjacent mutators into a single mutator pass.
686	MutatesGlobalState() MutatorHandle
687}
688
689type TransitionMutatorHandle interface {
690	// NeverFar causes the variations created by this mutator to never be ignored when adding
691	// far variation dependencies. Normally, far variation dependencies ignore all the variants
692	// of the source module, and only use the variants explicitly requested by the
693	// AddFarVariationDependencies call.
694	NeverFar() MutatorHandle
695}
696
697func (mutator *mutator) Parallel() MutatorHandle {
698	return mutator
699}
700
701func (mutator *mutator) UsesRename() MutatorHandle {
702	mutator.usesRename = true
703	return mutator
704}
705
706func (mutator *mutator) UsesReverseDependencies() MutatorHandle {
707	mutator.usesReverseDependencies = true
708	return mutator
709}
710
711func (mutator *mutator) UsesReplaceDependencies() MutatorHandle {
712	mutator.usesReplaceDependencies = true
713	return mutator
714}
715
716func (mutator *mutator) UsesCreateModule() MutatorHandle {
717	mutator.usesCreateModule = true
718	return mutator
719}
720
721func (mutator *mutator) MutatesDependencies() MutatorHandle {
722	mutator.mutatesDependencies = true
723	return mutator
724}
725
726func (mutator *mutator) MutatesGlobalState() MutatorHandle {
727	mutator.mutatesGlobalState = true
728	return mutator
729}
730
731func (mutator *mutator) NeverFar() MutatorHandle {
732	mutator.neverFar = true
733	return mutator
734}
735
736func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
737	ctx.BottomUp("component-deps", componentDepsMutator)
738}
739
740// A special mutator that runs just prior to the deps mutator to allow the dependencies
741// on component modules to be added so that they can depend directly on a prebuilt
742// module.
743func componentDepsMutator(ctx BottomUpMutatorContext) {
744	ctx.Module().ComponentDepsMutator(ctx)
745}
746
747func depsMutator(ctx BottomUpMutatorContext) {
748	if m := ctx.Module(); m.Enabled(ctx) {
749		m.base().baseDepsMutator(ctx)
750		m.DepsMutator(ctx)
751	}
752}
753
754func registerDepsMutator(ctx RegisterMutatorsContext) {
755	ctx.BottomUp("deps", depsMutator).UsesReverseDependencies()
756}
757
758// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
759// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
760// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
761// non-overridden method has to be forwarded.  There are fewer non-overridden methods, so use the latter.  The following
762// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext.
763
764func (b *bottomUpMutatorContext) Rename(name string) {
765	b.bp.Rename(name)
766	b.Module().base().commonProperties.DebugName = name
767}
768
769func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
770	return b.bp.CreateModule(factory, name, props...)
771}
772
773func (b *bottomUpMutatorContext) createModuleInDirectory(factory blueprint.ModuleFactory, name string, _ string, props ...interface{}) blueprint.Module {
774	panic("createModuleInDirectory is not implemented for bottomUpMutatorContext")
775}
776
777func (b *bottomUpMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
778	return createModule(b, factory, "_bottomUpMutatorModule", doesNotSpecifyDirectory(), props...)
779}
780
781func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
782	if b.baseModuleContext.checkedMissingDeps() {
783		panic("Adding deps not allowed after checking for missing deps")
784	}
785	return b.bp.AddDependency(module, tag, name...)
786}
787
788func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
789	if b.baseModuleContext.checkedMissingDeps() {
790		panic("Adding deps not allowed after checking for missing deps")
791	}
792	b.bp.AddReverseDependency(module, tag, name)
793}
794
795func (b *bottomUpMutatorContext) AddReverseVariationDependency(variations []blueprint.Variation, tag blueprint.DependencyTag, name string) {
796	if b.baseModuleContext.checkedMissingDeps() {
797		panic("Adding deps not allowed after checking for missing deps")
798	}
799	b.bp.AddReverseVariationDependency(variations, tag, name)
800}
801
802func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
803	names ...string) []blueprint.Module {
804	if b.baseModuleContext.checkedMissingDeps() {
805		panic("Adding deps not allowed after checking for missing deps")
806	}
807	return b.bp.AddVariationDependencies(variations, tag, names...)
808}
809
810func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
811	tag blueprint.DependencyTag, names ...string) []blueprint.Module {
812	if b.baseModuleContext.checkedMissingDeps() {
813		panic("Adding deps not allowed after checking for missing deps")
814	}
815
816	return b.bp.AddFarVariationDependencies(variations, tag, names...)
817}
818
819func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
820	if b.baseModuleContext.checkedMissingDeps() {
821		panic("Adding deps not allowed after checking for missing deps")
822	}
823	b.bp.ReplaceDependencies(name)
824}
825
826func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
827	if b.baseModuleContext.checkedMissingDeps() {
828		panic("Adding deps not allowed after checking for missing deps")
829	}
830	b.bp.ReplaceDependenciesIf(name, predicate)
831}
832