• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	"android/soong/bazel"
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 (CreateVariations disallowed in this phase)
30//   continue on to GenerateAndroidBuildActions
31
32// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
33func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
34	bp2buildMutators := append(preArchMutators, registerBp2buildConversionMutator)
35	registerMutatorsForBazelConversion(ctx, bp2buildMutators)
36}
37
38// RegisterMutatorsForApiBazelConversion is an alternate registration pipeline for api_bp2build
39// This pipeline restricts generation of Bazel targets to Soong modules that contribute APIs
40func RegisterMutatorsForApiBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
41	bp2buildMutators := append(preArchMutators, registerApiBp2buildConversionMutator)
42	registerMutatorsForBazelConversion(ctx, bp2buildMutators)
43}
44
45func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []RegisterMutatorFunc) {
46	mctx := &registerMutatorsContext{
47		bazelConversionMode: true,
48	}
49
50	allMutators := append([]RegisterMutatorFunc{
51		RegisterNamespaceMutator,
52		RegisterDefaultsPreArchMutators,
53		// TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should
54		// evaluate the impact on conversion.
55		RegisterPrebuiltsPreArchMutators,
56	},
57		bp2buildMutators...)
58
59	// Register bp2build mutators
60	for _, f := range allMutators {
61		f(mctx)
62	}
63
64	mctx.mutators.registerAll(ctx)
65}
66
67// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
68// with the InitRegistrationContext and will be used at runtime.
69func collateGloballyRegisteredMutators() sortableComponents {
70	return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
71}
72
73// collateRegisteredMutators constructs a single list of mutators from the separate lists.
74func collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) sortableComponents {
75	mctx := &registerMutatorsContext{}
76
77	register := func(funcs []RegisterMutatorFunc) {
78		for _, f := range funcs {
79			f(mctx)
80		}
81	}
82
83	register(preArch)
84
85	register(preDeps)
86
87	register([]RegisterMutatorFunc{registerDepsMutator})
88
89	register(postDeps)
90
91	mctx.finalPhase = true
92	register(finalDeps)
93
94	return mctx.mutators
95}
96
97type registerMutatorsContext struct {
98	mutators            sortableComponents
99	finalPhase          bool
100	bazelConversionMode bool
101}
102
103type RegisterMutatorsContext interface {
104	TopDown(name string, m TopDownMutator) MutatorHandle
105	BottomUp(name string, m BottomUpMutator) MutatorHandle
106	BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
107	Transition(name string, m TransitionMutator)
108}
109
110type RegisterMutatorFunc func(RegisterMutatorsContext)
111
112var preArch = []RegisterMutatorFunc{
113	RegisterNamespaceMutator,
114
115	// Check the visibility rules are valid.
116	//
117	// This must run after the package renamer mutators so that any issues found during
118	// validation of the package's default_visibility property are reported using the
119	// correct package name and not the synthetic name.
120	//
121	// This must also be run before defaults mutators as the rules for validation are
122	// different before checking the rules than they are afterwards. e.g.
123	//    visibility: ["//visibility:private", "//visibility:public"]
124	// would be invalid if specified in a module definition but is valid if it results
125	// from something like this:
126	//
127	//    defaults {
128	//        name: "defaults",
129	//        // Be inaccessible outside a package by default.
130	//        visibility: ["//visibility:private"]
131	//    }
132	//
133	//    defaultable_module {
134	//        name: "defaultable_module",
135	//        defaults: ["defaults"],
136	//        // Override the default.
137	//        visibility: ["//visibility:public"]
138	//    }
139	//
140	RegisterVisibilityRuleChecker,
141
142	// Record the default_applicable_licenses for each package.
143	//
144	// This must run before the defaults so that defaults modules can pick up the package default.
145	RegisterLicensesPackageMapper,
146
147	// Apply properties from defaults modules to the referencing modules.
148	//
149	// Any mutators that are added before this will not see any modules created by
150	// a DefaultableHook.
151	RegisterDefaultsPreArchMutators,
152
153	// Add dependencies on any components so that any component references can be
154	// resolved within the deps mutator.
155	//
156	// Must be run after defaults so it can be used to create dependencies on the
157	// component modules that are creating in a DefaultableHook.
158	//
159	// Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are
160	// renamed. That is so that if a module creates components using a prebuilt module
161	// type that any dependencies (which must use prebuilt_ prefixes) are resolved to
162	// the prebuilt module and not the source module.
163	RegisterComponentsMutator,
164
165	// Create an association between prebuilt modules and their corresponding source
166	// modules (if any).
167	//
168	// Must be run after defaults mutators to ensure that any modules created by
169	// a DefaultableHook can be either a prebuilt or a source module with a matching
170	// prebuilt.
171	RegisterPrebuiltsPreArchMutators,
172
173	// Gather the licenses properties for all modules for use during expansion and enforcement.
174	//
175	// This must come after the defaults mutators to ensure that any licenses supplied
176	// in a defaults module has been successfully applied before the rules are gathered.
177	RegisterLicensesPropertyGatherer,
178
179	// Gather the visibility rules for all modules for us during visibility enforcement.
180	//
181	// This must come after the defaults mutators to ensure that any visibility supplied
182	// in a defaults module has been successfully applied before the rules are gathered.
183	RegisterVisibilityRuleGatherer,
184}
185
186func registerArchMutator(ctx RegisterMutatorsContext) {
187	ctx.BottomUpBlueprint("os", osMutator).Parallel()
188	ctx.BottomUp("image", imageMutator).Parallel()
189	ctx.BottomUpBlueprint("arch", archMutator).Parallel()
190}
191
192var preDeps = []RegisterMutatorFunc{
193	registerArchMutator,
194}
195
196var postDeps = []RegisterMutatorFunc{
197	registerPathDepsMutator,
198	RegisterPrebuiltsPostDepsMutators,
199	RegisterVisibilityRuleEnforcer,
200	RegisterLicensesDependencyChecker,
201	registerNeverallowMutator,
202	RegisterOverridePostDepsMutators,
203}
204
205var finalDeps = []RegisterMutatorFunc{}
206
207func PreArchMutators(f RegisterMutatorFunc) {
208	preArch = append(preArch, f)
209}
210
211func PreDepsMutators(f RegisterMutatorFunc) {
212	preDeps = append(preDeps, f)
213}
214
215func PostDepsMutators(f RegisterMutatorFunc) {
216	postDeps = append(postDeps, f)
217}
218
219func FinalDepsMutators(f RegisterMutatorFunc) {
220	finalDeps = append(finalDeps, f)
221}
222
223var bp2buildPreArchMutators = []RegisterMutatorFunc{}
224
225// A minimal context for Bp2build conversion
226type Bp2buildMutatorContext interface {
227	BazelConversionPathContext
228
229	CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
230}
231
232// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
233// into Bazel BUILD targets that should run prior to deps and conversion.
234func PreArchBp2BuildMutators(f RegisterMutatorFunc) {
235	bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
236}
237
238type BaseMutatorContext interface {
239	BaseModuleContext
240
241	// MutatorName returns the name that this mutator was registered with.
242	MutatorName() string
243
244	// Rename all variants of a module.  The new name is not visible to calls to ModuleName,
245	// AddDependency or OtherModuleName until after this mutator pass is complete.
246	Rename(name string)
247}
248
249type TopDownMutator func(TopDownMutatorContext)
250
251type TopDownMutatorContext interface {
252	BaseMutatorContext
253
254	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
255	// the specified property structs to it as if the properties were set in a blueprint file.
256	CreateModule(ModuleFactory, ...interface{}) Module
257
258	// CreateBazelTargetModule creates a BazelTargetModule by calling the
259	// factory method, just like in CreateModule, but also requires
260	// BazelTargetModuleProperties containing additional metadata for the
261	// bp2build codegenerator.
262	CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
263
264	// CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the
265	// factory method, just like in CreateModule, but also requires
266	// BazelTargetModuleProperties containing additional metadata for the
267	// bp2build codegenerator. The generated target is restricted to only be buildable for certain
268	// platforms, as dictated by a given bool attribute: the target will not be buildable in
269	// any platform for which this bool attribute is false.
270	CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
271
272	// CreateBazelTargetAliasInDir creates an alias definition in `dir` directory.
273	// This function can be used to create alias definitions in a directory that is different
274	// from the directory of the visited Soong module.
275	CreateBazelTargetAliasInDir(dir string, name string, actual bazel.Label)
276}
277
278type topDownMutatorContext struct {
279	bp blueprint.TopDownMutatorContext
280	baseModuleContext
281}
282
283type BottomUpMutator func(BottomUpMutatorContext)
284
285type BottomUpMutatorContext interface {
286	BaseMutatorContext
287
288	// AddDependency adds a dependency to the given module.  It returns a slice of modules for each
289	// dependency (some entries may be nil).
290	//
291	// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
292	// new dependencies have had the current mutator called on them.  If the mutator is not
293	// parallel this method does not affect the ordering of the current mutator pass, but will
294	// be ordered correctly for all future mutator passes.
295	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
296
297	// AddReverseDependency adds a dependency from the destination to the given module.
298	// Does not affect the ordering of the current mutator pass, but will be ordered
299	// correctly for all future mutator passes.  All reverse dependencies for a destination module are
300	// collected until the end of the mutator pass, sorted by name, and then appended to the destination
301	// module's dependency list.
302	AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
303
304	// CreateVariations splits  a module into multiple variants, one for each name in the variationNames
305	// parameter.  It returns a list of new modules in the same order as the variationNames
306	// list.
307	//
308	// If any of the dependencies of the module being operated on were already split
309	// by calling CreateVariations with the same name, the dependency will automatically
310	// be updated to point the matching variant.
311	//
312	// If a module is split, and then a module depending on the first module is not split
313	// when the Mutator is later called on it, the dependency of the depending module will
314	// automatically be updated to point to the first variant.
315	CreateVariations(...string) []Module
316
317	// CreateLocationVariations splits a module into multiple variants, one for each name in the variantNames
318	// parameter.  It returns a list of new modules in the same order as the variantNames
319	// list.
320	//
321	// Local variations do not affect automatic dependency resolution - dependencies added
322	// to the split module via deps or DynamicDependerModule must exactly match a variant
323	// that contains all the non-local variations.
324	CreateLocalVariations(...string) []Module
325
326	// SetDependencyVariation sets all dangling dependencies on the current module to point to the variation
327	// with given name. This function ignores the default variation set by SetDefaultDependencyVariation.
328	SetDependencyVariation(string)
329
330	// SetDefaultDependencyVariation sets the default variation when a dangling reference is detected
331	// during the subsequent calls on Create*Variations* functions. To reset, set it to nil.
332	SetDefaultDependencyVariation(*string)
333
334	// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
335	// argument to select which variant of the dependency to use.  It returns a slice of modules for
336	// each dependency (some entries may be nil).  A variant of the dependency must exist that matches
337	// all the non-local variations of the current module, plus the variations argument.
338	//
339	// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
340	// new dependencies have had the current mutator called on them.  If the mutator is not
341	// parallel this method does not affect the ordering of the current mutator pass, but will
342	// be ordered correctly for all future mutator passes.
343	AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
344
345	// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
346	// variations argument to select which variant of the dependency to use.  It returns a slice of
347	// modules for each dependency (some entries may be nil).  A variant of the dependency must
348	// exist that matches the variations argument, but may also have other variations.
349	// For any unspecified variation the first variant will be used.
350	//
351	// Unlike AddVariationDependencies, the variations of the current module are ignored - the
352	// dependency only needs to match the supplied variations.
353	//
354	// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
355	// new dependencies have had the current mutator called on them.  If the mutator is not
356	// parallel this method does not affect the ordering of the current mutator pass, but will
357	// be ordered correctly for all future mutator passes.
358	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
359
360	// AddInterVariantDependency adds a dependency between two variants of the same module.  Variants are always
361	// ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change
362	// that ordering, but it associates a DependencyTag with the dependency and makes it visible to VisitDirectDeps,
363	// WalkDeps, etc.
364	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
365
366	// ReplaceDependencies replaces all dependencies on the identical variant of the module with the
367	// specified name with the current variant of this module.  Replacements don't take effect until
368	// after the mutator pass is finished.
369	ReplaceDependencies(string)
370
371	// ReplaceDependencies replaces all dependencies on the identical variant of the module with the
372	// specified name with the current variant of this module as long as the supplied predicate returns
373	// true.
374	//
375	// Replacements don't take effect until after the mutator pass is finished.
376	ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
377
378	// AliasVariation takes a variationName that was passed to CreateVariations for this module,
379	// and creates an alias from the current variant (before the mutator has run) to the new
380	// variant.  The alias will be valid until the next time a mutator calls CreateVariations or
381	// CreateLocalVariations on this module without also calling AliasVariation.  The alias can
382	// be used to add dependencies on the newly created variant using the variant map from
383	// before CreateVariations was run.
384	AliasVariation(variationName string)
385
386	// CreateAliasVariation takes a toVariationName that was passed to CreateVariations for this
387	// module, and creates an alias from a new fromVariationName variant the toVariationName
388	// variant.  The alias will be valid until the next time a mutator calls CreateVariations or
389	// CreateLocalVariations on this module without also calling AliasVariation.  The alias can
390	// be used to add dependencies on the toVariationName variant using the fromVariationName
391	// variant.
392	CreateAliasVariation(fromVariationName, toVariationName string)
393
394	// SetVariationProvider sets the value for a provider for the given newly created variant of
395	// the current module, i.e. one of the Modules returned by CreateVariations..  It panics if
396	// not called during the appropriate mutator or GenerateBuildActions pass for the provider,
397	// if the value is not of the appropriate type, or if the module is not a newly created
398	// variant of the current module.  The value should not be modified after being passed to
399	// SetVariationProvider.
400	SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{})
401}
402
403type bottomUpMutatorContext struct {
404	bp blueprint.BottomUpMutatorContext
405	baseModuleContext
406	finalPhase bool
407}
408
409func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
410	finalPhase, bazelConversionMode bool) BottomUpMutatorContext {
411
412	moduleContext := a.base().baseModuleContextFactory(ctx)
413	moduleContext.bazelConversionMode = bazelConversionMode
414
415	return &bottomUpMutatorContext{
416		bp:                ctx,
417		baseModuleContext: moduleContext,
418		finalPhase:        finalPhase,
419	}
420}
421
422func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
423	finalPhase := x.finalPhase
424	bazelConversionMode := x.bazelConversionMode
425	f := func(ctx blueprint.BottomUpMutatorContext) {
426		if a, ok := ctx.Module().(Module); ok {
427			m(bottomUpMutatorContextFactory(ctx, a, finalPhase, bazelConversionMode))
428		}
429	}
430	mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f}
431	x.mutators = append(x.mutators, mutator)
432	return mutator
433}
434
435func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle {
436	mutator := &mutator{name: name, bottomUpMutator: m}
437	x.mutators = append(x.mutators, mutator)
438	return mutator
439}
440
441type IncomingTransitionContext interface {
442	// Module returns the target of the dependency edge for which the transition
443	// is being computed
444	Module() Module
445
446	// Config returns the configuration for the build.
447	Config() Config
448}
449
450type OutgoingTransitionContext interface {
451	// Module returns the target of the dependency edge for which the transition
452	// is being computed
453	Module() Module
454
455	// DepTag() Returns the dependency tag through which this dependency is
456	// reached
457	DepTag() blueprint.DependencyTag
458}
459
460// Transition mutators implement a top-down mechanism where a module tells its
461// direct dependencies what variation they should be built in but the dependency
462// has the final say.
463//
464// When implementing a transition mutator, one needs to implement four methods:
465//   - Split() that tells what variations a module has by itself
466//   - OutgoingTransition() where a module tells what it wants from its
467//     dependency
468//   - IncomingTransition() where a module has the final say about its own
469//     variation
470//   - Mutate() that changes the state of a module depending on its variation
471//
472// That the effective variation of module B when depended on by module A is the
473// composition the outgoing transition of module A and the incoming transition
474// of module B.
475//
476// the outgoing transition should not take the properties of the dependency into
477// account, only those of the module that depends on it. For this reason, the
478// dependency is not even passed into it as an argument. Likewise, the incoming
479// transition should not take the properties of the depending module into
480// account and is thus not informed about it. This makes for a nice
481// decomposition of the decision logic.
482//
483// A given transition mutator only affects its own variation; other variations
484// stay unchanged along the dependency edges.
485//
486// Soong makes sure that all modules are created in the desired variations and
487// that dependency edges are set up correctly. This ensures that "missing
488// variation" errors do not happen and allows for more flexible changes in the
489// value of the variation among dependency edges (as oppposed to bottom-up
490// mutators where if module A in variation X depends on module B and module B
491// has that variation X, A must depend on variation X of B)
492//
493// The limited power of the context objects passed to individual mutators
494// methods also makes it more difficult to shoot oneself in the foot. Complete
495// safety is not guaranteed because no one prevents individual transition
496// mutators from mutating modules in illegal ways and for e.g. Split() or
497// Mutate() to run their own visitations of the transitive dependency of the
498// module and both of these are bad ideas, but it's better than no guardrails at
499// all.
500//
501// This model is pretty close to Bazel's configuration transitions. The mapping
502// between concepts in Soong and Bazel is as follows:
503//   - Module == configured target
504//   - Variant == configuration
505//   - Variation name == configuration flag
506//   - Variation == configuration flag value
507//   - Outgoing transition == attribute transition
508//   - Incoming transition == rule transition
509//
510// The Split() method does not have a Bazel equivalent and Bazel split
511// transitions do not have a Soong equivalent.
512//
513// Mutate() does not make sense in Bazel due to the different models of the
514// two systems: when creating new variations, Soong clones the old module and
515// thus some way is needed to change it state whereas Bazel creates each
516// configuration of a given configured target anew.
517type TransitionMutator interface {
518	// Split returns the set of variations that should be created for a module no
519	// matter who depends on it. Used when Make depends on a particular variation
520	// or when the module knows its variations just based on information given to
521	// it in the Blueprint file. This method should not mutate the module it is
522	// called on.
523	Split(ctx BaseModuleContext) []string
524
525	// Called on a module to determine which variation it wants from its direct
526	// dependencies. The dependency itself can override this decision. This method
527	// should not mutate the module itself.
528	OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
529
530	// Called on a module to determine which variation it should be in based on
531	// the variation modules that depend on it want. This gives the module a final
532	// say about its own variations. This method should not mutate the module
533	// itself.
534	IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
535
536	// Called after a module was split into multiple variations on each variation.
537	// It should not split the module any further but adding new dependencies is
538	// fine. Unlike all the other methods on TransitionMutator, this method is
539	// allowed to mutate the module.
540	Mutate(ctx BottomUpMutatorContext, variation string)
541}
542
543type androidTransitionMutator struct {
544	finalPhase          bool
545	bazelConversionMode bool
546	mutator             TransitionMutator
547}
548
549func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
550	if m, ok := ctx.Module().(Module); ok {
551		moduleContext := m.base().baseModuleContextFactory(ctx)
552		moduleContext.bazelConversionMode = a.bazelConversionMode
553		return a.mutator.Split(&moduleContext)
554	} else {
555		return []string{""}
556	}
557}
558
559type outgoingTransitionContextImpl struct {
560	bp blueprint.OutgoingTransitionContext
561}
562
563func (c *outgoingTransitionContextImpl) Module() Module {
564	return c.bp.Module().(Module)
565}
566
567func (c *outgoingTransitionContextImpl) DepTag() blueprint.DependencyTag {
568	return c.bp.DepTag()
569}
570
571func (a *androidTransitionMutator) OutgoingTransition(ctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
572	if _, ok := ctx.Module().(Module); ok {
573		return a.mutator.OutgoingTransition(&outgoingTransitionContextImpl{bp: ctx}, sourceVariation)
574	} else {
575		return ""
576	}
577}
578
579type incomingTransitionContextImpl struct {
580	bp blueprint.IncomingTransitionContext
581}
582
583func (c *incomingTransitionContextImpl) Module() Module {
584	return c.bp.Module().(Module)
585}
586
587func (c *incomingTransitionContextImpl) Config() Config {
588	return c.bp.Config().(Config)
589}
590
591func (a *androidTransitionMutator) IncomingTransition(ctx blueprint.IncomingTransitionContext, incomingVariation string) string {
592	if _, ok := ctx.Module().(Module); ok {
593		return a.mutator.IncomingTransition(&incomingTransitionContextImpl{bp: ctx}, incomingVariation)
594	} else {
595		return ""
596	}
597}
598
599func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
600	if am, ok := ctx.Module().(Module); ok {
601		a.mutator.Mutate(bottomUpMutatorContextFactory(ctx, am, a.finalPhase, a.bazelConversionMode), variation)
602	}
603}
604
605func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) {
606	atm := &androidTransitionMutator{
607		finalPhase:          x.finalPhase,
608		bazelConversionMode: x.bazelConversionMode,
609		mutator:             m,
610	}
611	mutator := &mutator{
612		name:              name,
613		transitionMutator: atm}
614	x.mutators = append(x.mutators, mutator)
615}
616
617func (x *registerMutatorsContext) mutatorName(name string) string {
618	if x.bazelConversionMode {
619		return name + "_bp2build"
620	}
621	return name
622}
623
624func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
625	f := func(ctx blueprint.TopDownMutatorContext) {
626		if a, ok := ctx.Module().(Module); ok {
627			moduleContext := a.base().baseModuleContextFactory(ctx)
628			moduleContext.bazelConversionMode = x.bazelConversionMode
629			actx := &topDownMutatorContext{
630				bp:                ctx,
631				baseModuleContext: moduleContext,
632			}
633			m(actx)
634		}
635	}
636	mutator := &mutator{name: x.mutatorName(name), topDownMutator: f}
637	x.mutators = append(x.mutators, mutator)
638	return mutator
639}
640
641func (mutator *mutator) componentName() string {
642	return mutator.name
643}
644
645func (mutator *mutator) register(ctx *Context) {
646	blueprintCtx := ctx.Context
647	var handle blueprint.MutatorHandle
648	if mutator.bottomUpMutator != nil {
649		handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
650	} else if mutator.topDownMutator != nil {
651		handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
652	} else if mutator.transitionMutator != nil {
653		blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
654	}
655	if mutator.parallel {
656		handle.Parallel()
657	}
658}
659
660type MutatorHandle interface {
661	Parallel() MutatorHandle
662}
663
664func (mutator *mutator) Parallel() MutatorHandle {
665	mutator.parallel = true
666	return mutator
667}
668
669func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
670	ctx.BottomUp("component-deps", componentDepsMutator).Parallel()
671}
672
673// A special mutator that runs just prior to the deps mutator to allow the dependencies
674// on component modules to be added so that they can depend directly on a prebuilt
675// module.
676func componentDepsMutator(ctx BottomUpMutatorContext) {
677	if m := ctx.Module(); m.Enabled() {
678		m.ComponentDepsMutator(ctx)
679	}
680}
681
682func depsMutator(ctx BottomUpMutatorContext) {
683	if m := ctx.Module(); m.Enabled() {
684		m.DepsMutator(ctx)
685	}
686}
687
688func registerDepsMutator(ctx RegisterMutatorsContext) {
689	ctx.BottomUp("deps", depsMutator).Parallel()
690}
691
692func registerDepsMutatorBp2Build(ctx RegisterMutatorsContext) {
693	// TODO(b/179313531): Consider a separate mutator that only runs depsMutator for modules that are
694	// being converted to build targets.
695	ctx.BottomUp("deps", depsMutator).Parallel()
696}
697
698func (t *topDownMutatorContext) CreateBazelTargetModule(
699	bazelProps bazel.BazelTargetModuleProperties,
700	commonAttrs CommonAttributes,
701	attrs interface{}) {
702	t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{})
703}
704
705func (t *topDownMutatorContext) CreateBazelTargetModuleWithRestrictions(
706	bazelProps bazel.BazelTargetModuleProperties,
707	commonAttrs CommonAttributes,
708	attrs interface{},
709	enabledProperty bazel.BoolAttribute) {
710	t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty)
711}
712
713var (
714	bazelAliasModuleProperties = bazel.BazelTargetModuleProperties{
715		Rule_class: "alias",
716	}
717)
718
719type bazelAliasAttributes struct {
720	Actual *bazel.LabelAttribute
721}
722
723func (t *topDownMutatorContext) CreateBazelTargetAliasInDir(
724	dir string,
725	name string,
726	actual bazel.Label) {
727	mod := t.Module()
728	attrs := &bazelAliasAttributes{
729		Actual: bazel.MakeLabelAttribute(actual.Label),
730	}
731	info := bp2buildInfo{
732		Dir:             dir,
733		BazelProps:      bazelAliasModuleProperties,
734		CommonAttrs:     CommonAttributes{Name: name},
735		ConstraintAttrs: constraintAttributes{},
736		Attrs:           attrs,
737	}
738	mod.base().addBp2buildInfo(info)
739}
740
741// ApexAvailableTags converts the apex_available property value of an ApexModule
742// module and returns it as a list of keyed tags.
743func ApexAvailableTags(mod Module) bazel.StringListAttribute {
744	attr := bazel.StringListAttribute{}
745	// Transform specific attributes into tags.
746	if am, ok := mod.(ApexModule); ok {
747		// TODO(b/218841706): hidl_interface has the apex_available prop, but it's
748		// defined directly as a prop and not via ApexModule, so this doesn't
749		// pick those props up.
750		apexAvailable := am.apexModuleBase().ApexAvailable()
751		// If a user does not specify apex_available in Android.bp, then soong provides a default.
752		// To avoid verbosity of BUILD files, remove this default from user-facing BUILD files.
753		if len(am.apexModuleBase().ApexProperties.Apex_available) == 0 {
754			apexAvailable = []string{}
755		}
756		attr.Value = ConvertApexAvailableToTags(apexAvailable)
757	}
758	return attr
759}
760
761func ConvertApexAvailableToTags(apexAvailable []string) []string {
762	if len(apexAvailable) == 0 {
763		// We need nil specifically to make bp2build not add the tags property at all,
764		// instead of adding it with an empty list
765		return nil
766	}
767	result := make([]string, 0, len(apexAvailable))
768	for _, a := range apexAvailable {
769		result = append(result, "apex_available="+a)
770	}
771	return result
772}
773
774func (t *topDownMutatorContext) createBazelTargetModule(
775	bazelProps bazel.BazelTargetModuleProperties,
776	commonAttrs CommonAttributes,
777	attrs interface{},
778	enabledProperty bazel.BoolAttribute) {
779	constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty)
780	mod := t.Module()
781	info := bp2buildInfo{
782		Dir:             t.OtherModuleDir(mod),
783		BazelProps:      bazelProps,
784		CommonAttrs:     commonAttrs,
785		ConstraintAttrs: constraintAttributes,
786		Attrs:           attrs,
787	}
788	mod.base().addBp2buildInfo(info)
789}
790
791// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
792// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
793// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
794// non-overridden method has to be forwarded.  There are fewer non-overridden methods, so use the latter.  The following
795// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext.
796
797func (t *topDownMutatorContext) MutatorName() string {
798	return t.bp.MutatorName()
799}
800
801func (t *topDownMutatorContext) Rename(name string) {
802	t.bp.Rename(name)
803	t.Module().base().commonProperties.DebugName = name
804}
805
806func (t *topDownMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
807	return t.bp.CreateModule(factory, name, props...)
808}
809
810func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
811	return createModule(t, factory, "_topDownMutatorModule", props...)
812}
813
814func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module {
815	module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), "", props...).(Module)
816	return module
817}
818
819func (b *bottomUpMutatorContext) MutatorName() string {
820	return b.bp.MutatorName()
821}
822
823func (b *bottomUpMutatorContext) Rename(name string) {
824	b.bp.Rename(name)
825	b.Module().base().commonProperties.DebugName = name
826}
827
828func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
829	return b.bp.AddDependency(module, tag, name...)
830}
831
832func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
833	b.bp.AddReverseDependency(module, tag, name)
834}
835
836func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
837	if b.finalPhase {
838		panic("CreateVariations not allowed in FinalDepsMutators")
839	}
840
841	modules := b.bp.CreateVariations(variations...)
842
843	aModules := make([]Module, len(modules))
844	for i := range variations {
845		aModules[i] = modules[i].(Module)
846		base := aModules[i].base()
847		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
848		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
849	}
850
851	return aModules
852}
853
854func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
855	if b.finalPhase {
856		panic("CreateLocalVariations not allowed in FinalDepsMutators")
857	}
858
859	modules := b.bp.CreateLocalVariations(variations...)
860
861	aModules := make([]Module, len(modules))
862	for i := range variations {
863		aModules[i] = modules[i].(Module)
864		base := aModules[i].base()
865		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
866		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
867	}
868
869	return aModules
870}
871
872func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) {
873	b.bp.SetDependencyVariation(variation)
874}
875
876func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
877	b.bp.SetDefaultDependencyVariation(variation)
878}
879
880func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
881	names ...string) []blueprint.Module {
882	return b.bp.AddVariationDependencies(variations, tag, names...)
883}
884
885func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
886	tag blueprint.DependencyTag, names ...string) []blueprint.Module {
887
888	return b.bp.AddFarVariationDependencies(variations, tag, names...)
889}
890
891func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) {
892	b.bp.AddInterVariantDependency(tag, from, to)
893}
894
895func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
896	b.bp.ReplaceDependencies(name)
897}
898
899func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
900	b.bp.ReplaceDependenciesIf(name, predicate)
901}
902
903func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
904	b.bp.AliasVariation(variationName)
905}
906
907func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) {
908	b.bp.CreateAliasVariation(fromVariationName, toVariationName)
909}
910
911func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) {
912	b.bp.SetVariationProvider(module, provider, value)
913}
914