• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 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 blueprint
16
17import (
18	"errors"
19	"fmt"
20	"path/filepath"
21	"sort"
22	"strings"
23	"sync"
24	"text/scanner"
25
26	"github.com/google/blueprint/parser"
27	"github.com/google/blueprint/pathtools"
28	"github.com/google/blueprint/proptools"
29	"github.com/google/blueprint/uniquelist"
30)
31
32// A Module handles generating all of the Ninja build actions needed to build a
33// single module based on properties defined in a Blueprints file.  Module
34// objects are initially created during the parse phase of a Context using one
35// of the registered module types (and the associated ModuleFactory function).
36// The Module's properties struct is automatically filled in with the property
37// values specified in the Blueprints file (see Context.RegisterModuleType for more
38// information on this).
39//
40// A Module can be split into multiple Modules by a Mutator.  All existing
41// properties set on the module will be duplicated to the new Module, and then
42// modified as necessary by the Mutator.
43//
44// The Module implementation can access the build configuration as well as any
45// modules on which it depends (as defined by the "deps" property
46// specified in the Blueprints file, dynamically added by implementing the
47// (deprecated) DynamicDependerModule interface, or dynamically added by a
48// BottomUpMutator) using the ModuleContext passed to GenerateBuildActions.
49// This ModuleContext is also used to create Ninja build actions and to report
50// errors to the user.
51//
52// In addition to implementing the GenerateBuildActions method, a Module should
53// implement methods that provide dependant modules and singletons information
54// they need to generate their build actions.  These methods will only be called
55// after GenerateBuildActions is called because the Context calls
56// GenerateBuildActions in dependency-order (and singletons are invoked after
57// all the Modules).  The set of methods a Module supports will determine how
58// dependant Modules interact with it.
59//
60// For example, consider a Module that is responsible for generating a library
61// that other modules can link against.  The library Module might implement the
62// following interface:
63//
64//	type LibraryProducer interface {
65//	    LibraryFileName() string
66//	}
67//
68//	func IsLibraryProducer(module blueprint.Module) {
69//	    _, ok := module.(LibraryProducer)
70//	    return ok
71//	}
72//
73// A binary-producing Module that depends on the library Module could then do:
74//
75//	func (m *myBinaryModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
76//	    ...
77//	    var libraryFiles []string
78//	    ctx.VisitDepsDepthFirstIf(IsLibraryProducer,
79//	        func(module blueprint.Module) {
80//	            libProducer := module.(LibraryProducer)
81//	            libraryFiles = append(libraryFiles, libProducer.LibraryFileName())
82//	        })
83//	    ...
84//	}
85//
86// to build the list of library file names that should be included in its link
87// command.
88//
89// GenerateBuildActions may be called from multiple threads.  It is guaranteed to
90// be called after it has finished being called on all dependencies and on all
91// variants of that appear earlier in the ModuleContext.VisitAllModuleVariants list.
92// Any accesses to global variables or to Module objects that are not dependencies
93// or variants of the current Module must be synchronized by the implementation of
94// GenerateBuildActions.
95type Module interface {
96	// Name returns a string used to uniquely identify each module.  The return
97	// value must be unique across all modules.  It is only called once, during
98	// initial blueprint parsing.  To change the name later a mutator must call
99	// MutatorContext.Rename
100	//
101	// In most cases, Name should return the contents of a "name:" property from
102	// the blueprint file.  An embeddable SimpleName object can be used for this
103	// case.
104	Name() string
105
106	// GenerateBuildActions is called by the Context that created the Module
107	// during its generate phase.  This call should generate all Ninja build
108	// actions (rules, pools, and build statements) needed to build the module.
109	GenerateBuildActions(ModuleContext)
110
111	String() string
112}
113
114type ModuleProxy struct {
115	module Module
116}
117
118func CreateModuleProxy(module Module) ModuleProxy {
119	return ModuleProxy{
120		module: module,
121	}
122}
123
124func (m ModuleProxy) IsNil() bool {
125	return m.module == nil
126}
127
128func (m ModuleProxy) Name() string {
129	return m.module.Name()
130}
131
132func (m ModuleProxy) String() string {
133	return m.module.String()
134}
135func (m ModuleProxy) GenerateBuildActions(context ModuleContext) {
136	m.module.GenerateBuildActions(context)
137}
138
139// A DynamicDependerModule is a Module that may add dependencies that do not
140// appear in its "deps" property.  Any Module that implements this interface
141// will have its DynamicDependencies method called by the Context that created
142// it during generate phase.
143//
144// Deprecated, use a BottomUpMutator instead
145type DynamicDependerModule interface {
146	Module
147
148	// DynamicDependencies is called by the Context that created the
149	// DynamicDependerModule during its generate phase.  This call should return
150	// the list of module names that the DynamicDependerModule depends on
151	// dynamically.  Module names that already appear in the "deps" property may
152	// but do not need to be included in the returned list.
153	DynamicDependencies(DynamicDependerModuleContext) []string
154}
155
156type EarlyModuleContext interface {
157	// Module returns the current module as a Module.  It should rarely be necessary, as the module already has a
158	// reference to itself.
159	Module() Module
160
161	// ModuleName returns the name of the module.  This is generally the value that was returned by Module.Name() when
162	// the module was created, but may have been modified by calls to BottomUpMutatorContext.Rename.
163	ModuleName() string
164
165	// ModuleDir returns the path to the directory that contains the definition of the module.
166	ModuleDir() string
167
168	// ModuleType returns the name of the module type that was used to create the module, as specified in
169	// Context.RegisterModuleType().
170	ModuleType() string
171
172	// ModuleTags returns the tags for this module that should be passed to
173	// ninja for analysis. For example:
174	// [
175	//   "module_name": "libfoo",
176	//   "module_type": "cc_library",
177	// ]
178	ModuleTags() map[string]string
179
180	// BlueprintsFile returns the name of the blueprint file that contains the definition of this
181	// module.
182	BlueprintsFile() string
183
184	// Config returns the config object that was passed to Context.PrepareBuildActions.
185	Config() interface{}
186
187	// ContainsProperty returns true if the specified property name was set in the module definition.
188	ContainsProperty(name string) bool
189
190	// Errorf reports an error at the specified position of the module definition file.
191	Errorf(pos scanner.Position, fmt string, args ...interface{})
192
193	// ModuleErrorf reports an error at the line number of the module type in the module definition.
194	ModuleErrorf(fmt string, args ...interface{})
195
196	// PropertyErrorf reports an error at the line number of a property in the module definition.
197	PropertyErrorf(property, fmt string, args ...interface{})
198
199	// OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition.
200	OtherModulePropertyErrorf(logicModule Module, property string, format string, args ...interface{})
201
202	// Failed returns true if any errors have been reported.  In most cases the module can continue with generating
203	// build rules after an error, allowing it to report additional errors in a single run, but in cases where the error
204	// has prevented the module from creating necessary data it can return early when Failed returns true.
205	Failed() bool
206
207	// GlobWithDeps returns a list of files and directories that match the
208	// specified pattern but do not match any of the patterns in excludes.
209	// Any directories will have a '/' suffix.  It also adds efficient
210	// dependencies to rerun the primary builder whenever a file matching
211	// the pattern as added or removed, without rerunning if a file that
212	// does not match the pattern is added to a searched directory.
213	GlobWithDeps(pattern string, excludes []string) ([]string, error)
214
215	// Fs returns a pathtools.Filesystem that can be used to interact with files.  Using the Filesystem interface allows
216	// the module to be used in build system tests that run against a mock filesystem.
217	Fs() pathtools.FileSystem
218
219	// AddNinjaFileDeps adds dependencies on the specified files to the rule that creates the ninja manifest.  The
220	// primary builder will be rerun whenever the specified files are modified.
221	AddNinjaFileDeps(deps ...string)
222
223	moduleInfo() *moduleInfo
224
225	error(err error)
226
227	// Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the
228	// default SimpleNameInterface if Context.SetNameInterface was not called.
229	Namespace() Namespace
230
231	// ModuleFactories returns a map of all of the global ModuleFactories by name.
232	ModuleFactories() map[string]ModuleFactory
233
234	// HasMutatorFinished returns true if the given mutator has finished running.
235	// It will panic if given an invalid mutator name.
236	HasMutatorFinished(mutatorName string) bool
237}
238
239type BaseModuleContext interface {
240	EarlyModuleContext
241
242	// GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
243	// none exists.  It panics if the dependency does not have the specified tag.
244	GetDirectDepWithTag(name string, tag DependencyTag) Module
245
246	GetDirectDepProxyWithTag(name string, tag DependencyTag) *ModuleProxy
247
248	// VisitDirectDeps calls visit for each direct dependency.  If there are multiple direct dependencies on the same
249	// module visit will be called multiple times on that module and OtherModuleDependencyTag will return a different
250	// tag for each.
251	//
252	// The Module passed to the visit function should not be retained outside of the visit function, it may be
253	// invalidated by future mutators.
254	VisitDirectDeps(visit func(Module))
255
256	VisitDirectDepsProxy(visit func(proxy ModuleProxy))
257
258	// VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit.  If there are
259	// multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
260	// OtherModuleDependencyTag will return a different tag for each.
261	//
262	// The Module passed to the visit function should not be retained outside of the visit function, it may be
263	// invalidated by future mutators.
264	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
265
266	// VisitDepsDepthFirst calls visit for each transitive dependency, traversing the dependency tree in depth first
267	// order. visit will only be called once for any given module, even if there are multiple paths through the
268	// dependency tree to the module or multiple direct dependencies with different tags.  OtherModuleDependencyTag will
269	// return the tag for the first path found to the module.
270	//
271	// The Module passed to the visit function should not be retained outside of the visit function, it may be
272	// invalidated by future mutators.
273	VisitDepsDepthFirst(visit func(Module))
274
275	// VisitDepsDepthFirstIf calls pred for each transitive dependency, and if pred returns true calls visit, traversing
276	// the dependency tree in depth first order.  visit will only be called once for any given module, even if there are
277	// multiple paths through the dependency tree to the module or multiple direct dependencies with different tags.
278	// OtherModuleDependencyTag will return the tag for the first path found to the module.  The return value of pred
279	// does not affect which branches of the tree are traversed.
280	//
281	// The Module passed to the visit function should not be retained outside of the visit function, it may be
282	// invalidated by future mutators.
283	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
284
285	// WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order.  visit may
286	// be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
287	// child and parent with different tags.  OtherModuleDependencyTag will return the tag for the currently visited
288	// (child, parent) pair.  If visit returns false WalkDeps will not continue recursing down to child.
289	//
290	// The Modules passed to the visit function should not be retained outside of the visit function, they may be
291	// invalidated by future mutators.
292	WalkDeps(visit func(Module, Module) bool)
293
294	WalkDepsProxy(visit func(ModuleProxy, ModuleProxy) bool)
295
296	// PrimaryModule returns the first variant of the current module.  Variants of a module are always visited in
297	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
298	// Module returned by PrimaryModule without data races.  This can be used to perform singleton actions that are
299	// only done once for all variants of a module.
300	PrimaryModule() Module
301
302	// FinalModule returns the last variant of the current module.  Variants of a module are always visited in
303	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
304	// variants using VisitAllModuleVariants if the current module == FinalModule().  This can be used to perform
305	// singleton actions that are only done once for all variants of a module.
306	FinalModule() Module
307
308	// IsFinalModule returns if the current module is the last variant.  Variants of a module are always visited in
309	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
310	// variants using VisitAllModuleVariants if the current module is the last one.  This can be used to perform
311	// singleton actions that are only done once for all variants of a module.
312	IsFinalModule(module Module) bool
313
314	// VisitAllModuleVariants calls visit for each variant of the current module.  Variants of a module are always
315	// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
316	// from all variants if the current module is the last one.  Otherwise, care must be taken to not access any
317	// data modified by the current mutator.
318	VisitAllModuleVariants(visit func(Module))
319
320	// VisitAllModuleVariantProxies calls visit for each variant of the current module.  Variants of a module are always
321	// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
322	// from all variants if the current module is the last one.  Otherwise, care must be taken to not access any
323	// data modified by the current mutator.
324	VisitAllModuleVariantProxies(visit func(proxy ModuleProxy))
325
326	// OtherModuleName returns the name of another Module.  See BaseModuleContext.ModuleName for more information.
327	// It is intended for use inside the visit functions of Visit* and WalkDeps.
328	OtherModuleName(m Module) string
329
330	// OtherModuleDir returns the directory of another Module.  See BaseModuleContext.ModuleDir for more information.
331	// It is intended for use inside the visit functions of Visit* and WalkDeps.
332	OtherModuleDir(m Module) string
333
334	// OtherModuleType returns the type of another Module.  See BaseModuleContext.ModuleType for more information.
335	// It is intended for use inside the visit functions of Visit* and WalkDeps.
336	OtherModuleType(m Module) string
337
338	// OtherModuleErrorf reports an error on another Module.  See BaseModuleContext.ModuleErrorf for more information.
339	// It is intended for use inside the visit functions of Visit* and WalkDeps.
340	OtherModuleErrorf(m Module, fmt string, args ...interface{})
341
342	// OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
343	// on the module.  When called inside a Visit* method with current module being visited, and there are multiple
344	// dependencies on the module being visited, it returns the dependency tag used for the current dependency.
345	OtherModuleDependencyTag(m Module) DependencyTag
346
347	// OtherModuleSubDir returns the string representing the variations of the module.
348	OtherModuleSubDir(m Module) string
349
350	// OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
351	// passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
352	OtherModuleExists(name string) bool
353
354	// ModuleFromName returns (module, true) if a module exists by the given name and same context namespace,
355	// or (nil, false) if it does not exist. It panics if there is either more than one
356	// module of the given name, or if the given name refers to an alias instead of a module.
357	// There are no guarantees about which variant of the module will be returned.
358	// Prefer retrieving the module using GetDirectDep or a visit function, when possible, as
359	// this will guarantee the appropriate module-variant dependency is returned.
360	//
361	// WARNING: This should _only_ be used within the context of bp2build, where variants and
362	// dependencies are not created.
363	ModuleFromName(name string) (Module, bool)
364
365	// OtherModuleDependencyVariantExists returns true if a module with the
366	// specified name and variant exists. The variant must match the given
367	// variations. It must also match all the non-local variations of the current
368	// module. In other words, it checks for the module that AddVariationDependencies
369	// would add a dependency on with the same arguments.
370	OtherModuleDependencyVariantExists(variations []Variation, name string) bool
371
372	// OtherModuleFarDependencyVariantExists returns true if a module with the
373	// specified name and variant exists. The variant must match the given
374	// variations, but not the non-local variations of the current module. In
375	// other words, it checks for the module that AddFarVariationDependencies
376	// would add a dependency on with the same arguments.
377	OtherModuleFarDependencyVariantExists(variations []Variation, name string) bool
378
379	// OtherModuleReverseDependencyVariantExists returns true if a module with the
380	// specified name exists with the same variations as the current module. In
381	// other words, it checks for the module that AddReverseDependency would add a
382	// dependency on with the same argument.
383	OtherModuleReverseDependencyVariantExists(name string) bool
384
385	// OtherModuleProvider returns the value for a provider for the given module.  If the value is
386	// not set it returns nil and false.  The value returned may be a deep copy of the value originally
387	// passed to SetProvider.
388	//
389	// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
390	OtherModuleProvider(m Module, provider AnyProviderKey) (any, bool)
391
392	OtherModuleHasProvider(m Module, provider AnyProviderKey) bool
393
394	// OtherModuleIsAutoGenerated returns true if a module has been generated from another module,
395	// instead of being defined in Android.bp file
396	OtherModuleIsAutoGenerated(m Module) bool
397
398	// Provider returns the value for a provider for the current module.  If the value is
399	// not set it returns nil and false.  It panics if called before the appropriate
400	// mutator or GenerateBuildActions pass for the provider.  The value returned may be a deep
401	// copy of the value originally passed to SetProvider.
402	//
403	// This method shouldn't be used directly, prefer the type-safe android.ModuleProvider instead.
404	Provider(provider AnyProviderKey) (any, bool)
405
406	// SetProvider sets the value for a provider for the current module.  It panics if not called
407	// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
408	// is not of the appropriate type, or if the value has already been set.  The value should not
409	// be modified after being passed to SetProvider.
410	//
411	// This method shouldn't be used directly, prefer the type-safe android.SetProvider instead.
412	SetProvider(provider AnyProviderKey, value any)
413
414	EarlyGetMissingDependencies() []string
415
416	base() *baseModuleContext
417}
418
419type DynamicDependerModuleContext BottomUpMutatorContext
420
421type ModuleContext interface {
422	BaseModuleContext
423
424	// ModuleSubDir returns a unique name for the current variant of a module that can be used as part of the path
425	// to ensure that each variant of a module gets its own intermediates directory to write to.
426	ModuleSubDir() string
427
428	ModuleCacheKey() string
429
430	// Variable creates a new ninja variable scoped to the module.  It can be referenced by calls to Rule and Build
431	// in the same module.
432	Variable(pctx PackageContext, name, value string)
433
434	// Rule creates a new ninja rule scoped to the module.  It can be referenced by calls to Build in the same module.
435	Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
436
437	// Build creates a new ninja build statement.
438	Build(pctx PackageContext, params BuildParams)
439
440	// GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods,
441	// but do not exist.  It can be used with Context.SetAllowMissingDependencies to allow the primary builder to
442	// handle missing dependencies on its own instead of having Blueprint treat them as an error.
443	GetMissingDependencies() []string
444}
445
446var _ BaseModuleContext = (*baseModuleContext)(nil)
447
448type baseModuleContext struct {
449	context        *Context
450	config         interface{}
451	module         *moduleInfo
452	errs           []error
453	visitingParent *moduleInfo
454	visitingDep    depInfo
455	ninjaFileDeps  []string
456}
457
458func (d *baseModuleContext) moduleInfo() *moduleInfo {
459	return d.module
460}
461
462func (d *baseModuleContext) Module() Module {
463	return d.module.logicModule
464}
465
466func (d *baseModuleContext) ModuleName() string {
467	return d.module.Name()
468}
469
470func (d *baseModuleContext) ModuleType() string {
471	return d.module.typeName
472}
473
474func (d *baseModuleContext) ModuleTags() map[string]string {
475	return map[string]string{
476		"module_name": d.ModuleName(),
477		"module_type": d.ModuleType(),
478	}
479}
480
481func (d *baseModuleContext) ContainsProperty(name string) bool {
482	_, ok := d.module.propertyPos[name]
483	return ok
484}
485
486func (d *baseModuleContext) ModuleDir() string {
487	return filepath.Dir(d.module.relBlueprintsFile)
488}
489
490func (d *baseModuleContext) BlueprintsFile() string {
491	return d.module.relBlueprintsFile
492}
493
494func (d *baseModuleContext) Config() interface{} {
495	return d.config
496}
497
498func (d *baseModuleContext) error(err error) {
499	if err != nil {
500		d.errs = append(d.errs, err)
501	}
502}
503
504func (d *baseModuleContext) Errorf(pos scanner.Position,
505	format string, args ...interface{}) {
506
507	d.error(&BlueprintError{
508		Err: fmt.Errorf(format, args...),
509		Pos: pos,
510	})
511}
512
513func (d *baseModuleContext) ModuleErrorf(format string,
514	args ...interface{}) {
515
516	d.error(d.context.moduleErrorf(d.module, format, args...))
517}
518
519func (d *baseModuleContext) PropertyErrorf(property, format string,
520	args ...interface{}) {
521
522	d.error(d.context.PropertyErrorf(d.module.logicModule, property, format, args...))
523}
524
525func (d *baseModuleContext) OtherModulePropertyErrorf(logicModule Module, property string, format string,
526	args ...interface{}) {
527
528	d.error(d.context.PropertyErrorf(getWrappedModule(logicModule), property, format, args...))
529}
530
531func (d *baseModuleContext) Failed() bool {
532	return len(d.errs) > 0
533}
534
535func (d *baseModuleContext) GlobWithDeps(pattern string,
536	excludes []string) ([]string, error) {
537	return d.context.glob(pattern, excludes)
538}
539
540func (d *baseModuleContext) Fs() pathtools.FileSystem {
541	return d.context.fs
542}
543
544func (d *baseModuleContext) Namespace() Namespace {
545	return d.context.nameInterface.GetNamespace(newNamespaceContext(d.module))
546}
547
548func (d *baseModuleContext) HasMutatorFinished(mutatorName string) bool {
549	return d.context.HasMutatorFinished(mutatorName)
550}
551
552var _ ModuleContext = (*moduleContext)(nil)
553
554type moduleContext struct {
555	baseModuleContext
556	scope              *localScope
557	actionDefs         localBuildActions
558	handledMissingDeps bool
559}
560
561func EqualModules(m1, m2 Module) bool {
562	return getWrappedModule(m1) == getWrappedModule(m2)
563}
564
565func (m *baseModuleContext) OtherModuleName(logicModule Module) string {
566	module := m.context.moduleInfo[getWrappedModule(logicModule)]
567	return module.Name()
568}
569
570func (m *baseModuleContext) OtherModuleDir(logicModule Module) string {
571	module := m.context.moduleInfo[getWrappedModule(logicModule)]
572	return filepath.Dir(module.relBlueprintsFile)
573}
574
575func (m *baseModuleContext) OtherModuleType(logicModule Module) string {
576	module := m.context.moduleInfo[getWrappedModule(logicModule)]
577	return module.typeName
578}
579
580func (m *baseModuleContext) OtherModuleErrorf(logicModule Module, format string,
581	args ...interface{}) {
582
583	module := m.context.moduleInfo[getWrappedModule(logicModule)]
584	m.errs = append(m.errs, &ModuleError{
585		BlueprintError: BlueprintError{
586			Err: fmt.Errorf(format, args...),
587			Pos: module.pos,
588		},
589		module: module,
590	})
591}
592
593func getWrappedModule(module Module) Module {
594	if mp, isProxy := module.(ModuleProxy); isProxy {
595		return mp.module
596	}
597	return module
598}
599
600func (m *baseModuleContext) OtherModuleDependencyTag(logicModule Module) DependencyTag {
601	// fast path for calling OtherModuleDependencyTag from inside VisitDirectDeps
602	if m.visitingDep.module != nil && getWrappedModule(logicModule) == m.visitingDep.module.logicModule {
603		return m.visitingDep.tag
604	}
605
606	if m.visitingParent == nil {
607		return nil
608	}
609
610	for _, dep := range m.visitingParent.directDeps {
611		if dep.module.logicModule == getWrappedModule(logicModule) {
612			return dep.tag
613		}
614	}
615
616	return nil
617}
618
619func (m *baseModuleContext) OtherModuleSubDir(logicModule Module) string {
620	return m.context.ModuleSubDir(getWrappedModule(logicModule))
621}
622
623func (m *baseModuleContext) ModuleFromName(name string) (Module, bool) {
624	moduleGroup, exists := m.context.nameInterface.ModuleFromName(name, m.module.namespace())
625	if exists {
626		if len(moduleGroup.modules) != 1 {
627			panic(fmt.Errorf("Expected exactly one module named %q, but got %d", name, len(moduleGroup.modules)))
628		}
629		moduleInfo := moduleGroup.modules[0]
630		if moduleInfo != nil {
631			return moduleInfo.logicModule, true
632		} else {
633			panic(fmt.Errorf(`Expected actual module named %q, but group did not contain a module.
634    There may instead be an alias by that name.`, name))
635		}
636	}
637	return nil, exists
638}
639
640func (m *baseModuleContext) OtherModuleExists(name string) bool {
641	_, exists := m.context.nameInterface.ModuleFromName(name, m.module.namespace())
642	return exists
643}
644
645func (m *baseModuleContext) OtherModuleDependencyVariantExists(variations []Variation, name string) bool {
646	possibleDeps := m.context.moduleGroupFromName(name, m.module.namespace())
647	if possibleDeps == nil {
648		return false
649	}
650	found, _, errs := m.context.findVariant(m.module, m.config, possibleDeps, variations, false, false)
651	if errs != nil {
652		panic(errors.Join(errs...))
653	}
654	return found != nil
655}
656
657func (m *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []Variation, name string) bool {
658	possibleDeps := m.context.moduleGroupFromName(name, m.module.namespace())
659	if possibleDeps == nil {
660		return false
661	}
662	found, _, errs := m.context.findVariant(m.module, m.config, possibleDeps, variations, true, false)
663	if errs != nil {
664		panic(errors.Join(errs...))
665	}
666	return found != nil
667}
668
669func (m *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
670	possibleDeps := m.context.moduleGroupFromName(name, m.module.namespace())
671	if possibleDeps == nil {
672		return false
673	}
674	found, _, errs := m.context.findVariant(m.module, m.config, possibleDeps, nil, false, true)
675	if errs != nil {
676		panic(errors.Join(errs...))
677	}
678	return found != nil
679}
680
681func (m *baseModuleContext) OtherModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) {
682	module := m.context.moduleInfo[getWrappedModule(logicModule)]
683	return m.context.provider(module, provider.provider())
684}
685
686func (m *baseModuleContext) OtherModuleHasProvider(logicModule Module, provider AnyProviderKey) bool {
687	module := m.context.moduleInfo[getWrappedModule(logicModule)]
688	return m.context.hasProvider(module, provider.provider())
689}
690
691func (m *baseModuleContext) Provider(provider AnyProviderKey) (any, bool) {
692	return m.context.provider(m.module, provider.provider())
693}
694
695func (m *baseModuleContext) SetProvider(provider AnyProviderKey, value interface{}) {
696	m.context.setProvider(m.module, provider.provider(), value)
697}
698
699func (m *moduleContext) restoreModuleBuildActions() bool {
700	// Whether the incremental flag is set and the module type supports
701	// incremental, this will decide weather to cache the data for the module.
702	incrementalEnabled := false
703	// Whether the above conditions are true and we can try to restore from
704	// the cache for this module, i.e., no env, product variables and Soong
705	// code changes.
706	incrementalAnalysis := false
707	var cacheKey *BuildActionCacheKey = nil
708	if m.context.GetIncrementalEnabled() {
709		if im, ok := m.module.logicModule.(Incremental); ok {
710			incrementalEnabled = im.IncrementalSupported()
711			incrementalAnalysis = m.context.GetIncrementalAnalysis() && incrementalEnabled
712		}
713	}
714	if incrementalEnabled {
715		hash, err := proptools.CalculateHash(m.module.properties)
716		if err != nil {
717			panic(newPanicErrorf(err, "failed to calculate properties hash"))
718		}
719		cacheInput := new(BuildActionCacheInput)
720		cacheInput.PropertiesHash = hash
721		m.VisitDirectDeps(func(module Module) {
722			cacheInput.ProvidersHash =
723				append(cacheInput.ProvidersHash, m.context.moduleInfo[module].providerInitialValueHashes)
724		})
725		hash, err = proptools.CalculateHash(&cacheInput)
726		if err != nil {
727			panic(newPanicErrorf(err, "failed to calculate cache input hash"))
728		}
729		cacheKey = &BuildActionCacheKey{
730			Id:        m.ModuleCacheKey(),
731			InputHash: hash,
732		}
733		m.module.buildActionCacheKey = cacheKey
734	}
735
736	restored := false
737	if incrementalAnalysis && cacheKey != nil {
738		// Try to restore from cache if there is a cache hit
739		data := m.context.getBuildActionsFromCache(cacheKey)
740		relPos := m.module.pos
741		relPos.Filename = m.module.relBlueprintsFile
742		if data != nil && data.Pos != nil && relPos == *data.Pos {
743			for _, provider := range data.Providers {
744				m.context.setProvider(m.module, provider.Id, *provider.Value)
745			}
746			m.module.incrementalRestored = true
747			m.module.orderOnlyStrings = data.OrderOnlyStrings
748			restored = true
749			for _, str := range data.OrderOnlyStrings {
750				if !strings.HasPrefix(str, "dedup-") {
751					continue
752				}
753				orderOnlyStrings, ok := m.context.orderOnlyStringsCache[str]
754				if !ok {
755					panic(fmt.Errorf("no cached value found for order only dep: %s", str))
756				}
757				key := uniquelist.Make(orderOnlyStrings)
758				if info, loaded := m.context.orderOnlyStrings.LoadOrStore(key, &orderOnlyStringsInfo{
759					dedup:       true,
760					incremental: true,
761				}); loaded {
762					for {
763						cpy := *info
764						cpy.dedup = true
765						cpy.incremental = true
766						if m.context.orderOnlyStrings.CompareAndSwap(key, info, &cpy) {
767							break
768						}
769						if info, loaded = m.context.orderOnlyStrings.Load(key); !loaded {
770							// This shouldn't happen
771							panic("order only string was removed unexpectedly")
772						}
773					}
774				}
775			}
776		}
777	}
778
779	return restored
780}
781
782func (m *baseModuleContext) GetDirectDepWithTag(name string, tag DependencyTag) Module {
783	var deps []depInfo
784	for _, dep := range m.module.directDeps {
785		if dep.module.Name() == name {
786			if dep.tag == tag {
787				return dep.module.logicModule
788			}
789			deps = append(deps, dep)
790		}
791	}
792
793	if len(deps) != 0 {
794		panic(fmt.Errorf("Unable to find dependency %q with requested tag %#v. Found: %#v", deps[0].module, tag, deps))
795	}
796
797	return nil
798}
799
800func (m *baseModuleContext) GetDirectDepProxyWithTag(name string, tag DependencyTag) *ModuleProxy {
801	module := m.GetDirectDepWithTag(name, tag)
802	if module != nil {
803		return &ModuleProxy{module}
804	}
805
806	return nil
807}
808
809func (m *baseModuleContext) VisitDirectDeps(visit func(Module)) {
810	defer func() {
811		if r := recover(); r != nil {
812			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
813				m.module, funcName(visit), m.visitingDep.module))
814		}
815	}()
816
817	m.visitingParent = m.module
818
819	for _, dep := range m.module.directDeps {
820		m.visitingDep = dep
821		visit(dep.module.logicModule)
822	}
823
824	m.visitingParent = nil
825	m.visitingDep = depInfo{}
826}
827
828func (m *baseModuleContext) VisitDirectDepsProxy(visit func(proxy ModuleProxy)) {
829	defer func() {
830		if r := recover(); r != nil {
831			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
832				m.module, funcName(visit), m.visitingDep.module))
833		}
834	}()
835
836	m.visitingParent = m.module
837
838	for _, dep := range m.module.directDeps {
839		m.visitingDep = dep
840		visit(ModuleProxy{dep.module.logicModule})
841	}
842
843	m.visitingParent = nil
844	m.visitingDep = depInfo{}
845}
846
847func (m *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
848	defer func() {
849		if r := recover(); r != nil {
850			panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s",
851				m.module, funcName(pred), funcName(visit), m.visitingDep.module))
852		}
853	}()
854
855	m.visitingParent = m.module
856
857	for _, dep := range m.module.directDeps {
858		m.visitingDep = dep
859		if pred(dep.module.logicModule) {
860			visit(dep.module.logicModule)
861		}
862	}
863
864	m.visitingParent = nil
865	m.visitingDep = depInfo{}
866}
867
868func (m *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
869	defer func() {
870		if r := recover(); r != nil {
871			panic(newPanicErrorf(r, "VisitDepsDepthFirst(%s, %s) for dependency %s",
872				m.module, funcName(visit), m.visitingDep.module))
873		}
874	}()
875
876	m.context.walkDeps(m.module, false, nil, func(dep depInfo, parent *moduleInfo) {
877		m.visitingParent = parent
878		m.visitingDep = dep
879		visit(dep.module.logicModule)
880	})
881
882	m.visitingParent = nil
883	m.visitingDep = depInfo{}
884}
885
886func (m *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
887	visit func(Module)) {
888
889	defer func() {
890		if r := recover(); r != nil {
891			panic(newPanicErrorf(r, "VisitDepsDepthFirstIf(%s, %s, %s) for dependency %s",
892				m.module, funcName(pred), funcName(visit), m.visitingDep.module))
893		}
894	}()
895
896	m.context.walkDeps(m.module, false, nil, func(dep depInfo, parent *moduleInfo) {
897		if pred(dep.module.logicModule) {
898			m.visitingParent = parent
899			m.visitingDep = dep
900			visit(dep.module.logicModule)
901		}
902	})
903
904	m.visitingParent = nil
905	m.visitingDep = depInfo{}
906}
907
908func (m *baseModuleContext) WalkDeps(visit func(child, parent Module) bool) {
909	m.context.walkDeps(m.module, true, func(dep depInfo, parent *moduleInfo) bool {
910		m.visitingParent = parent
911		m.visitingDep = dep
912		return visit(dep.module.logicModule, parent.logicModule)
913	}, nil)
914
915	m.visitingParent = nil
916	m.visitingDep = depInfo{}
917}
918
919func (m *baseModuleContext) WalkDepsProxy(visit func(child, parent ModuleProxy) bool) {
920	m.context.walkDeps(m.module, true, func(dep depInfo, parent *moduleInfo) bool {
921		m.visitingParent = parent
922		m.visitingDep = dep
923		return visit(ModuleProxy{dep.module.logicModule}, ModuleProxy{parent.logicModule})
924	}, nil)
925
926	m.visitingParent = nil
927	m.visitingDep = depInfo{}
928}
929
930func (m *baseModuleContext) PrimaryModule() Module {
931	return m.module.group.modules.firstModule().logicModule
932}
933
934func (m *baseModuleContext) FinalModule() Module {
935	return m.module.group.modules.lastModule().logicModule
936}
937
938func (m *baseModuleContext) IsFinalModule(module Module) bool {
939	return m.module.group.modules.lastModule().logicModule == module
940}
941
942func (m *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
943	m.context.visitAllModuleVariants(m.module, visit)
944}
945
946func (m *baseModuleContext) VisitAllModuleVariantProxies(visit func(proxy ModuleProxy)) {
947	m.context.visitAllModuleVariants(m.module, visitProxyAdaptor(visit))
948}
949
950func (m *baseModuleContext) AddNinjaFileDeps(deps ...string) {
951	m.ninjaFileDeps = append(m.ninjaFileDeps, deps...)
952}
953
954func (m *baseModuleContext) ModuleFactories() map[string]ModuleFactory {
955	return m.context.ModuleTypeFactories()
956}
957
958func (m *baseModuleContext) base() *baseModuleContext {
959	return m
960}
961
962func (m *baseModuleContext) OtherModuleIsAutoGenerated(logicModule Module) bool {
963	module := m.context.moduleInfo[getWrappedModule(logicModule)]
964	if module == nil {
965		panic(fmt.Errorf("Module %s not found in baseModuleContext", logicModule.Name()))
966	}
967	return module.createdBy != nil
968}
969
970func (m *moduleContext) ModuleSubDir() string {
971	return m.module.variant.name
972}
973
974func (m *moduleContext) ModuleCacheKey() string {
975	return m.module.ModuleCacheKey()
976}
977
978func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
979	m.scope.ReparentTo(pctx)
980
981	v, err := m.scope.AddLocalVariable(name, value)
982	if err != nil {
983		panic(err)
984	}
985
986	m.actionDefs.variables = append(m.actionDefs.variables, v)
987}
988
989func (m *moduleContext) Rule(pctx PackageContext, name string,
990	params RuleParams, argNames ...string) Rule {
991
992	m.scope.ReparentTo(pctx)
993
994	r, err := m.scope.AddLocalRule(name, &params, argNames...)
995	if err != nil {
996		panic(err)
997	}
998
999	m.actionDefs.rules = append(m.actionDefs.rules, r)
1000
1001	return r
1002}
1003
1004func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
1005	m.scope.ReparentTo(pctx)
1006
1007	def, err := parseBuildParams(m.scope, &params, m.ModuleTags())
1008	if err != nil {
1009		panic(err)
1010	}
1011
1012	m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
1013	if def.OrderOnlyStrings.Len() > 0 {
1014		if info, loaded := m.context.orderOnlyStrings.LoadOrStore(def.OrderOnlyStrings, &orderOnlyStringsInfo{
1015			dedup:       false,
1016			incremental: m.module.buildActionCacheKey != nil,
1017		}); loaded {
1018			for {
1019				cpy := *info
1020				cpy.dedup = true
1021				cpy.incremental = cpy.incremental || m.module.buildActionCacheKey != nil
1022				if m.context.orderOnlyStrings.CompareAndSwap(def.OrderOnlyStrings, info, &cpy) {
1023					break
1024				}
1025				if info, loaded = m.context.orderOnlyStrings.Load(def.OrderOnlyStrings); !loaded {
1026					// This shouldn't happen
1027					panic("order only string was removed unexpectedly")
1028				}
1029			}
1030		}
1031	}
1032}
1033
1034func (m *moduleContext) GetMissingDependencies() []string {
1035	m.handledMissingDeps = true
1036	return m.module.missingDeps
1037}
1038
1039func (m *baseModuleContext) EarlyGetMissingDependencies() []string {
1040	return m.module.missingDeps
1041}
1042
1043//
1044// MutatorContext
1045//
1046
1047type mutatorContext struct {
1048	baseModuleContext
1049	mutator          *mutatorInfo
1050	reverseDeps      []reverseDep
1051	rename           []rename
1052	replace          []replace
1053	newVariations    moduleList    // new variants of existing modules
1054	newModules       []*moduleInfo // brand new modules
1055	defaultVariation *string
1056	pauseCh          chan<- pauseSpec
1057}
1058
1059type BottomUpMutatorContext interface {
1060	BaseModuleContext
1061
1062	// AddDependency adds a dependency to the given module.  It returns a slice of modules for each
1063	// dependency (some entries may be nil).  Does not affect the ordering of the current mutator
1064	// pass, but will be ordered correctly for all future mutator passes.
1065	//
1066	// This method will pause until the new dependencies have had the current mutator called on them.
1067	AddDependency(module Module, tag DependencyTag, name ...string) []Module
1068
1069	// AddReverseDependency adds a dependency from the destination to the given module.
1070	// Does not affect the ordering of the current mutator pass, but will be ordered
1071	// correctly for all future mutator passes.  All reverse dependencies for a destination module are
1072	// collected until the end of the mutator pass, sorted by name, and then appended to the destination
1073	// module's dependency list.  May only  be called by mutators that were marked with
1074	// UsesReverseDependencies during registration.
1075	AddReverseDependency(module Module, tag DependencyTag, name string)
1076
1077	// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
1078	// argument to select which variant of the dependency to use.  It returns a slice of modules for
1079	// each dependency (some entries may be nil).  A variant of the dependency must exist that matches
1080	// the all of the non-local variations of the current module, plus the variations argument.
1081	//
1082	//
1083	// This method will pause until the new dependencies have had the current mutator called on them.
1084	AddVariationDependencies([]Variation, DependencyTag, ...string) []Module
1085
1086	// AddReverseVariationDependency adds a dependency from the named module to the current
1087	// module. The given variations will be added to the current module's varations, and then the
1088	// result will be used to find the correct variation of the depending module, which must exist.
1089	//
1090	// Does not affect the ordering of the current mutator pass, but will be ordered
1091	// correctly for all future mutator passes.  All reverse dependencies for a destination module are
1092	// collected until the end of the mutator pass, sorted by name, and then appended to the destination
1093	// module's dependency list.  May only  be called by mutators that were marked with
1094	// UsesReverseDependencies during registration.
1095	AddReverseVariationDependency([]Variation, DependencyTag, string)
1096
1097	// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
1098	// variations argument to select which variant of the dependency to use.  It returns a slice of
1099	// modules for each dependency (some entries may be nil).  A variant of the dependency must
1100	// exist that matches the variations argument, but may also have other variations.
1101	// For any unspecified variation the first variant will be used.
1102	//
1103	// Unlike AddVariationDependencies, the variations of the current module are ignored - the
1104	// dependency only needs to match the supplied variations.
1105	//
1106	//
1107	// This method will pause until the new dependencies have had the current mutator called on them.
1108	AddFarVariationDependencies([]Variation, DependencyTag, ...string) []Module
1109
1110	// ReplaceDependencies finds all the variants of the module with the specified name, then
1111	// replaces all dependencies onto those variants with the current variant of this module.
1112	// Replacements don't take effect until after the mutator pass is finished.  May only
1113	// be called by mutators that were marked with UsesReplaceDependencies during registration.
1114	ReplaceDependencies(string)
1115
1116	// ReplaceDependenciesIf finds all the variants of the module with the specified name, then
1117	// replaces all dependencies onto those variants with the current variant of this module
1118	// as long as the supplied predicate returns true.
1119	// Replacements don't take effect until after the mutator pass is finished.  May only
1120	// be called by mutators that were marked with UsesReplaceDependencies during registration.
1121	ReplaceDependenciesIf(string, ReplaceDependencyPredicate)
1122
1123	// Rename all variants of a module.  The new name is not visible to calls to ModuleName,
1124	// AddDependency or OtherModuleName until after this mutator pass is complete.  May only be called
1125	// by mutators that were marked with UsesRename during registration.
1126	Rename(name string)
1127
1128	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
1129	// the specified property structs to it as if the properties were set in a blueprint file.  May only
1130	// be called by mutators that were marked with UsesCreateModule during registration.
1131	CreateModule(ModuleFactory, string, ...interface{}) Module
1132}
1133
1134// A Mutator function is called for each Module, and can modify properties on the modules.
1135// It is called after parsing all Blueprint files, but before generating any build rules,
1136// and is always called on dependencies before being called on the depending module.
1137//
1138// The Mutator function should only modify members of properties structs, and not
1139// members of the module struct itself, to ensure the modified values are copied
1140// if a second Mutator chooses to split the module a second time.
1141type BottomUpMutator func(mctx BottomUpMutatorContext)
1142
1143// DependencyTag is an interface to an arbitrary object that embeds BaseDependencyTag.  It can be
1144// used to transfer information on a dependency between the mutator that called AddDependency
1145// and the GenerateBuildActions method.
1146type DependencyTag interface {
1147	dependencyTag(DependencyTag)
1148}
1149
1150type BaseDependencyTag struct {
1151}
1152
1153func (BaseDependencyTag) dependencyTag(DependencyTag) {
1154}
1155
1156var _ DependencyTag = BaseDependencyTag{}
1157
1158func (mctx *mutatorContext) createVariationsWithTransition(variationNames []string, outgoingTransitions [][]string) []*moduleInfo {
1159	depChooser := chooseDepByIndexes(mctx.mutator.name, outgoingTransitions)
1160	modules, errs := mctx.context.createVariations(mctx.module, mctx.mutator, depChooser, variationNames)
1161	if len(errs) > 0 {
1162		mctx.errs = append(mctx.errs, errs...)
1163	}
1164
1165	if mctx.newVariations != nil {
1166		panic("module already has variations from this mutator")
1167	}
1168	mctx.newVariations = modules
1169
1170	if len(modules) != len(variationNames) {
1171		panic("oops!")
1172	}
1173
1174	return modules
1175}
1176
1177func (mctx *mutatorContext) Module() Module {
1178	return mctx.module.logicModule
1179}
1180
1181func (mctx *mutatorContext) AddDependency(module Module, tag DependencyTag, deps ...string) []Module {
1182	depInfos := make([]Module, 0, len(deps))
1183	for _, dep := range deps {
1184		modInfo := mctx.context.moduleInfo[module]
1185		depInfo, errs := mctx.context.addVariationDependency(modInfo, mctx.mutator, mctx.config, nil, tag, dep, false)
1186		if len(errs) > 0 {
1187			mctx.errs = append(mctx.errs, errs...)
1188		}
1189		if !mctx.pause(depInfo) {
1190			// Pausing not supported by this mutator, new dependencies can't be returned.
1191			depInfo = nil
1192		}
1193		depInfos = append(depInfos, maybeLogicModule(depInfo))
1194	}
1195	return depInfos
1196}
1197
1198func (m *mutatorContext) AddReverseDependency(module Module, tag DependencyTag, name string) {
1199	if !m.mutator.usesReverseDependencies {
1200		panic(fmt.Errorf("method AddReverseDependency called from mutator that was not marked UsesReverseDependencies"))
1201	}
1202
1203	if _, ok := tag.(BaseDependencyTag); ok {
1204		panic("BaseDependencyTag is not allowed to be used directly!")
1205	}
1206
1207	if module != m.module.logicModule {
1208		panic(fmt.Errorf("AddReverseDependency called with module that is not the current module"))
1209	}
1210	m.AddReverseVariationDependency(nil, tag, name)
1211}
1212
1213func (mctx *mutatorContext) AddReverseVariationDependency(variations []Variation, tag DependencyTag, name string) {
1214	if !mctx.mutator.usesReverseDependencies {
1215		panic(fmt.Errorf("method AddReverseVariationDependency called from mutator that was not marked UsesReverseDependencies"))
1216	}
1217
1218	if _, ok := tag.(BaseDependencyTag); ok {
1219		panic("BaseDependencyTag is not allowed to be used directly!")
1220	}
1221
1222	possibleDeps := mctx.context.moduleGroupFromName(name, mctx.module.namespace())
1223	if possibleDeps == nil {
1224		mctx.errs = append(mctx.errs, &BlueprintError{
1225			Err: fmt.Errorf("%q has a reverse dependency on undefined module %q",
1226				mctx.module.Name(), name),
1227			Pos: mctx.module.pos,
1228		})
1229		return
1230	}
1231
1232	found, newVariant, errs := mctx.context.findVariant(mctx.module, mctx.config, possibleDeps, variations, false, true)
1233	if errs != nil {
1234		mctx.errs = append(mctx.errs, errs...)
1235		return
1236	}
1237
1238	if found == nil {
1239		if mctx.context.allowMissingDependencies {
1240			// Allow missing variants.
1241			mctx.errs = append(mctx.errs, mctx.context.discoveredMissingDependencies(mctx.module, name, newVariant)...)
1242		} else {
1243			mctx.errs = append(mctx.errs, &BlueprintError{
1244				Err: fmt.Errorf("reverse dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
1245					name, mctx.module.Name(),
1246					mctx.context.prettyPrintVariant(newVariant),
1247					mctx.context.prettyPrintGroupVariants(possibleDeps)),
1248				Pos: mctx.module.pos,
1249			})
1250		}
1251		return
1252	}
1253
1254	mctx.reverseDeps = append(mctx.reverseDeps, reverseDep{
1255		found,
1256		depInfo{mctx.module, tag},
1257	})
1258}
1259
1260func (mctx *mutatorContext) AddVariationDependencies(variations []Variation, tag DependencyTag,
1261	deps ...string) []Module {
1262
1263	depInfos := make([]Module, 0, len(deps))
1264	for _, dep := range deps {
1265		depInfo, errs := mctx.context.addVariationDependency(mctx.module, mctx.mutator, mctx.config, variations, tag, dep, false)
1266		if len(errs) > 0 {
1267			mctx.errs = append(mctx.errs, errs...)
1268		}
1269		if !mctx.pause(depInfo) {
1270			// Pausing not supported by this mutator, new dependencies can't be returned.
1271			depInfo = nil
1272		}
1273		depInfos = append(depInfos, maybeLogicModule(depInfo))
1274	}
1275	return depInfos
1276}
1277
1278func (mctx *mutatorContext) AddFarVariationDependencies(variations []Variation, tag DependencyTag,
1279	deps ...string) []Module {
1280
1281	depInfos := make([]Module, 0, len(deps))
1282	for _, dep := range deps {
1283		depInfo, errs := mctx.context.addVariationDependency(mctx.module, mctx.mutator, mctx.config, variations, tag, dep, true)
1284		if len(errs) > 0 {
1285			mctx.errs = append(mctx.errs, errs...)
1286		}
1287		if !mctx.pause(depInfo) {
1288			// Pausing not supported by this mutator, new dependencies can't be returned.
1289			depInfo = nil
1290		}
1291		depInfos = append(depInfos, maybeLogicModule(depInfo))
1292	}
1293	return depInfos
1294}
1295
1296func (mctx *mutatorContext) ReplaceDependencies(name string) {
1297	mctx.ReplaceDependenciesIf(name, nil)
1298}
1299
1300type ReplaceDependencyPredicate func(from Module, tag DependencyTag, to Module) bool
1301
1302func (mctx *mutatorContext) ReplaceDependenciesIf(name string, predicate ReplaceDependencyPredicate) {
1303	if !mctx.mutator.usesReplaceDependencies {
1304		panic(fmt.Errorf("method ReplaceDependenciesIf called from mutator that was not marked UsesReplaceDependencies"))
1305	}
1306
1307	targets := mctx.context.moduleVariantsThatDependOn(name, mctx.module)
1308
1309	if len(targets) == 0 {
1310		panic(fmt.Errorf("ReplaceDependenciesIf could not find variant of %s that depends on %s variant %s",
1311			name,
1312			mctx.module.group.name,
1313			mctx.context.prettyPrintVariant(mctx.module.variant.variations),
1314		))
1315	}
1316
1317	for _, target := range targets {
1318		mctx.replace = append(mctx.replace, replace{target, mctx.module, predicate})
1319	}
1320}
1321
1322func (mctx *mutatorContext) Rename(name string) {
1323	if !mctx.mutator.usesRename {
1324		panic(fmt.Errorf("method Rename called from mutator that was not marked UsesRename"))
1325	}
1326	mctx.rename = append(mctx.rename, rename{mctx.module.group, name})
1327}
1328
1329func (mctx *mutatorContext) CreateModule(factory ModuleFactory, typeName string, props ...interface{}) Module {
1330	if !mctx.mutator.usesCreateModule {
1331		panic(fmt.Errorf("method CreateModule called from mutator that was not marked UsesCreateModule"))
1332	}
1333
1334	module := newModule(factory)
1335
1336	module.relBlueprintsFile = mctx.module.relBlueprintsFile
1337	module.pos = mctx.module.pos
1338	module.propertyPos = mctx.module.propertyPos
1339	module.createdBy = mctx.module
1340	module.typeName = typeName
1341
1342	for _, p := range props {
1343		err := proptools.AppendMatchingProperties(module.properties, p, nil)
1344		if err != nil {
1345			panic(err)
1346		}
1347	}
1348
1349	mctx.newModules = append(mctx.newModules, module)
1350
1351	return module.logicModule
1352}
1353
1354// pause waits until the given dependency has been visited by the mutator's parallelVisit call.
1355// It returns true if the pause was supported, false if the pause was not supported and did not
1356// occur, which will happen when the mutator is not parallelizable.  If the dependency is nil
1357// it returns true if pausing is supported or false if it is not.
1358func (mctx *mutatorContext) pause(dep *moduleInfo) bool {
1359	if mctx.pauseCh != nil {
1360		if dep != nil {
1361			unpause := make(unpause)
1362			mctx.pauseCh <- pauseSpec{
1363				paused:  mctx.module,
1364				until:   dep,
1365				unpause: unpause,
1366			}
1367			<-unpause
1368		}
1369		return true
1370	}
1371	return false
1372}
1373
1374// SimpleName is an embeddable object to implement the ModuleContext.Name method using a property
1375// called "name".  Modules that embed it must also add SimpleName.Properties to their property
1376// structure list.
1377type SimpleName struct {
1378	Properties struct {
1379		Name string
1380	}
1381}
1382
1383func (s *SimpleName) Name() string {
1384	return s.Properties.Name
1385}
1386
1387func (s *SimpleName) String() string {
1388	return s.Name()
1389}
1390
1391// Load Hooks
1392
1393type LoadHookContext interface {
1394	EarlyModuleContext
1395
1396	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
1397	// the specified property structs to it as if the properties were set in a blueprint file.
1398	CreateModule(ModuleFactory, string, ...interface{}) Module
1399
1400	// CreateModuleInDirectory creates a new module in the specified directory by calling the
1401	// factory method for the specified moduleType, and applies the specified property structs
1402	// to it as if the properties were set in a blueprint file.
1403	CreateModuleInDirectory(ModuleFactory, string, string, ...interface{}) Module
1404
1405	// RegisterScopedModuleType creates a new module type that is scoped to the current Blueprints
1406	// file.
1407	RegisterScopedModuleType(name string, factory ModuleFactory)
1408}
1409
1410func (l *loadHookContext) createModule(factory ModuleFactory, typeName, moduleDir string, props ...interface{}) Module {
1411	module := newModule(factory)
1412
1413	module.relBlueprintsFile = moduleDir
1414	module.pos = l.module.pos
1415	module.propertyPos = l.module.propertyPos
1416	module.createdBy = l.module
1417	module.typeName = typeName
1418
1419	for _, p := range props {
1420		err := proptools.AppendMatchingProperties(module.properties, p, nil)
1421		if err != nil {
1422			panic(err)
1423		}
1424	}
1425
1426	l.newModules = append(l.newModules, module)
1427
1428	return module.logicModule
1429}
1430
1431func (l *loadHookContext) CreateModule(factory ModuleFactory, typeName string, props ...interface{}) Module {
1432	return l.createModule(factory, typeName, l.module.relBlueprintsFile, props...)
1433}
1434
1435func (l *loadHookContext) CreateModuleInDirectory(factory ModuleFactory, typeName, moduleDir string, props ...interface{}) Module {
1436	if moduleDir != filepath.Clean(moduleDir) {
1437		panic(fmt.Errorf("Cannot create a module in %s", moduleDir))
1438	}
1439
1440	filePath := filepath.Join(moduleDir, "Android.bp")
1441	return l.createModule(factory, typeName, filePath, props...)
1442}
1443
1444func (l *loadHookContext) RegisterScopedModuleType(name string, factory ModuleFactory) {
1445	if _, exists := l.context.moduleFactories[name]; exists {
1446		panic(fmt.Errorf("A global module type named %q already exists", name))
1447	}
1448
1449	if _, exists := (*l.scopedModuleFactories)[name]; exists {
1450		panic(fmt.Errorf("A module type named %q already exists in this scope", name))
1451	}
1452
1453	if *l.scopedModuleFactories == nil {
1454		*l.scopedModuleFactories = make(map[string]ModuleFactory)
1455	}
1456
1457	(*l.scopedModuleFactories)[name] = factory
1458}
1459
1460type loadHookContext struct {
1461	baseModuleContext
1462	newModules            []*moduleInfo
1463	scopedModuleFactories *map[string]ModuleFactory
1464}
1465
1466type LoadHook func(ctx LoadHookContext)
1467
1468// LoadHookWithPriority is a wrapper around LoadHook and allows hooks to be sorted by priority.
1469// hooks with higher value of `priority` run last.
1470// hooks with equal value of `priority` run in the order they were registered.
1471type LoadHookWithPriority struct {
1472	priority int
1473	loadHook LoadHook
1474}
1475
1476// Load hooks need to be added by module factories, which don't have any parameter to get to the
1477// Context, and only produce a Module interface with no base implementation, so the load hooks
1478// must be stored in a global map.  The key is a pointer allocated by the module factory, so there
1479// is no chance of collisions even if tests are running in parallel with multiple contexts.  The
1480// contents should be short-lived, they are added during a module factory and removed immediately
1481// after the module factory returns.
1482var pendingHooks sync.Map
1483
1484func AddLoadHook(module Module, hook LoadHook) {
1485	// default priority is 0
1486	AddLoadHookWithPriority(module, hook, 0)
1487}
1488
1489// AddLoadhHookWithPriority adds a load hook with a specified priority.
1490// Hooks with higher priority run last.
1491// Hooks with equal priority run in the order they were registered.
1492func AddLoadHookWithPriority(module Module, hook LoadHook, priority int) {
1493	// Only one goroutine can be processing a given module, so no additional locking is required
1494	// for the slice stored in the sync.Map.
1495	v, exists := pendingHooks.Load(module)
1496	if !exists {
1497		v, _ = pendingHooks.LoadOrStore(module, new([]LoadHookWithPriority))
1498	}
1499	hooks := v.(*[]LoadHookWithPriority)
1500	*hooks = append(*hooks, LoadHookWithPriority{priority, hook})
1501}
1502
1503func runAndRemoveLoadHooks(ctx *Context, config interface{}, module *moduleInfo,
1504	scopedModuleFactories *map[string]ModuleFactory) (newModules []*moduleInfo, deps []string, errs []error) {
1505
1506	if v, exists := pendingHooks.Load(module.logicModule); exists {
1507		hooks := v.(*[]LoadHookWithPriority)
1508		// Sort the hooks by priority.
1509		// Use SliceStable so that hooks with equal priority run in the order they were registered.
1510		sort.SliceStable(*hooks, func(i, j int) bool { return (*hooks)[i].priority < (*hooks)[j].priority })
1511
1512		for _, hook := range *hooks {
1513			mctx := &loadHookContext{
1514				baseModuleContext: baseModuleContext{
1515					context: ctx,
1516					config:  config,
1517					module:  module,
1518				},
1519				scopedModuleFactories: scopedModuleFactories,
1520			}
1521			hook.loadHook(mctx)
1522			newModules = append(newModules, mctx.newModules...)
1523			deps = append(deps, mctx.ninjaFileDeps...)
1524			errs = append(errs, mctx.errs...)
1525		}
1526		pendingHooks.Delete(module.logicModule)
1527
1528		return newModules, deps, errs
1529	}
1530
1531	return nil, nil, nil
1532}
1533
1534// Check the syntax of a generated blueprint file.
1535//
1536// This is intended to perform a quick syntactic check for generated blueprint
1537// code, where syntactically correct means:
1538// * No variable definitions.
1539// * Valid module types.
1540// * Valid property names.
1541// * Valid values for the property type.
1542//
1543// It does not perform any semantic checking of properties, existence of referenced
1544// files, or dependencies.
1545//
1546// At a low level it:
1547// * Parses the contents.
1548// * Invokes relevant factory to create Module instances.
1549// * Unpacks the properties into the Module.
1550// * Does not invoke load hooks or any mutators.
1551//
1552// The filename is only used for reporting errors.
1553func CheckBlueprintSyntax(moduleFactories map[string]ModuleFactory, filename string, contents string) []error {
1554	file, errs := parser.Parse(filename, strings.NewReader(contents))
1555	if len(errs) != 0 {
1556		return errs
1557	}
1558
1559	for _, def := range file.Defs {
1560		switch def := def.(type) {
1561		case *parser.Module:
1562			_, moduleErrs := processModuleDef(def, filename, moduleFactories, nil, false)
1563			errs = append(errs, moduleErrs...)
1564
1565		default:
1566			panic(fmt.Errorf("unknown definition type: %T", def))
1567		}
1568	}
1569
1570	return errs
1571}
1572
1573func maybeLogicModule(module *moduleInfo) Module {
1574	if module != nil {
1575		return module.logicModule
1576	} else {
1577		return nil
1578	}
1579}
1580