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