xref: /aosp_15_r20/build/soong/android/base_module_context.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2015 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"regexp"
20*333d2b36SAndroid Build Coastguard Worker	"slices"
21*333d2b36SAndroid Build Coastguard Worker	"strings"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
28*333d2b36SAndroid Build Coastguard Worker// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
29*333d2b36SAndroid Build Coastguard Worker// instead of a blueprint.Module, plus some extra methods that return Android-specific information
30*333d2b36SAndroid Build Coastguard Worker// about the current module.
31*333d2b36SAndroid Build Coastguard Workertype BaseModuleContext interface {
32*333d2b36SAndroid Build Coastguard Worker	ArchModuleContext
33*333d2b36SAndroid Build Coastguard Worker	EarlyModuleContext
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Worker	blueprintBaseModuleContext() blueprint.BaseModuleContext
36*333d2b36SAndroid Build Coastguard Worker
37*333d2b36SAndroid Build Coastguard Worker	EqualModules(m1, m2 Module) bool
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	// OtherModuleName returns the name of another Module.  See BaseModuleContext.ModuleName for more information.
40*333d2b36SAndroid Build Coastguard Worker	// It is intended for use inside the visit functions of Visit* and WalkDeps.
41*333d2b36SAndroid Build Coastguard Worker	OtherModuleName(m blueprint.Module) string
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Worker	// OtherModuleDir returns the directory of another Module.  See BaseModuleContext.ModuleDir for more information.
44*333d2b36SAndroid Build Coastguard Worker	// It is intended for use inside the visit functions of Visit* and WalkDeps.
45*333d2b36SAndroid Build Coastguard Worker	OtherModuleDir(m blueprint.Module) string
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker	// OtherModuleErrorf reports an error on another Module.  See BaseModuleContext.ModuleErrorf for more information.
48*333d2b36SAndroid Build Coastguard Worker	// It is intended for use inside the visit functions of Visit* and WalkDeps.
49*333d2b36SAndroid Build Coastguard Worker	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker	// OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
52*333d2b36SAndroid Build Coastguard Worker	// on the module.  When called inside a Visit* method with current module being visited, and there are multiple
53*333d2b36SAndroid Build Coastguard Worker	// dependencies on the module being visited, it returns the dependency tag used for the current dependency.
54*333d2b36SAndroid Build Coastguard Worker	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	// OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
57*333d2b36SAndroid Build Coastguard Worker	// passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
58*333d2b36SAndroid Build Coastguard Worker	OtherModuleExists(name string) bool
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker	// OtherModuleDependencyVariantExists returns true if a module with the
61*333d2b36SAndroid Build Coastguard Worker	// specified name and variant exists. The variant must match the given
62*333d2b36SAndroid Build Coastguard Worker	// variations. It must also match all the non-local variations of the current
63*333d2b36SAndroid Build Coastguard Worker	// module. In other words, it checks for the module that AddVariationDependencies
64*333d2b36SAndroid Build Coastguard Worker	// would add a dependency on with the same arguments.
65*333d2b36SAndroid Build Coastguard Worker	OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker	// OtherModuleFarDependencyVariantExists returns true if a module with the
68*333d2b36SAndroid Build Coastguard Worker	// specified name and variant exists. The variant must match the given
69*333d2b36SAndroid Build Coastguard Worker	// variations, but not the non-local variations of the current module. In
70*333d2b36SAndroid Build Coastguard Worker	// other words, it checks for the module that AddFarVariationDependencies
71*333d2b36SAndroid Build Coastguard Worker	// would add a dependency on with the same arguments.
72*333d2b36SAndroid Build Coastguard Worker	OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker	// OtherModuleReverseDependencyVariantExists returns true if a module with the
75*333d2b36SAndroid Build Coastguard Worker	// specified name exists with the same variations as the current module. In
76*333d2b36SAndroid Build Coastguard Worker	// other words, it checks for the module that AddReverseDependency would add a
77*333d2b36SAndroid Build Coastguard Worker	// dependency on with the same argument.
78*333d2b36SAndroid Build Coastguard Worker	OtherModuleReverseDependencyVariantExists(name string) bool
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	// OtherModuleType returns the type of another Module.  See BaseModuleContext.ModuleType for more information.
81*333d2b36SAndroid Build Coastguard Worker	// It is intended for use inside the visit functions of Visit* and WalkDeps.
82*333d2b36SAndroid Build Coastguard Worker	OtherModuleType(m blueprint.Module) string
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker	// otherModuleProvider returns the value for a provider for the given module.  If the value is
85*333d2b36SAndroid Build Coastguard Worker	// not set it returns nil and false.  The value returned may be a deep copy of the value originally
86*333d2b36SAndroid Build Coastguard Worker	// passed to SetProvider.
87*333d2b36SAndroid Build Coastguard Worker	//
88*333d2b36SAndroid Build Coastguard Worker	// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
89*333d2b36SAndroid Build Coastguard Worker	otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Worker	// OtherModuleIsAutoGenerated returns true if the module is auto generated by another module
92*333d2b36SAndroid Build Coastguard Worker	// instead of being defined in Android.bp file.
93*333d2b36SAndroid Build Coastguard Worker	OtherModuleIsAutoGenerated(m blueprint.Module) bool
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Worker	// Provider returns the value for a provider for the current module.  If the value is
96*333d2b36SAndroid Build Coastguard Worker	// not set it returns nil and false.  It panics if called before the appropriate
97*333d2b36SAndroid Build Coastguard Worker	// mutator or GenerateBuildActions pass for the provider.  The value returned may be a deep
98*333d2b36SAndroid Build Coastguard Worker	// copy of the value originally passed to SetProvider.
99*333d2b36SAndroid Build Coastguard Worker	//
100*333d2b36SAndroid Build Coastguard Worker	// This method shouldn't be used directly, prefer the type-safe android.ModuleProvider instead.
101*333d2b36SAndroid Build Coastguard Worker	provider(provider blueprint.AnyProviderKey) (any, bool)
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	// setProvider sets the value for a provider for the current module.  It panics if not called
104*333d2b36SAndroid Build Coastguard Worker	// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
105*333d2b36SAndroid Build Coastguard Worker	// is not of the appropriate type, or if the value has already been set.  The value should not
106*333d2b36SAndroid Build Coastguard Worker	// be modified after being passed to SetProvider.
107*333d2b36SAndroid Build Coastguard Worker	//
108*333d2b36SAndroid Build Coastguard Worker	// This method shouldn't be used directly, prefer the type-safe android.SetProvider instead.
109*333d2b36SAndroid Build Coastguard Worker	setProvider(provider blueprint.AnyProviderKey, value any)
110*333d2b36SAndroid Build Coastguard Worker
111*333d2b36SAndroid Build Coastguard Worker	GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
112*333d2b36SAndroid Build Coastguard Worker
113*333d2b36SAndroid Build Coastguard Worker	// GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
114*333d2b36SAndroid Build Coastguard Worker	// none exists.  It panics if the dependency does not have the specified tag.  It skips any
115*333d2b36SAndroid Build Coastguard Worker	// dependencies that are not an android.Module.
116*333d2b36SAndroid Build Coastguard Worker	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker	// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
119*333d2b36SAndroid Build Coastguard Worker	// name, or nil if none exists.  If there are multiple dependencies on the same module it returns
120*333d2b36SAndroid Build Coastguard Worker	// the first DependencyTag.
121*333d2b36SAndroid Build Coastguard Worker	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Worker	// VisitDirectDeps calls visit for each direct dependency.  If there are multiple
124*333d2b36SAndroid Build Coastguard Worker	// direct dependencies on the same module visit will be called multiple times on that module
125*333d2b36SAndroid Build Coastguard Worker	// and OtherModuleDependencyTag will return a different tag for each.  It raises an error if any of the
126*333d2b36SAndroid Build Coastguard Worker	// dependencies are disabled.
127*333d2b36SAndroid Build Coastguard Worker	//
128*333d2b36SAndroid Build Coastguard Worker	// The Module passed to the visit function should not be retained outside of the visit
129*333d2b36SAndroid Build Coastguard Worker	// function, it may be invalidated by future mutators.
130*333d2b36SAndroid Build Coastguard Worker	VisitDirectDeps(visit func(Module))
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Worker	// VisitDirectDepsProxy calls visit for each direct dependency.  If there are multiple
133*333d2b36SAndroid Build Coastguard Worker	// direct dependencies on the same module visit will be called multiple times on that module
134*333d2b36SAndroid Build Coastguard Worker	// and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
135*333d2b36SAndroid Build Coastguard Worker	// dependencies are disabled.
136*333d2b36SAndroid Build Coastguard Worker	//
137*333d2b36SAndroid Build Coastguard Worker	// The ModuleProxy passed to the visit function should not be retained outside of the visit
138*333d2b36SAndroid Build Coastguard Worker	// function, it may be invalidated by future mutators.
139*333d2b36SAndroid Build Coastguard Worker	VisitDirectDepsProxy(visit func(proxy ModuleProxy))
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker	// VisitDirectDepsProxyAllowDisabled calls visit for each direct dependency.  If there are
142*333d2b36SAndroid Build Coastguard Worker	// multiple direct dependencies on the same module visit will be called multiple times on
143*333d2b36SAndroid Build Coastguard Worker	// that module and OtherModuleDependencyTag will return a different tag for each.
144*333d2b36SAndroid Build Coastguard Worker	//
145*333d2b36SAndroid Build Coastguard Worker	// The ModuleProxy passed to the visit function should not be retained outside of the visit function, it may be
146*333d2b36SAndroid Build Coastguard Worker	// invalidated by future mutators.
147*333d2b36SAndroid Build Coastguard Worker	VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy))
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
150*333d2b36SAndroid Build Coastguard Worker
151*333d2b36SAndroid Build Coastguard Worker	VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(proxy ModuleProxy))
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	// VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit.  If there are
154*333d2b36SAndroid Build Coastguard Worker	// multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
155*333d2b36SAndroid Build Coastguard Worker	// OtherModuleDependencyTag will return a different tag for each.  It skips any
156*333d2b36SAndroid Build Coastguard Worker	// dependencies that are not an android.Module.
157*333d2b36SAndroid Build Coastguard Worker	//
158*333d2b36SAndroid Build Coastguard Worker	// The Module passed to the visit function should not be retained outside of the visit function, it may be
159*333d2b36SAndroid Build Coastguard Worker	// invalidated by future mutators.
160*333d2b36SAndroid Build Coastguard Worker	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
161*333d2b36SAndroid Build Coastguard Worker	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
162*333d2b36SAndroid Build Coastguard Worker	VisitDepsDepthFirst(visit func(Module))
163*333d2b36SAndroid Build Coastguard Worker	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
164*333d2b36SAndroid Build Coastguard Worker	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Worker	// WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order.  visit may
167*333d2b36SAndroid Build Coastguard Worker	// be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
168*333d2b36SAndroid Build Coastguard Worker	// child and parent with different tags.  OtherModuleDependencyTag will return the tag for the currently visited
169*333d2b36SAndroid Build Coastguard Worker	// (child, parent) pair.  If visit returns false WalkDeps will not continue recursing down to child.  It skips
170*333d2b36SAndroid Build Coastguard Worker	// any dependencies that are not an android.Module.
171*333d2b36SAndroid Build Coastguard Worker	//
172*333d2b36SAndroid Build Coastguard Worker	// The Modules passed to the visit function should not be retained outside of the visit function, they may be
173*333d2b36SAndroid Build Coastguard Worker	// invalidated by future mutators.
174*333d2b36SAndroid Build Coastguard Worker	WalkDeps(visit func(child, parent Module) bool)
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker	// WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order.  visit may
177*333d2b36SAndroid Build Coastguard Worker	// be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
178*333d2b36SAndroid Build Coastguard Worker	// child and parent with different tags.  OtherModuleDependencyTag will return the tag for the currently visited
179*333d2b36SAndroid Build Coastguard Worker	// (child, parent) pair.  If visit returns false WalkDeps will not continue recursing down to child.  It skips
180*333d2b36SAndroid Build Coastguard Worker	// any dependencies that are not an android.Module.
181*333d2b36SAndroid Build Coastguard Worker	//
182*333d2b36SAndroid Build Coastguard Worker	// The Modules passed to the visit function should not be retained outside of the visit function, they may be
183*333d2b36SAndroid Build Coastguard Worker	// invalidated by future mutators.
184*333d2b36SAndroid Build Coastguard Worker	WalkDepsProxy(visit func(child, parent ModuleProxy) bool)
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Worker	// GetWalkPath is supposed to be called in visit function passed in WalkDeps()
187*333d2b36SAndroid Build Coastguard Worker	// and returns a top-down dependency path from a start module to current child module.
188*333d2b36SAndroid Build Coastguard Worker	GetWalkPath() []Module
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Worker	// PrimaryModule returns the first variant of the current module.  Variants of a module are always visited in
191*333d2b36SAndroid Build Coastguard Worker	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
192*333d2b36SAndroid Build Coastguard Worker	// Module returned by PrimaryModule without data races.  This can be used to perform singleton actions that are
193*333d2b36SAndroid Build Coastguard Worker	// only done once for all variants of a module.
194*333d2b36SAndroid Build Coastguard Worker	PrimaryModule() Module
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker	// FinalModule returns the last variant of the current module.  Variants of a module are always visited in
197*333d2b36SAndroid Build Coastguard Worker	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
198*333d2b36SAndroid Build Coastguard Worker	// variants using VisitAllModuleVariants if the current module == FinalModule().  This can be used to perform
199*333d2b36SAndroid Build Coastguard Worker	// singleton actions that are only done once for all variants of a module.
200*333d2b36SAndroid Build Coastguard Worker	FinalModule() Module
201*333d2b36SAndroid Build Coastguard Worker
202*333d2b36SAndroid Build Coastguard Worker	// IsFinalModule returns if the current module is the last variant.  Variants of a module are always visited in
203*333d2b36SAndroid Build Coastguard Worker	// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
204*333d2b36SAndroid Build Coastguard Worker	// variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform
205*333d2b36SAndroid Build Coastguard Worker	// singleton actions that are only done once for all variants of a module.
206*333d2b36SAndroid Build Coastguard Worker	IsFinalModule(module Module) bool
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Worker	// VisitAllModuleVariants calls visit for each variant of the current module.  Variants of a module are always
209*333d2b36SAndroid Build Coastguard Worker	// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
210*333d2b36SAndroid Build Coastguard Worker	// from all variants if the current module is the last one. Otherwise, care must be taken to not access any
211*333d2b36SAndroid Build Coastguard Worker	// data modified by the current mutator.
212*333d2b36SAndroid Build Coastguard Worker	VisitAllModuleVariants(visit func(Module))
213*333d2b36SAndroid Build Coastguard Worker
214*333d2b36SAndroid Build Coastguard Worker	// VisitAllModuleVariantProxies calls visit for each variant of the current module.  Variants of a module are always
215*333d2b36SAndroid Build Coastguard Worker	// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
216*333d2b36SAndroid Build Coastguard Worker	// from all variants if the current module is the last one. Otherwise, care must be taken to not access any
217*333d2b36SAndroid Build Coastguard Worker	// data modified by the current mutator.
218*333d2b36SAndroid Build Coastguard Worker	VisitAllModuleVariantProxies(visit func(proxy ModuleProxy))
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Worker	// GetTagPath is supposed to be called in visit function passed in WalkDeps()
221*333d2b36SAndroid Build Coastguard Worker	// and returns a top-down dependency tags path from a start module to current child module.
222*333d2b36SAndroid Build Coastguard Worker	// It has one less entry than GetWalkPath() as it contains the dependency tags that
223*333d2b36SAndroid Build Coastguard Worker	// exist between each adjacent pair of modules in the GetWalkPath().
224*333d2b36SAndroid Build Coastguard Worker	// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
225*333d2b36SAndroid Build Coastguard Worker	GetTagPath() []blueprint.DependencyTag
226*333d2b36SAndroid Build Coastguard Worker
227*333d2b36SAndroid Build Coastguard Worker	// GetPathString is supposed to be called in visit function passed in WalkDeps()
228*333d2b36SAndroid Build Coastguard Worker	// and returns a multi-line string showing the modules and dependency tags
229*333d2b36SAndroid Build Coastguard Worker	// among them along the top-down dependency path from a start module to current child module.
230*333d2b36SAndroid Build Coastguard Worker	// skipFirst when set to true, the output doesn't include the start module,
231*333d2b36SAndroid Build Coastguard Worker	// which is already printed when this function is used along with ModuleErrorf().
232*333d2b36SAndroid Build Coastguard Worker	GetPathString(skipFirst bool) string
233*333d2b36SAndroid Build Coastguard Worker
234*333d2b36SAndroid Build Coastguard Worker	AddMissingDependencies(missingDeps []string)
235*333d2b36SAndroid Build Coastguard Worker
236*333d2b36SAndroid Build Coastguard Worker	// getMissingDependencies returns the list of missing dependencies.
237*333d2b36SAndroid Build Coastguard Worker	// Calling this function prevents adding new dependencies.
238*333d2b36SAndroid Build Coastguard Worker	getMissingDependencies() []string
239*333d2b36SAndroid Build Coastguard Worker
240*333d2b36SAndroid Build Coastguard Worker	// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
241*333d2b36SAndroid Build Coastguard Worker	// can be used to evaluate the final value of Configurable properties.
242*333d2b36SAndroid Build Coastguard Worker	EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
243*333d2b36SAndroid Build Coastguard Worker}
244*333d2b36SAndroid Build Coastguard Worker
245*333d2b36SAndroid Build Coastguard Workertype baseModuleContext struct {
246*333d2b36SAndroid Build Coastguard Worker	bp blueprint.BaseModuleContext
247*333d2b36SAndroid Build Coastguard Worker	earlyModuleContext
248*333d2b36SAndroid Build Coastguard Worker	archModuleContext
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Worker	walkPath []Module
251*333d2b36SAndroid Build Coastguard Worker	tagPath  []blueprint.DependencyTag
252*333d2b36SAndroid Build Coastguard Worker
253*333d2b36SAndroid Build Coastguard Worker	strictVisitDeps bool // If true, enforce that all dependencies are enabled
254*333d2b36SAndroid Build Coastguard Worker
255*333d2b36SAndroid Build Coastguard Worker}
256*333d2b36SAndroid Build Coastguard Worker
257*333d2b36SAndroid Build Coastguard Workerfunc getWrappedModule(module blueprint.Module) blueprint.Module {
258*333d2b36SAndroid Build Coastguard Worker	if mp, isProxy := module.(ModuleProxy); isProxy {
259*333d2b36SAndroid Build Coastguard Worker		return mp.module
260*333d2b36SAndroid Build Coastguard Worker	}
261*333d2b36SAndroid Build Coastguard Worker	return module
262*333d2b36SAndroid Build Coastguard Worker}
263*333d2b36SAndroid Build Coastguard Worker
264*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) EqualModules(m1, m2 Module) bool {
265*333d2b36SAndroid Build Coastguard Worker	return b.bp.EqualModules(getWrappedModule(m1), getWrappedModule(m2))
266*333d2b36SAndroid Build Coastguard Worker}
267*333d2b36SAndroid Build Coastguard Worker
268*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
269*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleName(getWrappedModule(m))
270*333d2b36SAndroid Build Coastguard Worker}
271*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string {
272*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleDir(getWrappedModule(m))
273*333d2b36SAndroid Build Coastguard Worker}
274*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
275*333d2b36SAndroid Build Coastguard Worker	b.bp.OtherModuleErrorf(getWrappedModule(m), fmt, args...)
276*333d2b36SAndroid Build Coastguard Worker}
277*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
278*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleDependencyTag(getWrappedModule(m))
279*333d2b36SAndroid Build Coastguard Worker}
280*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
281*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
282*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleDependencyVariantExists(variations, name)
283*333d2b36SAndroid Build Coastguard Worker}
284*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool {
285*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleFarDependencyVariantExists(variations, name)
286*333d2b36SAndroid Build Coastguard Worker}
287*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
288*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleReverseDependencyVariantExists(name)
289*333d2b36SAndroid Build Coastguard Worker}
290*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
291*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleType(getWrappedModule(m))
292*333d2b36SAndroid Build Coastguard Worker}
293*333d2b36SAndroid Build Coastguard Worker
294*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
295*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleProvider(m, provider)
296*333d2b36SAndroid Build Coastguard Worker}
297*333d2b36SAndroid Build Coastguard Worker
298*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool {
299*333d2b36SAndroid Build Coastguard Worker	return b.bp.OtherModuleIsAutoGenerated(m)
300*333d2b36SAndroid Build Coastguard Worker}
301*333d2b36SAndroid Build Coastguard Worker
302*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) provider(provider blueprint.AnyProviderKey) (any, bool) {
303*333d2b36SAndroid Build Coastguard Worker	return b.bp.Provider(provider)
304*333d2b36SAndroid Build Coastguard Worker}
305*333d2b36SAndroid Build Coastguard Worker
306*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value any) {
307*333d2b36SAndroid Build Coastguard Worker	b.bp.SetProvider(provider, value)
308*333d2b36SAndroid Build Coastguard Worker}
309*333d2b36SAndroid Build Coastguard Worker
310*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module {
311*333d2b36SAndroid Build Coastguard Worker	if module := b.bp.GetDirectDepWithTag(name, tag); module != nil {
312*333d2b36SAndroid Build Coastguard Worker		return module.(Module)
313*333d2b36SAndroid Build Coastguard Worker	}
314*333d2b36SAndroid Build Coastguard Worker	return nil
315*333d2b36SAndroid Build Coastguard Worker}
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
318*333d2b36SAndroid Build Coastguard Worker	return b.bp
319*333d2b36SAndroid Build Coastguard Worker}
320*333d2b36SAndroid Build Coastguard Worker
321*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) AddMissingDependencies(deps []string) {
322*333d2b36SAndroid Build Coastguard Worker	if deps != nil {
323*333d2b36SAndroid Build Coastguard Worker		missingDeps := &b.Module().base().commonProperties.MissingDeps
324*333d2b36SAndroid Build Coastguard Worker		*missingDeps = append(*missingDeps, deps...)
325*333d2b36SAndroid Build Coastguard Worker		*missingDeps = FirstUniqueStrings(*missingDeps)
326*333d2b36SAndroid Build Coastguard Worker	}
327*333d2b36SAndroid Build Coastguard Worker}
328*333d2b36SAndroid Build Coastguard Worker
329*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) checkedMissingDeps() bool {
330*333d2b36SAndroid Build Coastguard Worker	return b.Module().base().commonProperties.CheckedMissingDeps
331*333d2b36SAndroid Build Coastguard Worker}
332*333d2b36SAndroid Build Coastguard Worker
333*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) getMissingDependencies() []string {
334*333d2b36SAndroid Build Coastguard Worker	checked := &b.Module().base().commonProperties.CheckedMissingDeps
335*333d2b36SAndroid Build Coastguard Worker	*checked = true
336*333d2b36SAndroid Build Coastguard Worker	var missingDeps []string
337*333d2b36SAndroid Build Coastguard Worker	missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...)
338*333d2b36SAndroid Build Coastguard Worker	missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...)
339*333d2b36SAndroid Build Coastguard Worker	missingDeps = FirstUniqueStrings(missingDeps)
340*333d2b36SAndroid Build Coastguard Worker	return missingDeps
341*333d2b36SAndroid Build Coastguard Worker}
342*333d2b36SAndroid Build Coastguard Worker
343*333d2b36SAndroid Build Coastguard Workertype AllowDisabledModuleDependency interface {
344*333d2b36SAndroid Build Coastguard Worker	blueprint.DependencyTag
345*333d2b36SAndroid Build Coastguard Worker	AllowDisabledModuleDependency(target Module) bool
346*333d2b36SAndroid Build Coastguard Worker	AllowDisabledModuleDependencyProxy(ctx OtherModuleProviderContext, target ModuleProxy) bool
347*333d2b36SAndroid Build Coastguard Worker}
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Workertype AlwaysAllowDisabledModuleDependencyTag struct{}
350*333d2b36SAndroid Build Coastguard Worker
351*333d2b36SAndroid Build Coastguard Workerfunc (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Module) bool {
352*333d2b36SAndroid Build Coastguard Worker	return true
353*333d2b36SAndroid Build Coastguard Worker}
354*333d2b36SAndroid Build Coastguard Worker
355*333d2b36SAndroid Build Coastguard Workerfunc (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependencyProxy(OtherModuleProviderContext, ModuleProxy) bool {
356*333d2b36SAndroid Build Coastguard Worker	return true
357*333d2b36SAndroid Build Coastguard Worker}
358*333d2b36SAndroid Build Coastguard Worker
359*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module {
360*333d2b36SAndroid Build Coastguard Worker	aModule, _ := module.(Module)
361*333d2b36SAndroid Build Coastguard Worker
362*333d2b36SAndroid Build Coastguard Worker	if !strict {
363*333d2b36SAndroid Build Coastguard Worker		return aModule
364*333d2b36SAndroid Build Coastguard Worker	}
365*333d2b36SAndroid Build Coastguard Worker
366*333d2b36SAndroid Build Coastguard Worker	if aModule == nil {
367*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag))
368*333d2b36SAndroid Build Coastguard Worker	}
369*333d2b36SAndroid Build Coastguard Worker
370*333d2b36SAndroid Build Coastguard Worker	if !aModule.Enabled(b) {
371*333d2b36SAndroid Build Coastguard Worker		if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
372*333d2b36SAndroid Build Coastguard Worker			if b.Config().AllowMissingDependencies() {
373*333d2b36SAndroid Build Coastguard Worker				b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
374*333d2b36SAndroid Build Coastguard Worker			} else {
375*333d2b36SAndroid Build Coastguard Worker				b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
376*333d2b36SAndroid Build Coastguard Worker			}
377*333d2b36SAndroid Build Coastguard Worker		}
378*333d2b36SAndroid Build Coastguard Worker		return nil
379*333d2b36SAndroid Build Coastguard Worker	}
380*333d2b36SAndroid Build Coastguard Worker	return aModule
381*333d2b36SAndroid Build Coastguard Worker}
382*333d2b36SAndroid Build Coastguard Worker
383*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) validateAndroidModuleProxy(
384*333d2b36SAndroid Build Coastguard Worker	module blueprint.ModuleProxy, tag blueprint.DependencyTag, strict bool) *ModuleProxy {
385*333d2b36SAndroid Build Coastguard Worker	aModule := ModuleProxy{module: module}
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	if !strict {
388*333d2b36SAndroid Build Coastguard Worker		return &aModule
389*333d2b36SAndroid Build Coastguard Worker	}
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Worker	if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).Enabled {
392*333d2b36SAndroid Build Coastguard Worker		if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependencyProxy(b, aModule) {
393*333d2b36SAndroid Build Coastguard Worker			if b.Config().AllowMissingDependencies() {
394*333d2b36SAndroid Build Coastguard Worker				b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
395*333d2b36SAndroid Build Coastguard Worker			} else {
396*333d2b36SAndroid Build Coastguard Worker				b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
397*333d2b36SAndroid Build Coastguard Worker			}
398*333d2b36SAndroid Build Coastguard Worker		}
399*333d2b36SAndroid Build Coastguard Worker		return nil
400*333d2b36SAndroid Build Coastguard Worker	}
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Worker	return &aModule
403*333d2b36SAndroid Build Coastguard Worker}
404*333d2b36SAndroid Build Coastguard Worker
405*333d2b36SAndroid Build Coastguard Workertype dep struct {
406*333d2b36SAndroid Build Coastguard Worker	mod blueprint.Module
407*333d2b36SAndroid Build Coastguard Worker	tag blueprint.DependencyTag
408*333d2b36SAndroid Build Coastguard Worker}
409*333d2b36SAndroid Build Coastguard Worker
410*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
411*333d2b36SAndroid Build Coastguard Worker	var deps []dep
412*333d2b36SAndroid Build Coastguard Worker	b.VisitDirectDeps(func(module Module) {
413*333d2b36SAndroid Build Coastguard Worker		if module.base().BaseModuleName() == name {
414*333d2b36SAndroid Build Coastguard Worker			returnedTag := b.bp.OtherModuleDependencyTag(module)
415*333d2b36SAndroid Build Coastguard Worker			if tag == nil || returnedTag == tag {
416*333d2b36SAndroid Build Coastguard Worker				deps = append(deps, dep{module, returnedTag})
417*333d2b36SAndroid Build Coastguard Worker			}
418*333d2b36SAndroid Build Coastguard Worker		}
419*333d2b36SAndroid Build Coastguard Worker	})
420*333d2b36SAndroid Build Coastguard Worker	return deps
421*333d2b36SAndroid Build Coastguard Worker}
422*333d2b36SAndroid Build Coastguard Worker
423*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
424*333d2b36SAndroid Build Coastguard Worker	deps := b.getDirectDepsInternal(name, tag)
425*333d2b36SAndroid Build Coastguard Worker	if len(deps) == 1 {
426*333d2b36SAndroid Build Coastguard Worker		return deps[0].mod, deps[0].tag
427*333d2b36SAndroid Build Coastguard Worker	} else if len(deps) >= 2 {
428*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
429*333d2b36SAndroid Build Coastguard Worker			name, b.ModuleName()))
430*333d2b36SAndroid Build Coastguard Worker	} else {
431*333d2b36SAndroid Build Coastguard Worker		return nil, nil
432*333d2b36SAndroid Build Coastguard Worker	}
433*333d2b36SAndroid Build Coastguard Worker}
434*333d2b36SAndroid Build Coastguard Worker
435*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
436*333d2b36SAndroid Build Coastguard Worker	foundDeps := b.getDirectDepsInternal(name, nil)
437*333d2b36SAndroid Build Coastguard Worker	deps := map[blueprint.Module]bool{}
438*333d2b36SAndroid Build Coastguard Worker	for _, dep := range foundDeps {
439*333d2b36SAndroid Build Coastguard Worker		deps[dep.mod] = true
440*333d2b36SAndroid Build Coastguard Worker	}
441*333d2b36SAndroid Build Coastguard Worker	if len(deps) == 1 {
442*333d2b36SAndroid Build Coastguard Worker		return foundDeps[0].mod, foundDeps[0].tag
443*333d2b36SAndroid Build Coastguard Worker	} else if len(deps) >= 2 {
444*333d2b36SAndroid Build Coastguard Worker		// this could happen if two dependencies have the same name in different namespaces
445*333d2b36SAndroid Build Coastguard Worker		// TODO(b/186554727): this should not occur if namespaces are handled within
446*333d2b36SAndroid Build Coastguard Worker		// getDirectDepsInternal.
447*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
448*333d2b36SAndroid Build Coastguard Worker			name, b.ModuleName()))
449*333d2b36SAndroid Build Coastguard Worker	} else {
450*333d2b36SAndroid Build Coastguard Worker		return nil, nil
451*333d2b36SAndroid Build Coastguard Worker	}
452*333d2b36SAndroid Build Coastguard Worker}
453*333d2b36SAndroid Build Coastguard Worker
454*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
455*333d2b36SAndroid Build Coastguard Worker	var deps []Module
456*333d2b36SAndroid Build Coastguard Worker	b.VisitDirectDeps(func(module Module) {
457*333d2b36SAndroid Build Coastguard Worker		if b.bp.OtherModuleDependencyTag(module) == tag {
458*333d2b36SAndroid Build Coastguard Worker			deps = append(deps, module)
459*333d2b36SAndroid Build Coastguard Worker		}
460*333d2b36SAndroid Build Coastguard Worker	})
461*333d2b36SAndroid Build Coastguard Worker	return deps
462*333d2b36SAndroid Build Coastguard Worker}
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
465*333d2b36SAndroid Build Coastguard Worker// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
466*333d2b36SAndroid Build Coastguard Worker// first DependencyTag.
467*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
468*333d2b36SAndroid Build Coastguard Worker	return b.getDirectDepFirstTag(name)
469*333d2b36SAndroid Build Coastguard Worker}
470*333d2b36SAndroid Build Coastguard Worker
471*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
472*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDeps(func(module blueprint.Module) {
473*333d2b36SAndroid Build Coastguard Worker		if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
474*333d2b36SAndroid Build Coastguard Worker			visit(aModule)
475*333d2b36SAndroid Build Coastguard Worker		}
476*333d2b36SAndroid Build Coastguard Worker	})
477*333d2b36SAndroid Build Coastguard Worker}
478*333d2b36SAndroid Build Coastguard Worker
479*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDepsProxy(visit func(ModuleProxy)) {
480*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) {
481*333d2b36SAndroid Build Coastguard Worker		if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
482*333d2b36SAndroid Build Coastguard Worker			visit(*aModule)
483*333d2b36SAndroid Build Coastguard Worker		}
484*333d2b36SAndroid Build Coastguard Worker	})
485*333d2b36SAndroid Build Coastguard Worker}
486*333d2b36SAndroid Build Coastguard Worker
487*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy)) {
488*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDepsProxy(visitProxyAdaptor(visit))
489*333d2b36SAndroid Build Coastguard Worker}
490*333d2b36SAndroid Build Coastguard Worker
491*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
492*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDeps(func(module blueprint.Module) {
493*333d2b36SAndroid Build Coastguard Worker		if b.bp.OtherModuleDependencyTag(module) == tag {
494*333d2b36SAndroid Build Coastguard Worker			if aModule := b.validateAndroidModule(module, tag, b.strictVisitDeps); aModule != nil {
495*333d2b36SAndroid Build Coastguard Worker				visit(aModule)
496*333d2b36SAndroid Build Coastguard Worker			}
497*333d2b36SAndroid Build Coastguard Worker		}
498*333d2b36SAndroid Build Coastguard Worker	})
499*333d2b36SAndroid Build Coastguard Worker}
500*333d2b36SAndroid Build Coastguard Worker
501*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(proxy ModuleProxy)) {
502*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) {
503*333d2b36SAndroid Build Coastguard Worker		if b.bp.OtherModuleDependencyTag(module) == tag {
504*333d2b36SAndroid Build Coastguard Worker			if aModule := b.validateAndroidModuleProxy(module, tag, b.strictVisitDeps); aModule != nil {
505*333d2b36SAndroid Build Coastguard Worker				visit(*aModule)
506*333d2b36SAndroid Build Coastguard Worker			}
507*333d2b36SAndroid Build Coastguard Worker		}
508*333d2b36SAndroid Build Coastguard Worker	})
509*333d2b36SAndroid Build Coastguard Worker}
510*333d2b36SAndroid Build Coastguard Worker
511*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
512*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDirectDepsIf(
513*333d2b36SAndroid Build Coastguard Worker		// pred
514*333d2b36SAndroid Build Coastguard Worker		func(module blueprint.Module) bool {
515*333d2b36SAndroid Build Coastguard Worker			if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
516*333d2b36SAndroid Build Coastguard Worker				return pred(aModule)
517*333d2b36SAndroid Build Coastguard Worker			} else {
518*333d2b36SAndroid Build Coastguard Worker				return false
519*333d2b36SAndroid Build Coastguard Worker			}
520*333d2b36SAndroid Build Coastguard Worker		},
521*333d2b36SAndroid Build Coastguard Worker		// visit
522*333d2b36SAndroid Build Coastguard Worker		func(module blueprint.Module) {
523*333d2b36SAndroid Build Coastguard Worker			visit(module.(Module))
524*333d2b36SAndroid Build Coastguard Worker		})
525*333d2b36SAndroid Build Coastguard Worker}
526*333d2b36SAndroid Build Coastguard Worker
527*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
528*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
529*333d2b36SAndroid Build Coastguard Worker		if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
530*333d2b36SAndroid Build Coastguard Worker			visit(aModule)
531*333d2b36SAndroid Build Coastguard Worker		}
532*333d2b36SAndroid Build Coastguard Worker	})
533*333d2b36SAndroid Build Coastguard Worker}
534*333d2b36SAndroid Build Coastguard Worker
535*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
536*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitDepsDepthFirstIf(
537*333d2b36SAndroid Build Coastguard Worker		// pred
538*333d2b36SAndroid Build Coastguard Worker		func(module blueprint.Module) bool {
539*333d2b36SAndroid Build Coastguard Worker			if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
540*333d2b36SAndroid Build Coastguard Worker				return pred(aModule)
541*333d2b36SAndroid Build Coastguard Worker			} else {
542*333d2b36SAndroid Build Coastguard Worker				return false
543*333d2b36SAndroid Build Coastguard Worker			}
544*333d2b36SAndroid Build Coastguard Worker		},
545*333d2b36SAndroid Build Coastguard Worker		// visit
546*333d2b36SAndroid Build Coastguard Worker		func(module blueprint.Module) {
547*333d2b36SAndroid Build Coastguard Worker			visit(module.(Module))
548*333d2b36SAndroid Build Coastguard Worker		})
549*333d2b36SAndroid Build Coastguard Worker}
550*333d2b36SAndroid Build Coastguard Worker
551*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
552*333d2b36SAndroid Build Coastguard Worker	b.walkPath = []Module{b.Module()}
553*333d2b36SAndroid Build Coastguard Worker	b.tagPath = []blueprint.DependencyTag{}
554*333d2b36SAndroid Build Coastguard Worker	b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
555*333d2b36SAndroid Build Coastguard Worker		childAndroidModule, _ := child.(Module)
556*333d2b36SAndroid Build Coastguard Worker		parentAndroidModule, _ := parent.(Module)
557*333d2b36SAndroid Build Coastguard Worker		if childAndroidModule != nil && parentAndroidModule != nil {
558*333d2b36SAndroid Build Coastguard Worker			// record walkPath before visit
559*333d2b36SAndroid Build Coastguard Worker			for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
560*333d2b36SAndroid Build Coastguard Worker				b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
561*333d2b36SAndroid Build Coastguard Worker				b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
562*333d2b36SAndroid Build Coastguard Worker			}
563*333d2b36SAndroid Build Coastguard Worker			b.walkPath = append(b.walkPath, childAndroidModule)
564*333d2b36SAndroid Build Coastguard Worker			b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
565*333d2b36SAndroid Build Coastguard Worker			return visit(childAndroidModule, parentAndroidModule)
566*333d2b36SAndroid Build Coastguard Worker		} else {
567*333d2b36SAndroid Build Coastguard Worker			return false
568*333d2b36SAndroid Build Coastguard Worker		}
569*333d2b36SAndroid Build Coastguard Worker	})
570*333d2b36SAndroid Build Coastguard Worker}
571*333d2b36SAndroid Build Coastguard Worker
572*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) WalkDepsProxy(visit func(ModuleProxy, ModuleProxy) bool) {
573*333d2b36SAndroid Build Coastguard Worker	b.walkPath = []Module{ModuleProxy{blueprint.CreateModuleProxy(b.Module())}}
574*333d2b36SAndroid Build Coastguard Worker	b.tagPath = []blueprint.DependencyTag{}
575*333d2b36SAndroid Build Coastguard Worker	b.bp.WalkDepsProxy(func(child, parent blueprint.ModuleProxy) bool {
576*333d2b36SAndroid Build Coastguard Worker		childAndroidModule := ModuleProxy{child}
577*333d2b36SAndroid Build Coastguard Worker		parentAndroidModule := ModuleProxy{parent}
578*333d2b36SAndroid Build Coastguard Worker		// record walkPath before visit
579*333d2b36SAndroid Build Coastguard Worker		for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
580*333d2b36SAndroid Build Coastguard Worker			b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
581*333d2b36SAndroid Build Coastguard Worker			b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
582*333d2b36SAndroid Build Coastguard Worker		}
583*333d2b36SAndroid Build Coastguard Worker		b.walkPath = append(b.walkPath, childAndroidModule)
584*333d2b36SAndroid Build Coastguard Worker		b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
585*333d2b36SAndroid Build Coastguard Worker		return visit(childAndroidModule, parentAndroidModule)
586*333d2b36SAndroid Build Coastguard Worker	})
587*333d2b36SAndroid Build Coastguard Worker}
588*333d2b36SAndroid Build Coastguard Worker
589*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetWalkPath() []Module {
590*333d2b36SAndroid Build Coastguard Worker	return slices.Clone(b.walkPath)
591*333d2b36SAndroid Build Coastguard Worker}
592*333d2b36SAndroid Build Coastguard Worker
593*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
594*333d2b36SAndroid Build Coastguard Worker	return b.tagPath
595*333d2b36SAndroid Build Coastguard Worker}
596*333d2b36SAndroid Build Coastguard Worker
597*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
598*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitAllModuleVariants(func(module blueprint.Module) {
599*333d2b36SAndroid Build Coastguard Worker		visit(module.(Module))
600*333d2b36SAndroid Build Coastguard Worker	})
601*333d2b36SAndroid Build Coastguard Worker}
602*333d2b36SAndroid Build Coastguard Worker
603*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) VisitAllModuleVariantProxies(visit func(ModuleProxy)) {
604*333d2b36SAndroid Build Coastguard Worker	b.bp.VisitAllModuleVariantProxies(visitProxyAdaptor(visit))
605*333d2b36SAndroid Build Coastguard Worker}
606*333d2b36SAndroid Build Coastguard Worker
607*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) PrimaryModule() Module {
608*333d2b36SAndroid Build Coastguard Worker	return b.bp.PrimaryModule().(Module)
609*333d2b36SAndroid Build Coastguard Worker}
610*333d2b36SAndroid Build Coastguard Worker
611*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) FinalModule() Module {
612*333d2b36SAndroid Build Coastguard Worker	return b.bp.FinalModule().(Module)
613*333d2b36SAndroid Build Coastguard Worker}
614*333d2b36SAndroid Build Coastguard Worker
615*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) IsFinalModule(module Module) bool {
616*333d2b36SAndroid Build Coastguard Worker	return b.bp.IsFinalModule(module)
617*333d2b36SAndroid Build Coastguard Worker}
618*333d2b36SAndroid Build Coastguard Worker
619*333d2b36SAndroid Build Coastguard Worker// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
620*333d2b36SAndroid Build Coastguard Workerfunc IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
621*333d2b36SAndroid Build Coastguard Worker	if tag == licenseKindTag {
622*333d2b36SAndroid Build Coastguard Worker		return true
623*333d2b36SAndroid Build Coastguard Worker	} else if tag == licensesTag {
624*333d2b36SAndroid Build Coastguard Worker		return true
625*333d2b36SAndroid Build Coastguard Worker	} else if tag == AcDepTag {
626*333d2b36SAndroid Build Coastguard Worker		return true
627*333d2b36SAndroid Build Coastguard Worker	}
628*333d2b36SAndroid Build Coastguard Worker	return false
629*333d2b36SAndroid Build Coastguard Worker}
630*333d2b36SAndroid Build Coastguard Worker
631*333d2b36SAndroid Build Coastguard Worker// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
632*333d2b36SAndroid Build Coastguard Worker// a dependency tag.
633*333d2b36SAndroid Build Coastguard Workervar tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
634*333d2b36SAndroid Build Coastguard Worker
635*333d2b36SAndroid Build Coastguard Worker// PrettyPrintTag returns string representation of the tag, but prefers
636*333d2b36SAndroid Build Coastguard Worker// custom String() method if available.
637*333d2b36SAndroid Build Coastguard Workerfunc PrettyPrintTag(tag blueprint.DependencyTag) string {
638*333d2b36SAndroid Build Coastguard Worker	// Use tag's custom String() method if available.
639*333d2b36SAndroid Build Coastguard Worker	if stringer, ok := tag.(fmt.Stringer); ok {
640*333d2b36SAndroid Build Coastguard Worker		return stringer.String()
641*333d2b36SAndroid Build Coastguard Worker	}
642*333d2b36SAndroid Build Coastguard Worker
643*333d2b36SAndroid Build Coastguard Worker	// Otherwise, get a default string representation of the tag's struct.
644*333d2b36SAndroid Build Coastguard Worker	tagString := fmt.Sprintf("%T: %+v", tag, tag)
645*333d2b36SAndroid Build Coastguard Worker
646*333d2b36SAndroid Build Coastguard Worker	// Remove the boilerplate from BaseDependencyTag as it adds no value.
647*333d2b36SAndroid Build Coastguard Worker	tagString = tagCleaner.ReplaceAllString(tagString, "")
648*333d2b36SAndroid Build Coastguard Worker	return tagString
649*333d2b36SAndroid Build Coastguard Worker}
650*333d2b36SAndroid Build Coastguard Worker
651*333d2b36SAndroid Build Coastguard Workerfunc (b *baseModuleContext) GetPathString(skipFirst bool) string {
652*333d2b36SAndroid Build Coastguard Worker	sb := strings.Builder{}
653*333d2b36SAndroid Build Coastguard Worker	tagPath := b.GetTagPath()
654*333d2b36SAndroid Build Coastguard Worker	walkPath := b.GetWalkPath()
655*333d2b36SAndroid Build Coastguard Worker	if !skipFirst {
656*333d2b36SAndroid Build Coastguard Worker		sb.WriteString(walkPath[0].String())
657*333d2b36SAndroid Build Coastguard Worker	}
658*333d2b36SAndroid Build Coastguard Worker	for i, m := range walkPath[1:] {
659*333d2b36SAndroid Build Coastguard Worker		sb.WriteString("\n")
660*333d2b36SAndroid Build Coastguard Worker		sb.WriteString(fmt.Sprintf("           via tag %s\n", PrettyPrintTag(tagPath[i])))
661*333d2b36SAndroid Build Coastguard Worker		sb.WriteString(fmt.Sprintf("    -> %s", m.String()))
662*333d2b36SAndroid Build Coastguard Worker	}
663*333d2b36SAndroid Build Coastguard Worker	return sb.String()
664*333d2b36SAndroid Build Coastguard Worker}
665*333d2b36SAndroid Build Coastguard Worker
666*333d2b36SAndroid Build Coastguard Workerfunc (m *baseModuleContext) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
667*333d2b36SAndroid Build Coastguard Worker	return m.Module().ConfigurableEvaluator(m).EvaluateConfiguration(condition, property)
668*333d2b36SAndroid Build Coastguard Worker}
669