• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package blueprint
16
17import (
18	"bytes"
19	"context"
20	"crypto/sha256"
21	"encoding/base64"
22	"encoding/json"
23	"errors"
24	"fmt"
25	"io"
26	"io/ioutil"
27	"os"
28	"path/filepath"
29	"reflect"
30	"runtime"
31	"runtime/pprof"
32	"sort"
33	"strings"
34	"sync"
35	"sync/atomic"
36	"text/scanner"
37	"text/template"
38
39	"github.com/google/blueprint/metrics"
40	"github.com/google/blueprint/parser"
41	"github.com/google/blueprint/pathtools"
42	"github.com/google/blueprint/proptools"
43)
44
45var ErrBuildActionsNotReady = errors.New("build actions are not ready")
46
47const maxErrors = 10
48const MockModuleListFile = "bplist"
49
50// A Context contains all the state needed to parse a set of Blueprints files
51// and generate a Ninja file.  The process of generating a Ninja file proceeds
52// through a series of four phases.  Each phase corresponds with a some methods
53// on the Context object
54//
55//	      Phase                            Methods
56//	   ------------      -------------------------------------------
57//	1. Registration         RegisterModuleType, RegisterSingletonType
58//
59//	2. Parse                    ParseBlueprintsFiles, Parse
60//
61//	3. Generate            ResolveDependencies, PrepareBuildActions
62//
63//	4. Write                           WriteBuildFile
64//
65// The registration phase prepares the context to process Blueprints files
66// containing various types of modules.  The parse phase reads in one or more
67// Blueprints files and validates their contents against the module types that
68// have been registered.  The generate phase then analyzes the parsed Blueprints
69// contents to create an internal representation for the build actions that must
70// be performed.  This phase also performs validation of the module dependencies
71// and property values defined in the parsed Blueprints files.  Finally, the
72// write phase generates the Ninja manifest text based on the generated build
73// actions.
74type Context struct {
75	context.Context
76
77	// Used for metrics-related event logging.
78	EventHandler *metrics.EventHandler
79
80	BeforePrepareBuildActionsHook func() error
81
82	moduleFactories     map[string]ModuleFactory
83	nameInterface       NameInterface
84	moduleGroups        []*moduleGroup
85	moduleInfo          map[Module]*moduleInfo
86	modulesSorted       []*moduleInfo
87	preSingletonInfo    []*singletonInfo
88	singletonInfo       []*singletonInfo
89	mutatorInfo         []*mutatorInfo
90	variantMutatorNames []string
91
92	depsModified uint32 // positive if a mutator modified the dependencies
93
94	dependenciesReady bool // set to true on a successful ResolveDependencies
95	buildActionsReady bool // set to true on a successful PrepareBuildActions
96
97	// set by SetIgnoreUnknownModuleTypes
98	ignoreUnknownModuleTypes bool
99
100	// set by SetAllowMissingDependencies
101	allowMissingDependencies bool
102
103	// set during PrepareBuildActions
104	pkgNames        map[*packageContext]string
105	liveGlobals     *liveTracker
106	globalVariables map[Variable]ninjaString
107	globalPools     map[Pool]*poolDef
108	globalRules     map[Rule]*ruleDef
109
110	// set during PrepareBuildActions
111	outDir             ninjaString // The builddir special Ninja variable
112	requiredNinjaMajor int         // For the ninja_required_version variable
113	requiredNinjaMinor int         // For the ninja_required_version variable
114	requiredNinjaMicro int         // For the ninja_required_version variable
115
116	subninjas []string
117
118	// set lazily by sortedModuleGroups
119	cachedSortedModuleGroups []*moduleGroup
120	// cache deps modified to determine whether cachedSortedModuleGroups needs to be recalculated
121	cachedDepsModified bool
122
123	globs    map[globKey]pathtools.GlobResult
124	globLock sync.Mutex
125
126	srcDir         string
127	fs             pathtools.FileSystem
128	moduleListFile string
129
130	// Mutators indexed by the ID of the provider associated with them.  Not all mutators will
131	// have providers, and not all providers will have a mutator, or if they do the mutator may
132	// not be registered in this Context.
133	providerMutators []*mutatorInfo
134
135	// The currently running mutator
136	startedMutator *mutatorInfo
137	// True for any mutators that have already run over all modules
138	finishedMutators map[*mutatorInfo]bool
139
140	// Can be set by tests to avoid invalidating Module values after mutators.
141	skipCloneModulesAfterMutators bool
142
143	// String values that can be used to gate build graph traversal
144	includeTags *IncludeTags
145
146	sourceRootDirs *SourceRootDirs
147}
148
149// A container for String keys. The keys can be used to gate build graph traversal
150type SourceRootDirs struct {
151	dirs []string
152}
153
154func (dirs *SourceRootDirs) Add(names ...string) {
155	dirs.dirs = append(dirs.dirs, names...)
156}
157
158func (dirs *SourceRootDirs) SourceRootDirAllowed(path string) (bool, string) {
159	sort.Slice(dirs.dirs, func(i, j int) bool {
160		return len(dirs.dirs[i]) < len(dirs.dirs[j])
161	})
162	last := len(dirs.dirs)
163	for i := range dirs.dirs {
164		// iterate from longest paths (most specific)
165		prefix := dirs.dirs[last-i-1]
166		disallowedPrefix := false
167		if len(prefix) >= 1 && prefix[0] == '-' {
168			prefix = prefix[1:]
169			disallowedPrefix = true
170		}
171		if strings.HasPrefix(path, prefix) {
172			if disallowedPrefix {
173				return false, prefix
174			} else {
175				return true, prefix
176			}
177		}
178	}
179	return true, ""
180}
181
182func (c *Context) AddSourceRootDirs(dirs ...string) {
183	c.sourceRootDirs.Add(dirs...)
184}
185
186// A container for String keys. The keys can be used to gate build graph traversal
187type IncludeTags map[string]bool
188
189func (tags *IncludeTags) Add(names ...string) {
190	for _, name := range names {
191		(*tags)[name] = true
192	}
193}
194
195func (tags *IncludeTags) Contains(tag string) bool {
196	_, exists := (*tags)[tag]
197	return exists
198}
199
200func (c *Context) AddIncludeTags(names ...string) {
201	c.includeTags.Add(names...)
202}
203
204func (c *Context) ContainsIncludeTag(name string) bool {
205	return c.includeTags.Contains(name)
206}
207
208// An Error describes a problem that was encountered that is related to a
209// particular location in a Blueprints file.
210type BlueprintError struct {
211	Err error            // the error that occurred
212	Pos scanner.Position // the relevant Blueprints file location
213}
214
215// A ModuleError describes a problem that was encountered that is related to a
216// particular module in a Blueprints file
217type ModuleError struct {
218	BlueprintError
219	module *moduleInfo
220}
221
222// A PropertyError describes a problem that was encountered that is related to a
223// particular property in a Blueprints file
224type PropertyError struct {
225	ModuleError
226	property string
227}
228
229func (e *BlueprintError) Error() string {
230	return fmt.Sprintf("%s: %s", e.Pos, e.Err)
231}
232
233func (e *ModuleError) Error() string {
234	return fmt.Sprintf("%s: %s: %s", e.Pos, e.module, e.Err)
235}
236
237func (e *PropertyError) Error() string {
238	return fmt.Sprintf("%s: %s: %s: %s", e.Pos, e.module, e.property, e.Err)
239}
240
241type localBuildActions struct {
242	variables []*localVariable
243	rules     []*localRule
244	buildDefs []*buildDef
245}
246
247type moduleAlias struct {
248	variant variant
249	target  *moduleInfo
250}
251
252func (m *moduleAlias) alias() *moduleAlias              { return m }
253func (m *moduleAlias) module() *moduleInfo              { return nil }
254func (m *moduleAlias) moduleOrAliasTarget() *moduleInfo { return m.target }
255func (m *moduleAlias) moduleOrAliasVariant() variant    { return m.variant }
256
257func (m *moduleInfo) alias() *moduleAlias              { return nil }
258func (m *moduleInfo) module() *moduleInfo              { return m }
259func (m *moduleInfo) moduleOrAliasTarget() *moduleInfo { return m }
260func (m *moduleInfo) moduleOrAliasVariant() variant    { return m.variant }
261
262type moduleOrAlias interface {
263	alias() *moduleAlias
264	module() *moduleInfo
265	moduleOrAliasTarget() *moduleInfo
266	moduleOrAliasVariant() variant
267}
268
269type modulesOrAliases []moduleOrAlias
270
271func (l modulesOrAliases) firstModule() *moduleInfo {
272	for _, moduleOrAlias := range l {
273		if m := moduleOrAlias.module(); m != nil {
274			return m
275		}
276	}
277	panic(fmt.Errorf("no first module!"))
278}
279
280func (l modulesOrAliases) lastModule() *moduleInfo {
281	for i := range l {
282		if m := l[len(l)-1-i].module(); m != nil {
283			return m
284		}
285	}
286	panic(fmt.Errorf("no last module!"))
287}
288
289type moduleGroup struct {
290	name      string
291	ninjaName string
292
293	modules modulesOrAliases
294
295	namespace Namespace
296}
297
298func (group *moduleGroup) moduleOrAliasByVariantName(name string) moduleOrAlias {
299	for _, module := range group.modules {
300		if module.moduleOrAliasVariant().name == name {
301			return module
302		}
303	}
304	return nil
305}
306
307func (group *moduleGroup) moduleByVariantName(name string) *moduleInfo {
308	return group.moduleOrAliasByVariantName(name).module()
309}
310
311type moduleInfo struct {
312	// set during Parse
313	typeName          string
314	factory           ModuleFactory
315	relBlueprintsFile string
316	pos               scanner.Position
317	propertyPos       map[string]scanner.Position
318	createdBy         *moduleInfo
319
320	variant variant
321
322	logicModule Module
323	group       *moduleGroup
324	properties  []interface{}
325
326	// set during ResolveDependencies
327	missingDeps   []string
328	newDirectDeps []depInfo
329
330	// set during updateDependencies
331	reverseDeps []*moduleInfo
332	forwardDeps []*moduleInfo
333	directDeps  []depInfo
334
335	// used by parallelVisit
336	waitingCount int
337
338	// set during each runMutator
339	splitModules modulesOrAliases
340
341	// Used by TransitionMutator implementations
342	transitionVariations     []string
343	currentTransitionMutator string
344	requiredVariationsLock   sync.Mutex
345
346	// set during PrepareBuildActions
347	actionDefs localBuildActions
348
349	providers []interface{}
350
351	startedMutator  *mutatorInfo
352	finishedMutator *mutatorInfo
353
354	startedGenerateBuildActions  bool
355	finishedGenerateBuildActions bool
356}
357
358type variant struct {
359	name                 string
360	variations           variationMap
361	dependencyVariations variationMap
362}
363
364type depInfo struct {
365	module *moduleInfo
366	tag    DependencyTag
367}
368
369func (module *moduleInfo) Name() string {
370	// If this is called from a LoadHook (which is run before the module has been registered)
371	// then group will not be set and so the name is retrieved from logicModule.Name().
372	// Usually, using that method is not safe as it does not track renames (group.name does).
373	// However, when called from LoadHook it is safe as there is no way to rename a module
374	// until after the LoadHook has run and the module has been registered.
375	if module.group != nil {
376		return module.group.name
377	} else {
378		return module.logicModule.Name()
379	}
380}
381
382func (module *moduleInfo) String() string {
383	s := fmt.Sprintf("module %q", module.Name())
384	if module.variant.name != "" {
385		s += fmt.Sprintf(" variant %q", module.variant.name)
386	}
387	if module.createdBy != nil {
388		s += fmt.Sprintf(" (created by %s)", module.createdBy)
389	}
390
391	return s
392}
393
394func (module *moduleInfo) namespace() Namespace {
395	return module.group.namespace
396}
397
398// A Variation is a way that a variant of a module differs from other variants of the same module.
399// For example, two variants of the same module might have Variation{"arch","arm"} and
400// Variation{"arch","arm64"}
401type Variation struct {
402	// Mutator is the axis on which this variation applies, i.e. "arch" or "link"
403	Mutator string
404	// Variation is the name of the variation on the axis, i.e. "arm" or "arm64" for arch, or
405	// "shared" or "static" for link.
406	Variation string
407}
408
409// A variationMap stores a map of Mutator to Variation to specify a variant of a module.
410type variationMap map[string]string
411
412func (vm variationMap) clone() variationMap {
413	if vm == nil {
414		return nil
415	}
416	newVm := make(variationMap)
417	for k, v := range vm {
418		newVm[k] = v
419	}
420
421	return newVm
422}
423
424// Compare this variationMap to another one.  Returns true if the every entry in this map
425// exists and has the same value in the other map.
426func (vm variationMap) subsetOf(other variationMap) bool {
427	for k, v1 := range vm {
428		if v2, ok := other[k]; !ok || v1 != v2 {
429			return false
430		}
431	}
432	return true
433}
434
435func (vm variationMap) equal(other variationMap) bool {
436	return reflect.DeepEqual(vm, other)
437}
438
439type singletonInfo struct {
440	// set during RegisterSingletonType
441	factory   SingletonFactory
442	singleton Singleton
443	name      string
444
445	// set during PrepareBuildActions
446	actionDefs localBuildActions
447}
448
449type mutatorInfo struct {
450	// set during RegisterMutator
451	topDownMutator  TopDownMutator
452	bottomUpMutator BottomUpMutator
453	name            string
454	parallel        bool
455}
456
457func newContext() *Context {
458	eventHandler := metrics.EventHandler{}
459	return &Context{
460		Context:            context.Background(),
461		EventHandler:       &eventHandler,
462		moduleFactories:    make(map[string]ModuleFactory),
463		nameInterface:      NewSimpleNameInterface(),
464		moduleInfo:         make(map[Module]*moduleInfo),
465		globs:              make(map[globKey]pathtools.GlobResult),
466		fs:                 pathtools.OsFs,
467		finishedMutators:   make(map[*mutatorInfo]bool),
468		includeTags:        &IncludeTags{},
469		sourceRootDirs:     &SourceRootDirs{},
470		outDir:             nil,
471		requiredNinjaMajor: 1,
472		requiredNinjaMinor: 7,
473		requiredNinjaMicro: 0,
474	}
475}
476
477// NewContext creates a new Context object.  The created context initially has
478// no module or singleton factories registered, so the RegisterModuleFactory and
479// RegisterSingletonFactory methods must be called before it can do anything
480// useful.
481func NewContext() *Context {
482	ctx := newContext()
483
484	ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)
485
486	return ctx
487}
488
489// A ModuleFactory function creates a new Module object.  See the
490// Context.RegisterModuleType method for details about how a registered
491// ModuleFactory is used by a Context.
492type ModuleFactory func() (m Module, propertyStructs []interface{})
493
494// RegisterModuleType associates a module type name (which can appear in a
495// Blueprints file) with a Module factory function.  When the given module type
496// name is encountered in a Blueprints file during parsing, the Module factory
497// is invoked to instantiate a new Module object to handle the build action
498// generation for the module.  If a Mutator splits a module into multiple variants,
499// the factory is invoked again to create a new Module for each variant.
500//
501// The module type names given here must be unique for the context.  The factory
502// function should be a named function so that its package and name can be
503// included in the generated Ninja file for debugging purposes.
504//
505// The factory function returns two values.  The first is the newly created
506// Module object.  The second is a slice of pointers to that Module object's
507// properties structs.  Each properties struct is examined when parsing a module
508// definition of this type in a Blueprints file.  Exported fields of the
509// properties structs are automatically set to the property values specified in
510// the Blueprints file.  The properties struct field names determine the name of
511// the Blueprints file properties that are used - the Blueprints property name
512// matches that of the properties struct field name with the first letter
513// converted to lower-case.
514//
515// The fields of the properties struct must be either []string, a string, or
516// bool. The Context will panic if a Module gets instantiated with a properties
517// struct containing a field that is not one these supported types.
518//
519// Any properties that appear in the Blueprints files that are not built-in
520// module properties (such as "name" and "deps") and do not have a corresponding
521// field in the returned module properties struct result in an error during the
522// Context's parse phase.
523//
524// As an example, the follow code:
525//
526//	type myModule struct {
527//	    properties struct {
528//	        Foo string
529//	        Bar []string
530//	    }
531//	}
532//
533//	func NewMyModule() (blueprint.Module, []interface{}) {
534//	    module := new(myModule)
535//	    properties := &module.properties
536//	    return module, []interface{}{properties}
537//	}
538//
539//	func main() {
540//	    ctx := blueprint.NewContext()
541//	    ctx.RegisterModuleType("my_module", NewMyModule)
542//	    // ...
543//	}
544//
545// would support parsing a module defined in a Blueprints file as follows:
546//
547//	my_module {
548//	    name: "myName",
549//	    foo:  "my foo string",
550//	    bar:  ["my", "bar", "strings"],
551//	}
552//
553// The factory function may be called from multiple goroutines.  Any accesses
554// to global variables must be synchronized.
555func (c *Context) RegisterModuleType(name string, factory ModuleFactory) {
556	if _, present := c.moduleFactories[name]; present {
557		panic(fmt.Errorf("module type %q is already registered", name))
558	}
559	c.moduleFactories[name] = factory
560}
561
562// A SingletonFactory function creates a new Singleton object.  See the
563// Context.RegisterSingletonType method for details about how a registered
564// SingletonFactory is used by a Context.
565type SingletonFactory func() Singleton
566
567// RegisterSingletonType registers a singleton type that will be invoked to
568// generate build actions.  Each registered singleton type is instantiated
569// and invoked exactly once as part of the generate phase.  Each registered
570// singleton is invoked in registration order.
571//
572// The singleton type names given here must be unique for the context.  The
573// factory function should be a named function so that its package and name can
574// be included in the generated Ninja file for debugging purposes.
575func (c *Context) RegisterSingletonType(name string, factory SingletonFactory) {
576	for _, s := range c.singletonInfo {
577		if s.name == name {
578			panic(fmt.Errorf("singleton %q is already registered", name))
579		}
580	}
581
582	c.singletonInfo = append(c.singletonInfo, &singletonInfo{
583		factory:   factory,
584		singleton: factory(),
585		name:      name,
586	})
587}
588
589// RegisterPreSingletonType registers a presingleton type that will be invoked to
590// generate build actions before any Blueprint files have been read.  Each registered
591// presingleton type is instantiated and invoked exactly once at the beginning of the
592// parse phase.  Each registered presingleton is invoked in registration order.
593//
594// The presingleton type names given here must be unique for the context.  The
595// factory function should be a named function so that its package and name can
596// be included in the generated Ninja file for debugging purposes.
597func (c *Context) RegisterPreSingletonType(name string, factory SingletonFactory) {
598	for _, s := range c.preSingletonInfo {
599		if s.name == name {
600			panic(fmt.Errorf("presingleton %q is already registered", name))
601		}
602	}
603
604	c.preSingletonInfo = append(c.preSingletonInfo, &singletonInfo{
605		factory:   factory,
606		singleton: factory(),
607		name:      name,
608	})
609}
610
611func (c *Context) SetNameInterface(i NameInterface) {
612	c.nameInterface = i
613}
614
615func (c *Context) SetSrcDir(path string) {
616	c.srcDir = path
617	c.fs = pathtools.NewOsFs(path)
618}
619
620func (c *Context) SrcDir() string {
621	return c.srcDir
622}
623
624func singletonPkgPath(singleton Singleton) string {
625	typ := reflect.TypeOf(singleton)
626	for typ.Kind() == reflect.Ptr {
627		typ = typ.Elem()
628	}
629	return typ.PkgPath()
630}
631
632func singletonTypeName(singleton Singleton) string {
633	typ := reflect.TypeOf(singleton)
634	for typ.Kind() == reflect.Ptr {
635		typ = typ.Elem()
636	}
637	return typ.PkgPath() + "." + typ.Name()
638}
639
640// RegisterTopDownMutator registers a mutator that will be invoked to propagate dependency info
641// top-down between Modules.  Each registered mutator is invoked in registration order (mixing
642// TopDownMutators and BottomUpMutators) once per Module, and the invocation on any module will
643// have returned before it is in invoked on any of its dependencies.
644//
645// The mutator type names given here must be unique to all top down mutators in
646// the Context.
647//
648// Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
649// parallel while maintaining ordering.
650func (c *Context) RegisterTopDownMutator(name string, mutator TopDownMutator) MutatorHandle {
651	for _, m := range c.mutatorInfo {
652		if m.name == name && m.topDownMutator != nil {
653			panic(fmt.Errorf("mutator %q is already registered", name))
654		}
655	}
656
657	info := &mutatorInfo{
658		topDownMutator: mutator,
659		name:           name,
660	}
661
662	c.mutatorInfo = append(c.mutatorInfo, info)
663
664	return info
665}
666
667// RegisterBottomUpMutator registers a mutator that will be invoked to split Modules into variants.
668// Each registered mutator is invoked in registration order (mixing TopDownMutators and
669// BottomUpMutators) once per Module, will not be invoked on a module until the invocations on all
670// of the modules dependencies have returned.
671//
672// The mutator type names given here must be unique to all bottom up or early
673// mutators in the Context.
674//
675// Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
676// parallel while maintaining ordering.
677func (c *Context) RegisterBottomUpMutator(name string, mutator BottomUpMutator) MutatorHandle {
678	for _, m := range c.variantMutatorNames {
679		if m == name {
680			panic(fmt.Errorf("mutator %q is already registered", name))
681		}
682	}
683
684	info := &mutatorInfo{
685		bottomUpMutator: mutator,
686		name:            name,
687	}
688	c.mutatorInfo = append(c.mutatorInfo, info)
689
690	c.variantMutatorNames = append(c.variantMutatorNames, name)
691
692	return info
693}
694
695type IncomingTransitionContext interface {
696	// Module returns the target of the dependency edge for which the transition
697	// is being computed
698	Module() Module
699
700	// Config returns the config object that was passed to
701	// Context.PrepareBuildActions.
702	Config() interface{}
703}
704
705type OutgoingTransitionContext interface {
706	// Module returns the target of the dependency edge for which the transition
707	// is being computed
708	Module() Module
709
710	// DepTag() Returns the dependency tag through which this dependency is
711	// reached
712	DepTag() DependencyTag
713}
714
715// Transition mutators implement a top-down mechanism where a module tells its
716// direct dependencies what variation they should be built in but the dependency
717// has the final say.
718//
719// When implementing a transition mutator, one needs to implement four methods:
720//   - Split() that tells what variations a module has by itself
721//   - OutgoingTransition() where a module tells what it wants from its
722//     dependency
723//   - IncomingTransition() where a module has the final say about its own
724//     variation
725//   - Mutate() that changes the state of a module depending on its variation
726//
727// That the effective variation of module B when depended on by module A is the
728// composition the outgoing transition of module A and the incoming transition
729// of module B.
730//
731// the outgoing transition should not take the properties of the dependency into
732// account, only those of the module that depends on it. For this reason, the
733// dependency is not even passed into it as an argument. Likewise, the incoming
734// transition should not take the properties of the depending module into
735// account and is thus not informed about it. This makes for a nice
736// decomposition of the decision logic.
737//
738// A given transition mutator only affects its own variation; other variations
739// stay unchanged along the dependency edges.
740//
741// Soong makes sure that all modules are created in the desired variations and
742// that dependency edges are set up correctly. This ensures that "missing
743// variation" errors do not happen and allows for more flexible changes in the
744// value of the variation among dependency edges (as oppposed to bottom-up
745// mutators where if module A in variation X depends on module B and module B
746// has that variation X, A must depend on variation X of B)
747//
748// The limited power of the context objects passed to individual mutators
749// methods also makes it more difficult to shoot oneself in the foot. Complete
750// safety is not guaranteed because no one prevents individual transition
751// mutators from mutating modules in illegal ways and for e.g. Split() or
752// Mutate() to run their own visitations of the transitive dependency of the
753// module and both of these are bad ideas, but it's better than no guardrails at
754// all.
755//
756// This model is pretty close to Bazel's configuration transitions. The mapping
757// between concepts in Soong and Bazel is as follows:
758//   - Module == configured target
759//   - Variant == configuration
760//   - Variation name == configuration flag
761//   - Variation == configuration flag value
762//   - Outgoing transition == attribute transition
763//   - Incoming transition == rule transition
764//
765// The Split() method does not have a Bazel equivalent and Bazel split
766// transitions do not have a Soong equivalent.
767//
768// Mutate() does not make sense in Bazel due to the different models of the
769// two systems: when creating new variations, Soong clones the old module and
770// thus some way is needed to change it state whereas Bazel creates each
771// configuration of a given configured target anew.
772type TransitionMutator interface {
773	// Returns the set of variations that should be created for a module no matter
774	// who depends on it. Used when Make depends on a particular variation or when
775	// the module knows its variations just based on information given to it in
776	// the Blueprint file. This method should not mutate the module it is called
777	// on.
778	Split(ctx BaseModuleContext) []string
779
780	// Called on a module to determine which variation it wants from its direct
781	// dependencies. The dependency itself can override this decision. This method
782	// should not mutate the module itself.
783	OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
784
785	// Called on a module to determine which variation it should be in based on
786	// the variation modules that depend on it want. This gives the module a final
787	// say about its own variations. This method should not mutate the module
788	// itself.
789	IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
790
791	// Called after a module was split into multiple variations on each variation.
792	// It should not split the module any further but adding new dependencies is
793	// fine. Unlike all the other methods on TransitionMutator, this method is
794	// allowed to mutate the module.
795	Mutate(ctx BottomUpMutatorContext, variation string)
796}
797
798type transitionMutatorImpl struct {
799	name    string
800	mutator TransitionMutator
801}
802
803// Adds each argument in items to l if it's not already there.
804func addToStringListIfNotPresent(l []string, items ...string) []string {
805OUTER:
806	for _, i := range items {
807		for _, existing := range l {
808			if existing == i {
809				continue OUTER
810			}
811		}
812
813		l = append(l, i)
814	}
815
816	return l
817}
818
819func (t *transitionMutatorImpl) addRequiredVariation(m *moduleInfo, variation string) {
820	m.requiredVariationsLock.Lock()
821	defer m.requiredVariationsLock.Unlock()
822
823	// This is only a consistency check. Leaking the variations of a transition
824	// mutator to another one could well lead to issues that are difficult to
825	// track down.
826	if m.currentTransitionMutator != "" && m.currentTransitionMutator != t.name {
827		panic(fmt.Errorf("transition mutator is %s in mutator %s", m.currentTransitionMutator, t.name))
828	}
829
830	m.currentTransitionMutator = t.name
831	m.transitionVariations = addToStringListIfNotPresent(m.transitionVariations, variation)
832}
833
834func (t *transitionMutatorImpl) topDownMutator(mctx TopDownMutatorContext) {
835	module := mctx.(*mutatorContext).module
836	mutatorSplits := t.mutator.Split(mctx)
837	if mutatorSplits == nil || len(mutatorSplits) == 0 {
838		panic(fmt.Errorf("transition mutator %s returned no splits for module %s", t.name, mctx.ModuleName()))
839	}
840
841	// transitionVariations for given a module can be mutated by the module itself
842	// and modules that directly depend on it. Since this is a top-down mutator,
843	// all modules that directly depend on this module have already been processed
844	// so no locking is necessary.
845	module.transitionVariations = addToStringListIfNotPresent(module.transitionVariations, mutatorSplits...)
846	sort.Strings(module.transitionVariations)
847
848	for _, srcVariation := range module.transitionVariations {
849		for _, dep := range module.directDeps {
850			finalVariation := t.transition(mctx)(mctx.Module(), srcVariation, dep.module.logicModule, dep.tag)
851			t.addRequiredVariation(dep.module, finalVariation)
852		}
853	}
854}
855
856type transitionContextImpl struct {
857	module Module
858	depTag DependencyTag
859	config interface{}
860}
861
862func (c *transitionContextImpl) Module() Module {
863	return c.module
864}
865
866func (c *transitionContextImpl) DepTag() DependencyTag {
867	return c.depTag
868}
869
870func (c *transitionContextImpl) Config() interface{} {
871	return c.config
872}
873
874func (t *transitionMutatorImpl) transition(mctx BaseMutatorContext) Transition {
875	return func(source Module, sourceVariation string, dep Module, depTag DependencyTag) string {
876		tc := &transitionContextImpl{module: dep, depTag: depTag, config: mctx.Config()}
877		outgoingVariation := t.mutator.OutgoingTransition(tc, sourceVariation)
878		finalVariation := t.mutator.IncomingTransition(tc, outgoingVariation)
879		return finalVariation
880	}
881}
882
883func (t *transitionMutatorImpl) bottomUpMutator(mctx BottomUpMutatorContext) {
884	mc := mctx.(*mutatorContext)
885	// Fetch and clean up transition mutator state. No locking needed since the
886	// only time interaction between multiple modules is required is during the
887	// computation of the variations required by a given module.
888	variations := mc.module.transitionVariations
889	mc.module.transitionVariations = nil
890	mc.module.currentTransitionMutator = ""
891
892	if len(variations) < 1 {
893		panic(fmt.Errorf("no variations found for module %s by mutator %s",
894			mctx.ModuleName(), t.name))
895	}
896
897	if len(variations) == 1 && variations[0] == "" {
898		// Module is not split, just apply the transition
899		mc.applyTransition(t.transition(mctx))
900	} else {
901		mc.createVariationsWithTransition(t.transition(mctx), variations...)
902	}
903}
904
905func (t *transitionMutatorImpl) mutateMutator(mctx BottomUpMutatorContext) {
906	module := mctx.(*mutatorContext).module
907	currentVariation := module.variant.variations[t.name]
908	t.mutator.Mutate(mctx, currentVariation)
909}
910
911func (c *Context) RegisterTransitionMutator(name string, mutator TransitionMutator) {
912	impl := &transitionMutatorImpl{name: name, mutator: mutator}
913
914	c.RegisterTopDownMutator(name+"_deps", impl.topDownMutator).Parallel()
915	c.RegisterBottomUpMutator(name, impl.bottomUpMutator).Parallel()
916	c.RegisterBottomUpMutator(name+"_mutate", impl.mutateMutator).Parallel()
917}
918
919type MutatorHandle interface {
920	// Set the mutator to visit modules in parallel while maintaining ordering.  Calling any
921	// method on the mutator context is thread-safe, but the mutator must handle synchronization
922	// for any modifications to global state or any modules outside the one it was invoked on.
923	Parallel() MutatorHandle
924}
925
926func (mutator *mutatorInfo) Parallel() MutatorHandle {
927	mutator.parallel = true
928	return mutator
929}
930
931// SetIgnoreUnknownModuleTypes sets the behavior of the context in the case
932// where it encounters an unknown module type while parsing Blueprints files. By
933// default, the context will report unknown module types as an error.  If this
934// method is called with ignoreUnknownModuleTypes set to true then the context
935// will silently ignore unknown module types.
936//
937// This method should generally not be used.  It exists to facilitate the
938// bootstrapping process.
939func (c *Context) SetIgnoreUnknownModuleTypes(ignoreUnknownModuleTypes bool) {
940	c.ignoreUnknownModuleTypes = ignoreUnknownModuleTypes
941}
942
943// SetAllowMissingDependencies changes the behavior of Blueprint to ignore
944// unresolved dependencies.  If the module's GenerateBuildActions calls
945// ModuleContext.GetMissingDependencies Blueprint will not emit any errors
946// for missing dependencies.
947func (c *Context) SetAllowMissingDependencies(allowMissingDependencies bool) {
948	c.allowMissingDependencies = allowMissingDependencies
949}
950
951func (c *Context) SetModuleListFile(listFile string) {
952	c.moduleListFile = listFile
953}
954
955func (c *Context) ListModulePaths(baseDir string) (paths []string, err error) {
956	reader, err := c.fs.Open(c.moduleListFile)
957	if err != nil {
958		return nil, err
959	}
960	defer reader.Close()
961	bytes, err := ioutil.ReadAll(reader)
962	if err != nil {
963		return nil, err
964	}
965	text := string(bytes)
966
967	text = strings.Trim(text, "\n")
968	lines := strings.Split(text, "\n")
969	for i := range lines {
970		lines[i] = filepath.Join(baseDir, lines[i])
971	}
972
973	return lines, nil
974}
975
976// a fileParseContext tells the status of parsing a particular file
977type fileParseContext struct {
978	// name of file
979	fileName string
980
981	// scope to use when resolving variables
982	Scope *parser.Scope
983
984	// pointer to the one in the parent directory
985	parent *fileParseContext
986
987	// is closed once FileHandler has completed for this file
988	doneVisiting chan struct{}
989}
990
991// ParseBlueprintsFiles parses a set of Blueprints files starting with the file
992// at rootFile.  When it encounters a Blueprints file with a set of subdirs
993// listed it recursively parses any Blueprints files found in those
994// subdirectories.
995//
996// If no errors are encountered while parsing the files, the list of paths on
997// which the future output will depend is returned.  This list will include both
998// Blueprints file paths as well as directory paths for cases where wildcard
999// subdirs are found.
1000func (c *Context) ParseBlueprintsFiles(rootFile string,
1001	config interface{}) (deps []string, errs []error) {
1002
1003	baseDir := filepath.Dir(rootFile)
1004	pathsToParse, err := c.ListModulePaths(baseDir)
1005	if err != nil {
1006		return nil, []error{err}
1007	}
1008	return c.ParseFileList(baseDir, pathsToParse, config)
1009}
1010
1011type shouldVisitFileInfo struct {
1012	shouldVisitFile bool
1013	skippedModules  []string
1014	reasonForSkip   string
1015	errs            []error
1016}
1017
1018// Returns a boolean for whether this file should be analyzed
1019// Evaluates to true if the file either
1020// 1. does not contain a blueprint_package_includes
1021// 2. contains a blueprint_package_includes and all requested tags are set
1022// This should be processed before adding any modules to the build graph
1023func shouldVisitFile(c *Context, file *parser.File) shouldVisitFileInfo {
1024	skippedModules := []string{}
1025	var blueprintPackageIncludes *PackageIncludes
1026	for _, def := range file.Defs {
1027		switch def := def.(type) {
1028		case *parser.Module:
1029			skippedModules = append(skippedModules, def.Name())
1030			if def.Type != "blueprint_package_includes" {
1031				continue
1032			}
1033			module, errs := processModuleDef(def, file.Name, c.moduleFactories, nil, c.ignoreUnknownModuleTypes)
1034			if len(errs) > 0 {
1035				// This file contains errors in blueprint_package_includes
1036				// Visit anyways so that we can report errors on other modules in the file
1037				return shouldVisitFileInfo{
1038					shouldVisitFile: true,
1039					errs:            errs,
1040				}
1041			}
1042			logicModule, _ := c.cloneLogicModule(module)
1043			blueprintPackageIncludes = logicModule.(*PackageIncludes)
1044		}
1045	}
1046
1047	if blueprintPackageIncludes != nil {
1048		packageMatches := blueprintPackageIncludes.MatchesIncludeTags(c)
1049		if !packageMatches {
1050			return shouldVisitFileInfo{
1051				shouldVisitFile: false,
1052				skippedModules:  skippedModules,
1053				reasonForSkip: fmt.Sprintf(
1054					"module is defined in %q which contains a blueprint_package_includes module with unsatisfied tags",
1055					file.Name,
1056				),
1057			}
1058		}
1059	}
1060
1061	shouldVisit, invalidatingPrefix := c.sourceRootDirs.SourceRootDirAllowed(file.Name)
1062	if !shouldVisit {
1063		return shouldVisitFileInfo{
1064			shouldVisitFile: shouldVisit,
1065			skippedModules:  skippedModules,
1066			reasonForSkip: fmt.Sprintf(
1067				"%q is a descendant of %q, and that path prefix was not included in PRODUCT_SOURCE_ROOT_DIRS",
1068				file.Name,
1069				invalidatingPrefix,
1070			),
1071		}
1072	}
1073	return shouldVisitFileInfo{shouldVisitFile: true}
1074}
1075
1076func (c *Context) ParseFileList(rootDir string, filePaths []string,
1077	config interface{}) (deps []string, errs []error) {
1078
1079	if len(filePaths) < 1 {
1080		return nil, []error{fmt.Errorf("no paths provided to parse")}
1081	}
1082
1083	c.dependenciesReady = false
1084
1085	type newModuleInfo struct {
1086		*moduleInfo
1087		deps  []string
1088		added chan<- struct{}
1089	}
1090
1091	type newSkipInfo struct {
1092		shouldVisitFileInfo
1093		file string
1094	}
1095
1096	moduleCh := make(chan newModuleInfo)
1097	errsCh := make(chan []error)
1098	doneCh := make(chan struct{})
1099	skipCh := make(chan newSkipInfo)
1100	var numErrs uint32
1101	var numGoroutines int32
1102
1103	// handler must be reentrant
1104	handleOneFile := func(file *parser.File) {
1105		if atomic.LoadUint32(&numErrs) > maxErrors {
1106			return
1107		}
1108
1109		addedCh := make(chan struct{})
1110
1111		var scopedModuleFactories map[string]ModuleFactory
1112
1113		var addModule func(module *moduleInfo) []error
1114		addModule = func(module *moduleInfo) []error {
1115			// Run any load hooks immediately before it is sent to the moduleCh and is
1116			// registered by name. This allows load hooks to set and/or modify any aspect
1117			// of the module (including names) using information that is not available when
1118			// the module factory is called.
1119			newModules, newDeps, errs := runAndRemoveLoadHooks(c, config, module, &scopedModuleFactories)
1120			if len(errs) > 0 {
1121				return errs
1122			}
1123
1124			moduleCh <- newModuleInfo{module, newDeps, addedCh}
1125			<-addedCh
1126			for _, n := range newModules {
1127				errs = addModule(n)
1128				if len(errs) > 0 {
1129					return errs
1130				}
1131			}
1132			return nil
1133		}
1134		shouldVisitInfo := shouldVisitFile(c, file)
1135		errs := shouldVisitInfo.errs
1136		if len(errs) > 0 {
1137			atomic.AddUint32(&numErrs, uint32(len(errs)))
1138			errsCh <- errs
1139		}
1140		if !shouldVisitInfo.shouldVisitFile {
1141			skipCh <- newSkipInfo{
1142				file:                file.Name,
1143				shouldVisitFileInfo: shouldVisitInfo,
1144			}
1145			// TODO: Write a file that lists the skipped bp files
1146			return
1147		}
1148
1149		for _, def := range file.Defs {
1150			switch def := def.(type) {
1151			case *parser.Module:
1152				module, errs := processModuleDef(def, file.Name, c.moduleFactories, scopedModuleFactories, c.ignoreUnknownModuleTypes)
1153				if len(errs) == 0 && module != nil {
1154					errs = addModule(module)
1155				}
1156
1157				if len(errs) > 0 {
1158					atomic.AddUint32(&numErrs, uint32(len(errs)))
1159					errsCh <- errs
1160				}
1161
1162			case *parser.Assignment:
1163				// Already handled via Scope object
1164			default:
1165				panic("unknown definition type")
1166			}
1167
1168		}
1169	}
1170
1171	atomic.AddInt32(&numGoroutines, 1)
1172	go func() {
1173		var errs []error
1174		deps, errs = c.WalkBlueprintsFiles(rootDir, filePaths, handleOneFile)
1175		if len(errs) > 0 {
1176			errsCh <- errs
1177		}
1178		doneCh <- struct{}{}
1179	}()
1180
1181	var hookDeps []string
1182loop:
1183	for {
1184		select {
1185		case newErrs := <-errsCh:
1186			errs = append(errs, newErrs...)
1187		case module := <-moduleCh:
1188			newErrs := c.addModule(module.moduleInfo)
1189			hookDeps = append(hookDeps, module.deps...)
1190			if module.added != nil {
1191				module.added <- struct{}{}
1192			}
1193			if len(newErrs) > 0 {
1194				errs = append(errs, newErrs...)
1195			}
1196		case <-doneCh:
1197			n := atomic.AddInt32(&numGoroutines, -1)
1198			if n == 0 {
1199				break loop
1200			}
1201		case skipped := <-skipCh:
1202			nctx := newNamespaceContextFromFilename(skipped.file)
1203			for _, name := range skipped.skippedModules {
1204				c.nameInterface.NewSkippedModule(nctx, name, SkippedModuleInfo{
1205					filename: skipped.file,
1206					reason:   skipped.reasonForSkip,
1207				})
1208			}
1209		}
1210	}
1211
1212	deps = append(deps, hookDeps...)
1213	return deps, errs
1214}
1215
1216type FileHandler func(*parser.File)
1217
1218// WalkBlueprintsFiles walks a set of Blueprints files starting with the given filepaths,
1219// calling the given file handler on each
1220//
1221// When WalkBlueprintsFiles encounters a Blueprints file with a set of subdirs listed,
1222// it recursively parses any Blueprints files found in those subdirectories.
1223//
1224// If any of the file paths is an ancestor directory of any other of file path, the ancestor
1225// will be parsed and visited first.
1226//
1227// the file handler will be called from a goroutine, so it must be reentrant.
1228//
1229// If no errors are encountered while parsing the files, the list of paths on
1230// which the future output will depend is returned.  This list will include both
1231// Blueprints file paths as well as directory paths for cases where wildcard
1232// subdirs are found.
1233//
1234// visitor will be called asynchronously, and will only be called once visitor for each
1235// ancestor directory has completed.
1236//
1237// WalkBlueprintsFiles will not return until all calls to visitor have returned.
1238func (c *Context) WalkBlueprintsFiles(rootDir string, filePaths []string,
1239	visitor FileHandler) (deps []string, errs []error) {
1240
1241	// make a mapping from ancestors to their descendants to facilitate parsing ancestors first
1242	descendantsMap, err := findBlueprintDescendants(filePaths)
1243	if err != nil {
1244		panic(err.Error())
1245	}
1246	blueprintsSet := make(map[string]bool)
1247
1248	// Channels to receive data back from openAndParse goroutines
1249	blueprintsCh := make(chan fileParseContext)
1250	errsCh := make(chan []error)
1251	depsCh := make(chan string)
1252
1253	// Channel to notify main loop that a openAndParse goroutine has finished
1254	doneParsingCh := make(chan fileParseContext)
1255
1256	// Number of outstanding goroutines to wait for
1257	activeCount := 0
1258	var pending []fileParseContext
1259	tooManyErrors := false
1260
1261	// Limit concurrent calls to parseBlueprintFiles to 200
1262	// Darwin has a default limit of 256 open files
1263	maxActiveCount := 200
1264
1265	// count the number of pending calls to visitor()
1266	visitorWaitGroup := sync.WaitGroup{}
1267
1268	startParseBlueprintsFile := func(blueprint fileParseContext) {
1269		if blueprintsSet[blueprint.fileName] {
1270			return
1271		}
1272		blueprintsSet[blueprint.fileName] = true
1273		activeCount++
1274		deps = append(deps, blueprint.fileName)
1275		visitorWaitGroup.Add(1)
1276		go func() {
1277			file, blueprints, deps, errs := c.openAndParse(blueprint.fileName, blueprint.Scope, rootDir,
1278				&blueprint)
1279			if len(errs) > 0 {
1280				errsCh <- errs
1281			}
1282			for _, blueprint := range blueprints {
1283				blueprintsCh <- blueprint
1284			}
1285			for _, dep := range deps {
1286				depsCh <- dep
1287			}
1288			doneParsingCh <- blueprint
1289
1290			if blueprint.parent != nil && blueprint.parent.doneVisiting != nil {
1291				// wait for visitor() of parent to complete
1292				<-blueprint.parent.doneVisiting
1293			}
1294
1295			if len(errs) == 0 {
1296				// process this file
1297				visitor(file)
1298			}
1299			if blueprint.doneVisiting != nil {
1300				close(blueprint.doneVisiting)
1301			}
1302			visitorWaitGroup.Done()
1303		}()
1304	}
1305
1306	foundParseableBlueprint := func(blueprint fileParseContext) {
1307		if activeCount >= maxActiveCount {
1308			pending = append(pending, blueprint)
1309		} else {
1310			startParseBlueprintsFile(blueprint)
1311		}
1312	}
1313
1314	startParseDescendants := func(blueprint fileParseContext) {
1315		descendants, hasDescendants := descendantsMap[blueprint.fileName]
1316		if hasDescendants {
1317			for _, descendant := range descendants {
1318				foundParseableBlueprint(fileParseContext{descendant, parser.NewScope(blueprint.Scope), &blueprint, make(chan struct{})})
1319			}
1320		}
1321	}
1322
1323	// begin parsing any files that have no ancestors
1324	startParseDescendants(fileParseContext{"", parser.NewScope(nil), nil, nil})
1325
1326loop:
1327	for {
1328		if len(errs) > maxErrors {
1329			tooManyErrors = true
1330		}
1331
1332		select {
1333		case newErrs := <-errsCh:
1334			errs = append(errs, newErrs...)
1335		case dep := <-depsCh:
1336			deps = append(deps, dep)
1337		case blueprint := <-blueprintsCh:
1338			if tooManyErrors {
1339				continue
1340			}
1341			foundParseableBlueprint(blueprint)
1342		case blueprint := <-doneParsingCh:
1343			activeCount--
1344			if !tooManyErrors {
1345				startParseDescendants(blueprint)
1346			}
1347			if activeCount < maxActiveCount && len(pending) > 0 {
1348				// start to process the next one from the queue
1349				next := pending[len(pending)-1]
1350				pending = pending[:len(pending)-1]
1351				startParseBlueprintsFile(next)
1352			}
1353			if activeCount == 0 {
1354				break loop
1355			}
1356		}
1357	}
1358
1359	sort.Strings(deps)
1360
1361	// wait for every visitor() to complete
1362	visitorWaitGroup.Wait()
1363
1364	return
1365}
1366
1367// MockFileSystem causes the Context to replace all reads with accesses to the provided map of
1368// filenames to contents stored as a byte slice.
1369func (c *Context) MockFileSystem(files map[string][]byte) {
1370	// look for a module list file
1371	_, ok := files[MockModuleListFile]
1372	if !ok {
1373		// no module list file specified; find every file named Blueprints
1374		pathsToParse := []string{}
1375		for candidate := range files {
1376			if filepath.Base(candidate) == "Android.bp" {
1377				pathsToParse = append(pathsToParse, candidate)
1378			}
1379		}
1380		if len(pathsToParse) < 1 {
1381			panic(fmt.Sprintf("No Blueprints files found in mock filesystem: %v\n", files))
1382		}
1383		// put the list of Blueprints files into a list file
1384		files[MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n"))
1385	}
1386	c.SetModuleListFile(MockModuleListFile)
1387
1388	// mock the filesystem
1389	c.fs = pathtools.MockFs(files)
1390}
1391
1392func (c *Context) SetFs(fs pathtools.FileSystem) {
1393	c.fs = fs
1394}
1395
1396// openAndParse opens and parses a single Blueprints file, and returns the results
1397func (c *Context) openAndParse(filename string, scope *parser.Scope, rootDir string,
1398	parent *fileParseContext) (file *parser.File,
1399	subBlueprints []fileParseContext, deps []string, errs []error) {
1400
1401	f, err := c.fs.Open(filename)
1402	if err != nil {
1403		// couldn't open the file; see if we can provide a clearer error than "could not open file"
1404		stats, statErr := c.fs.Lstat(filename)
1405		if statErr == nil {
1406			isSymlink := stats.Mode()&os.ModeSymlink != 0
1407			if isSymlink {
1408				err = fmt.Errorf("could not open symlink %v : %v", filename, err)
1409				target, readlinkErr := os.Readlink(filename)
1410				if readlinkErr == nil {
1411					_, targetStatsErr := c.fs.Lstat(target)
1412					if targetStatsErr != nil {
1413						err = fmt.Errorf("could not open symlink %v; its target (%v) cannot be opened", filename, target)
1414					}
1415				}
1416			} else {
1417				err = fmt.Errorf("%v exists but could not be opened: %v", filename, err)
1418			}
1419		}
1420		return nil, nil, nil, []error{err}
1421	}
1422
1423	func() {
1424		defer func() {
1425			err = f.Close()
1426			if err != nil {
1427				errs = append(errs, err)
1428			}
1429		}()
1430		file, subBlueprints, errs = c.parseOne(rootDir, filename, f, scope, parent)
1431	}()
1432
1433	if len(errs) > 0 {
1434		return nil, nil, nil, errs
1435	}
1436
1437	for _, b := range subBlueprints {
1438		deps = append(deps, b.fileName)
1439	}
1440
1441	return file, subBlueprints, deps, nil
1442}
1443
1444// parseOne parses a single Blueprints file from the given reader, creating Module
1445// objects for each of the module definitions encountered.  If the Blueprints
1446// file contains an assignment to the "subdirs" variable, then the
1447// subdirectories listed are searched for Blueprints files returned in the
1448// subBlueprints return value.  If the Blueprints file contains an assignment
1449// to the "build" variable, then the file listed are returned in the
1450// subBlueprints return value.
1451//
1452// rootDir specifies the path to the root directory of the source tree, while
1453// filename specifies the path to the Blueprints file.  These paths are used for
1454// error reporting and for determining the module's directory.
1455func (c *Context) parseOne(rootDir, filename string, reader io.Reader,
1456	scope *parser.Scope, parent *fileParseContext) (file *parser.File, subBlueprints []fileParseContext, errs []error) {
1457
1458	relBlueprintsFile, err := filepath.Rel(rootDir, filename)
1459	if err != nil {
1460		return nil, nil, []error{err}
1461	}
1462
1463	scope.Remove("subdirs")
1464	scope.Remove("optional_subdirs")
1465	scope.Remove("build")
1466	file, errs = parser.ParseAndEval(filename, reader, scope)
1467	if len(errs) > 0 {
1468		for i, err := range errs {
1469			if parseErr, ok := err.(*parser.ParseError); ok {
1470				err = &BlueprintError{
1471					Err: parseErr.Err,
1472					Pos: parseErr.Pos,
1473				}
1474				errs[i] = err
1475			}
1476		}
1477
1478		// If there were any parse errors don't bother trying to interpret the
1479		// result.
1480		return nil, nil, errs
1481	}
1482	file.Name = relBlueprintsFile
1483
1484	build, buildPos, err := getLocalStringListFromScope(scope, "build")
1485	if err != nil {
1486		errs = append(errs, err)
1487	}
1488	for _, buildEntry := range build {
1489		if strings.Contains(buildEntry, "/") {
1490			errs = append(errs, &BlueprintError{
1491				Err: fmt.Errorf("illegal value %v. The '/' character is not permitted", buildEntry),
1492				Pos: buildPos,
1493			})
1494		}
1495	}
1496
1497	if err != nil {
1498		errs = append(errs, err)
1499	}
1500
1501	var blueprints []string
1502
1503	newBlueprints, newErrs := c.findBuildBlueprints(filepath.Dir(filename), build, buildPos)
1504	blueprints = append(blueprints, newBlueprints...)
1505	errs = append(errs, newErrs...)
1506
1507	subBlueprintsAndScope := make([]fileParseContext, len(blueprints))
1508	for i, b := range blueprints {
1509		subBlueprintsAndScope[i] = fileParseContext{b, parser.NewScope(scope), parent, make(chan struct{})}
1510	}
1511	return file, subBlueprintsAndScope, errs
1512}
1513
1514func (c *Context) findBuildBlueprints(dir string, build []string,
1515	buildPos scanner.Position) ([]string, []error) {
1516
1517	var blueprints []string
1518	var errs []error
1519
1520	for _, file := range build {
1521		pattern := filepath.Join(dir, file)
1522		var matches []string
1523		var err error
1524
1525		matches, err = c.glob(pattern, nil)
1526
1527		if err != nil {
1528			errs = append(errs, &BlueprintError{
1529				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
1530				Pos: buildPos,
1531			})
1532			continue
1533		}
1534
1535		if len(matches) == 0 {
1536			errs = append(errs, &BlueprintError{
1537				Err: fmt.Errorf("%q: not found", pattern),
1538				Pos: buildPos,
1539			})
1540		}
1541
1542		for _, foundBlueprints := range matches {
1543			if strings.HasSuffix(foundBlueprints, "/") {
1544				errs = append(errs, &BlueprintError{
1545					Err: fmt.Errorf("%q: is a directory", foundBlueprints),
1546					Pos: buildPos,
1547				})
1548			}
1549			blueprints = append(blueprints, foundBlueprints)
1550		}
1551	}
1552
1553	return blueprints, errs
1554}
1555
1556func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos scanner.Position,
1557	subBlueprintsName string, optional bool) ([]string, []error) {
1558
1559	var blueprints []string
1560	var errs []error
1561
1562	for _, subdir := range subdirs {
1563		pattern := filepath.Join(dir, subdir, subBlueprintsName)
1564		var matches []string
1565		var err error
1566
1567		matches, err = c.glob(pattern, nil)
1568
1569		if err != nil {
1570			errs = append(errs, &BlueprintError{
1571				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
1572				Pos: subdirsPos,
1573			})
1574			continue
1575		}
1576
1577		if len(matches) == 0 && !optional {
1578			errs = append(errs, &BlueprintError{
1579				Err: fmt.Errorf("%q: not found", pattern),
1580				Pos: subdirsPos,
1581			})
1582		}
1583
1584		for _, subBlueprints := range matches {
1585			if strings.HasSuffix(subBlueprints, "/") {
1586				errs = append(errs, &BlueprintError{
1587					Err: fmt.Errorf("%q: is a directory", subBlueprints),
1588					Pos: subdirsPos,
1589				})
1590			}
1591			blueprints = append(blueprints, subBlueprints)
1592		}
1593	}
1594
1595	return blueprints, errs
1596}
1597
1598func getLocalStringListFromScope(scope *parser.Scope, v string) ([]string, scanner.Position, error) {
1599	if assignment, local := scope.Get(v); assignment == nil || !local {
1600		return nil, scanner.Position{}, nil
1601	} else {
1602		switch value := assignment.Value.Eval().(type) {
1603		case *parser.List:
1604			ret := make([]string, 0, len(value.Values))
1605
1606			for _, listValue := range value.Values {
1607				s, ok := listValue.(*parser.String)
1608				if !ok {
1609					// The parser should not produce this.
1610					panic("non-string value found in list")
1611				}
1612
1613				ret = append(ret, s.Value)
1614			}
1615
1616			return ret, assignment.EqualsPos, nil
1617		case *parser.Bool, *parser.String:
1618			return nil, scanner.Position{}, &BlueprintError{
1619				Err: fmt.Errorf("%q must be a list of strings", v),
1620				Pos: assignment.EqualsPos,
1621			}
1622		default:
1623			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type()))
1624		}
1625	}
1626}
1627
1628func getStringFromScope(scope *parser.Scope, v string) (string, scanner.Position, error) {
1629	if assignment, _ := scope.Get(v); assignment == nil {
1630		return "", scanner.Position{}, nil
1631	} else {
1632		switch value := assignment.Value.Eval().(type) {
1633		case *parser.String:
1634			return value.Value, assignment.EqualsPos, nil
1635		case *parser.Bool, *parser.List:
1636			return "", scanner.Position{}, &BlueprintError{
1637				Err: fmt.Errorf("%q must be a string", v),
1638				Pos: assignment.EqualsPos,
1639			}
1640		default:
1641			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type()))
1642		}
1643	}
1644}
1645
1646// Clones a build logic module by calling the factory method for its module type, and then cloning
1647// property values.  Any values stored in the module object that are not stored in properties
1648// structs will be lost.
1649func (c *Context) cloneLogicModule(origModule *moduleInfo) (Module, []interface{}) {
1650	newLogicModule, newProperties := origModule.factory()
1651
1652	if len(newProperties) != len(origModule.properties) {
1653		panic("mismatched properties array length in " + origModule.Name())
1654	}
1655
1656	for i := range newProperties {
1657		dst := reflect.ValueOf(newProperties[i])
1658		src := reflect.ValueOf(origModule.properties[i])
1659
1660		proptools.CopyProperties(dst, src)
1661	}
1662
1663	return newLogicModule, newProperties
1664}
1665
1666func newVariant(module *moduleInfo, mutatorName string, variationName string,
1667	local bool) variant {
1668
1669	newVariantName := module.variant.name
1670	if variationName != "" {
1671		if newVariantName == "" {
1672			newVariantName = variationName
1673		} else {
1674			newVariantName += "_" + variationName
1675		}
1676	}
1677
1678	newVariations := module.variant.variations.clone()
1679	if newVariations == nil {
1680		newVariations = make(variationMap)
1681	}
1682	newVariations[mutatorName] = variationName
1683
1684	newDependencyVariations := module.variant.dependencyVariations.clone()
1685	if !local {
1686		if newDependencyVariations == nil {
1687			newDependencyVariations = make(variationMap)
1688		}
1689		newDependencyVariations[mutatorName] = variationName
1690	}
1691
1692	return variant{newVariantName, newVariations, newDependencyVariations}
1693}
1694
1695func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
1696	depChooser depChooser, variationNames []string, local bool) (modulesOrAliases, []error) {
1697
1698	if len(variationNames) == 0 {
1699		panic(fmt.Errorf("mutator %q passed zero-length variation list for module %q",
1700			mutatorName, origModule.Name()))
1701	}
1702
1703	var newModules modulesOrAliases
1704
1705	var errs []error
1706
1707	for i, variationName := range variationNames {
1708		var newLogicModule Module
1709		var newProperties []interface{}
1710
1711		if i == 0 {
1712			// Reuse the existing module for the first new variant
1713			// This both saves creating a new module, and causes the insertion in c.moduleInfo below
1714			// with logicModule as the key to replace the original entry in c.moduleInfo
1715			newLogicModule, newProperties = origModule.logicModule, origModule.properties
1716		} else {
1717			newLogicModule, newProperties = c.cloneLogicModule(origModule)
1718		}
1719
1720		m := *origModule
1721		newModule := &m
1722		newModule.directDeps = append([]depInfo(nil), origModule.directDeps...)
1723		newModule.reverseDeps = nil
1724		newModule.forwardDeps = nil
1725		newModule.logicModule = newLogicModule
1726		newModule.variant = newVariant(origModule, mutatorName, variationName, local)
1727		newModule.properties = newProperties
1728		newModule.providers = append([]interface{}(nil), origModule.providers...)
1729
1730		newModules = append(newModules, newModule)
1731
1732		newErrs := c.convertDepsToVariation(newModule, depChooser)
1733		if len(newErrs) > 0 {
1734			errs = append(errs, newErrs...)
1735		}
1736	}
1737
1738	// Mark original variant as invalid.  Modules that depend on this module will still
1739	// depend on origModule, but we'll fix it when the mutator is called on them.
1740	origModule.logicModule = nil
1741	origModule.splitModules = newModules
1742
1743	atomic.AddUint32(&c.depsModified, 1)
1744
1745	return newModules, errs
1746}
1747
1748type depChooser func(source *moduleInfo, dep depInfo) (*moduleInfo, string)
1749
1750// This function is called for every dependency edge to determine which
1751// variation of the dependency is needed. Its inputs are the depending module,
1752// its variation, the dependency and the dependency tag.
1753type Transition func(source Module, sourceVariation string, dep Module, depTag DependencyTag) string
1754
1755func chooseDepByTransition(mutatorName string, transition Transition) depChooser {
1756	return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
1757		sourceVariation := source.variant.variations[mutatorName]
1758		depLogicModule := dep.module.logicModule
1759		if depLogicModule == nil {
1760			// This is really a lie because the original dependency before the split
1761			// went away when it was split. We choose an arbitrary split module
1762			// instead and hope that whatever information the transition wants from it
1763			// is the same as in the original one
1764			// TODO(lberki): this can be fixed by calling transition() once and saving
1765			// its results somewhere
1766			depLogicModule = dep.module.splitModules[0].moduleOrAliasTarget().logicModule
1767		}
1768
1769		desiredVariation := transition(source.logicModule, sourceVariation, depLogicModule, dep.tag)
1770		for _, m := range dep.module.splitModules {
1771			if m.moduleOrAliasVariant().variations[mutatorName] == desiredVariation {
1772				return m.moduleOrAliasTarget(), ""
1773			}
1774		}
1775
1776		return nil, desiredVariation
1777	}
1778}
1779
1780func chooseDep(candidates modulesOrAliases, mutatorName, variationName string, defaultVariationName *string) (*moduleInfo, string) {
1781	for _, m := range candidates {
1782		if m.moduleOrAliasVariant().variations[mutatorName] == variationName {
1783			return m.moduleOrAliasTarget(), ""
1784		}
1785	}
1786
1787	if defaultVariationName != nil {
1788		// give it a second chance; match with defaultVariationName
1789		for _, m := range candidates {
1790			if m.moduleOrAliasVariant().variations[mutatorName] == *defaultVariationName {
1791				return m.moduleOrAliasTarget(), ""
1792			}
1793		}
1794	}
1795
1796	return nil, variationName
1797}
1798
1799func chooseDepExplicit(mutatorName string,
1800	variationName string, defaultVariationName *string) depChooser {
1801	return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
1802		return chooseDep(dep.module.splitModules, mutatorName, variationName, defaultVariationName)
1803	}
1804}
1805
1806func chooseDepInherit(mutatorName string, defaultVariationName *string) depChooser {
1807	return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
1808		sourceVariation := source.variant.variations[mutatorName]
1809		return chooseDep(dep.module.splitModules, mutatorName, sourceVariation, defaultVariationName)
1810	}
1811}
1812
1813func (c *Context) convertDepsToVariation(module *moduleInfo, depChooser depChooser) (errs []error) {
1814	for i, dep := range module.directDeps {
1815		if dep.module.logicModule == nil {
1816			newDep, missingVariation := depChooser(module, dep)
1817			if newDep == nil {
1818				errs = append(errs, &BlueprintError{
1819					Err: fmt.Errorf("failed to find variation %q for module %q needed by %q",
1820						missingVariation, dep.module.Name(), module.Name()),
1821					Pos: module.pos,
1822				})
1823				continue
1824			}
1825			module.directDeps[i].module = newDep
1826		}
1827	}
1828
1829	return errs
1830}
1831
1832func (c *Context) prettyPrintVariant(variations variationMap) string {
1833	names := make([]string, 0, len(variations))
1834	for _, m := range c.variantMutatorNames {
1835		if v, ok := variations[m]; ok {
1836			names = append(names, m+":"+v)
1837		}
1838	}
1839
1840	return strings.Join(names, ",")
1841}
1842
1843func (c *Context) prettyPrintGroupVariants(group *moduleGroup) string {
1844	var variants []string
1845	for _, moduleOrAlias := range group.modules {
1846		if mod := moduleOrAlias.module(); mod != nil {
1847			variants = append(variants, c.prettyPrintVariant(mod.variant.variations))
1848		} else if alias := moduleOrAlias.alias(); alias != nil {
1849			variants = append(variants, c.prettyPrintVariant(alias.variant.variations)+
1850				" (alias to "+c.prettyPrintVariant(alias.target.variant.variations)+")")
1851		}
1852	}
1853	return strings.Join(variants, "\n  ")
1854}
1855
1856func newModule(factory ModuleFactory) *moduleInfo {
1857	logicModule, properties := factory()
1858
1859	return &moduleInfo{
1860		logicModule: logicModule,
1861		factory:     factory,
1862		properties:  properties,
1863	}
1864}
1865
1866func processModuleDef(moduleDef *parser.Module,
1867	relBlueprintsFile string, moduleFactories, scopedModuleFactories map[string]ModuleFactory, ignoreUnknownModuleTypes bool) (*moduleInfo, []error) {
1868
1869	factory, ok := moduleFactories[moduleDef.Type]
1870	if !ok && scopedModuleFactories != nil {
1871		factory, ok = scopedModuleFactories[moduleDef.Type]
1872	}
1873	if !ok {
1874		if ignoreUnknownModuleTypes {
1875			return nil, nil
1876		}
1877
1878		return nil, []error{
1879			&BlueprintError{
1880				Err: fmt.Errorf("unrecognized module type %q", moduleDef.Type),
1881				Pos: moduleDef.TypePos,
1882			},
1883		}
1884	}
1885
1886	module := newModule(factory)
1887	module.typeName = moduleDef.Type
1888
1889	module.relBlueprintsFile = relBlueprintsFile
1890
1891	propertyMap, errs := proptools.UnpackProperties(moduleDef.Properties, module.properties...)
1892	if len(errs) > 0 {
1893		for i, err := range errs {
1894			if unpackErr, ok := err.(*proptools.UnpackError); ok {
1895				err = &BlueprintError{
1896					Err: unpackErr.Err,
1897					Pos: unpackErr.Pos,
1898				}
1899				errs[i] = err
1900			}
1901		}
1902		return nil, errs
1903	}
1904
1905	module.pos = moduleDef.TypePos
1906	module.propertyPos = make(map[string]scanner.Position)
1907	for name, propertyDef := range propertyMap {
1908		module.propertyPos[name] = propertyDef.ColonPos
1909	}
1910
1911	return module, nil
1912}
1913
1914func (c *Context) addModule(module *moduleInfo) []error {
1915	name := module.logicModule.Name()
1916	if name == "" {
1917		return []error{
1918			&BlueprintError{
1919				Err: fmt.Errorf("property 'name' is missing from a module"),
1920				Pos: module.pos,
1921			},
1922		}
1923	}
1924	c.moduleInfo[module.logicModule] = module
1925
1926	group := &moduleGroup{
1927		name:    name,
1928		modules: modulesOrAliases{module},
1929	}
1930	module.group = group
1931	namespace, errs := c.nameInterface.NewModule(
1932		newNamespaceContext(module),
1933		ModuleGroup{moduleGroup: group},
1934		module.logicModule)
1935	if len(errs) > 0 {
1936		for i := range errs {
1937			errs[i] = &BlueprintError{Err: errs[i], Pos: module.pos}
1938		}
1939		return errs
1940	}
1941	group.namespace = namespace
1942
1943	c.moduleGroups = append(c.moduleGroups, group)
1944
1945	return nil
1946}
1947
1948// ResolveDependencies checks that the dependencies specified by all of the
1949// modules defined in the parsed Blueprints files are valid.  This means that
1950// the modules depended upon are defined and that no circular dependencies
1951// exist.
1952func (c *Context) ResolveDependencies(config interface{}) (deps []string, errs []error) {
1953	c.BeginEvent("resolve_deps")
1954	defer c.EndEvent("resolve_deps")
1955	return c.resolveDependencies(c.Context, config)
1956}
1957
1958func (c *Context) resolveDependencies(ctx context.Context, config interface{}) (deps []string, errs []error) {
1959	pprof.Do(ctx, pprof.Labels("blueprint", "ResolveDependencies"), func(ctx context.Context) {
1960		c.initProviders()
1961
1962		c.liveGlobals = newLiveTracker(c, config)
1963
1964		deps, errs = c.generateSingletonBuildActions(config, c.preSingletonInfo, c.liveGlobals)
1965		if len(errs) > 0 {
1966			return
1967		}
1968
1969		errs = c.updateDependencies()
1970		if len(errs) > 0 {
1971			return
1972		}
1973
1974		var mutatorDeps []string
1975		mutatorDeps, errs = c.runMutators(ctx, config)
1976		if len(errs) > 0 {
1977			return
1978		}
1979		deps = append(deps, mutatorDeps...)
1980
1981		if !c.skipCloneModulesAfterMutators {
1982			c.cloneModules()
1983		}
1984
1985		c.dependenciesReady = true
1986	})
1987
1988	if len(errs) > 0 {
1989		return nil, errs
1990	}
1991
1992	return deps, nil
1993}
1994
1995// Default dependencies handling.  If the module implements the (deprecated)
1996// DynamicDependerModule interface then this set consists of the union of those
1997// module names returned by its DynamicDependencies method and those added by calling
1998// AddDependencies or AddVariationDependencies on DynamicDependencyModuleContext.
1999func blueprintDepsMutator(ctx BottomUpMutatorContext) {
2000	if dynamicDepender, ok := ctx.Module().(DynamicDependerModule); ok {
2001		func() {
2002			defer func() {
2003				if r := recover(); r != nil {
2004					ctx.error(newPanicErrorf(r, "DynamicDependencies for %s", ctx.moduleInfo()))
2005				}
2006			}()
2007			dynamicDeps := dynamicDepender.DynamicDependencies(ctx)
2008
2009			if ctx.Failed() {
2010				return
2011			}
2012
2013			ctx.AddDependency(ctx.Module(), nil, dynamicDeps...)
2014		}()
2015	}
2016}
2017
2018// findExactVariantOrSingle searches the moduleGroup for a module with the same variant as module,
2019// and returns the matching module, or nil if one is not found.  A group with exactly one module
2020// is always considered matching.
2021func findExactVariantOrSingle(module *moduleInfo, possible *moduleGroup, reverse bool) *moduleInfo {
2022	found, _ := findVariant(module, possible, nil, false, reverse)
2023	if found == nil {
2024		for _, moduleOrAlias := range possible.modules {
2025			if m := moduleOrAlias.module(); m != nil {
2026				if found != nil {
2027					// more than one possible match, give up
2028					return nil
2029				}
2030				found = m
2031			}
2032		}
2033	}
2034	return found
2035}
2036
2037func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) (*moduleInfo, []error) {
2038	if _, ok := tag.(BaseDependencyTag); ok {
2039		panic("BaseDependencyTag is not allowed to be used directly!")
2040	}
2041
2042	if depName == module.Name() {
2043		return nil, []error{&BlueprintError{
2044			Err: fmt.Errorf("%q depends on itself", depName),
2045			Pos: module.pos,
2046		}}
2047	}
2048
2049	possibleDeps := c.moduleGroupFromName(depName, module.namespace())
2050	if possibleDeps == nil {
2051		return nil, c.discoveredMissingDependencies(module, depName, nil)
2052	}
2053
2054	if m := findExactVariantOrSingle(module, possibleDeps, false); m != nil {
2055		module.newDirectDeps = append(module.newDirectDeps, depInfo{m, tag})
2056		atomic.AddUint32(&c.depsModified, 1)
2057		return m, nil
2058	}
2059
2060	if c.allowMissingDependencies {
2061		// Allow missing variants.
2062		return nil, c.discoveredMissingDependencies(module, depName, module.variant.dependencyVariations)
2063	}
2064
2065	return nil, []error{&BlueprintError{
2066		Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
2067			depName, module.Name(),
2068			c.prettyPrintVariant(module.variant.dependencyVariations),
2069			c.prettyPrintGroupVariants(possibleDeps)),
2070		Pos: module.pos,
2071	}}
2072}
2073
2074func (c *Context) findReverseDependency(module *moduleInfo, destName string) (*moduleInfo, []error) {
2075	if destName == module.Name() {
2076		return nil, []error{&BlueprintError{
2077			Err: fmt.Errorf("%q depends on itself", destName),
2078			Pos: module.pos,
2079		}}
2080	}
2081
2082	possibleDeps := c.moduleGroupFromName(destName, module.namespace())
2083	if possibleDeps == nil {
2084		return nil, []error{&BlueprintError{
2085			Err: fmt.Errorf("%q has a reverse dependency on undefined module %q",
2086				module.Name(), destName),
2087			Pos: module.pos,
2088		}}
2089	}
2090
2091	if m := findExactVariantOrSingle(module, possibleDeps, true); m != nil {
2092		return m, nil
2093	}
2094
2095	if c.allowMissingDependencies {
2096		// Allow missing variants.
2097		return module, c.discoveredMissingDependencies(module, destName, module.variant.dependencyVariations)
2098	}
2099
2100	return nil, []error{&BlueprintError{
2101		Err: fmt.Errorf("reverse dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
2102			destName, module.Name(),
2103			c.prettyPrintVariant(module.variant.dependencyVariations),
2104			c.prettyPrintGroupVariants(possibleDeps)),
2105		Pos: module.pos,
2106	}}
2107}
2108
2109func findVariant(module *moduleInfo, possibleDeps *moduleGroup, variations []Variation, far bool, reverse bool) (*moduleInfo, variationMap) {
2110	// We can't just append variant.Variant to module.dependencyVariant.variantName and
2111	// compare the strings because the result won't be in mutator registration order.
2112	// Create a new map instead, and then deep compare the maps.
2113	var newVariant variationMap
2114	if !far {
2115		if !reverse {
2116			// For forward dependency, ignore local variants by matching against
2117			// dependencyVariant which doesn't have the local variants
2118			newVariant = module.variant.dependencyVariations.clone()
2119		} else {
2120			// For reverse dependency, use all the variants
2121			newVariant = module.variant.variations.clone()
2122		}
2123	}
2124	for _, v := range variations {
2125		if newVariant == nil {
2126			newVariant = make(variationMap)
2127		}
2128		newVariant[v.Mutator] = v.Variation
2129	}
2130
2131	check := func(variant variationMap) bool {
2132		if far {
2133			return newVariant.subsetOf(variant)
2134		} else {
2135			return variant.equal(newVariant)
2136		}
2137	}
2138
2139	var foundDep *moduleInfo
2140	for _, m := range possibleDeps.modules {
2141		if check(m.moduleOrAliasVariant().variations) {
2142			foundDep = m.moduleOrAliasTarget()
2143			break
2144		}
2145	}
2146
2147	return foundDep, newVariant
2148}
2149
2150func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
2151	tag DependencyTag, depName string, far bool) (*moduleInfo, []error) {
2152	if _, ok := tag.(BaseDependencyTag); ok {
2153		panic("BaseDependencyTag is not allowed to be used directly!")
2154	}
2155
2156	possibleDeps := c.moduleGroupFromName(depName, module.namespace())
2157	if possibleDeps == nil {
2158		return nil, c.discoveredMissingDependencies(module, depName, nil)
2159	}
2160
2161	foundDep, newVariant := findVariant(module, possibleDeps, variations, far, false)
2162
2163	if foundDep == nil {
2164		if c.allowMissingDependencies {
2165			// Allow missing variants.
2166			return nil, c.discoveredMissingDependencies(module, depName, newVariant)
2167		}
2168		return nil, []error{&BlueprintError{
2169			Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
2170				depName, module.Name(),
2171				c.prettyPrintVariant(newVariant),
2172				c.prettyPrintGroupVariants(possibleDeps)),
2173			Pos: module.pos,
2174		}}
2175	}
2176
2177	if module == foundDep {
2178		return nil, []error{&BlueprintError{
2179			Err: fmt.Errorf("%q depends on itself", depName),
2180			Pos: module.pos,
2181		}}
2182	}
2183	// AddVariationDependency allows adding a dependency on itself, but only if
2184	// that module is earlier in the module list than this one, since we always
2185	// run GenerateBuildActions in order for the variants of a module
2186	if foundDep.group == module.group && beforeInModuleList(module, foundDep, module.group.modules) {
2187		return nil, []error{&BlueprintError{
2188			Err: fmt.Errorf("%q depends on later version of itself", depName),
2189			Pos: module.pos,
2190		}}
2191	}
2192	module.newDirectDeps = append(module.newDirectDeps, depInfo{foundDep, tag})
2193	atomic.AddUint32(&c.depsModified, 1)
2194	return foundDep, nil
2195}
2196
2197func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag DependencyTag,
2198	from, to Module) *moduleInfo {
2199	if _, ok := tag.(BaseDependencyTag); ok {
2200		panic("BaseDependencyTag is not allowed to be used directly!")
2201	}
2202
2203	var fromInfo, toInfo *moduleInfo
2204	for _, moduleOrAlias := range origModule.splitModules {
2205		if m := moduleOrAlias.module(); m != nil {
2206			if m.logicModule == from {
2207				fromInfo = m
2208			}
2209			if m.logicModule == to {
2210				toInfo = m
2211				if fromInfo != nil {
2212					panic(fmt.Errorf("%q depends on later version of itself", origModule.Name()))
2213				}
2214			}
2215		}
2216	}
2217
2218	if fromInfo == nil || toInfo == nil {
2219		panic(fmt.Errorf("AddInterVariantDependency called for module %q on invalid variant",
2220			origModule.Name()))
2221	}
2222
2223	fromInfo.newDirectDeps = append(fromInfo.newDirectDeps, depInfo{toInfo, tag})
2224	atomic.AddUint32(&c.depsModified, 1)
2225	return toInfo
2226}
2227
2228// findBlueprintDescendants returns a map linking parent Blueprint files to child Blueprints files
2229// For example, if paths = []string{"a/b/c/Android.bp", "a/Android.bp"},
2230// then descendants = {"":[]string{"a/Android.bp"}, "a/Android.bp":[]string{"a/b/c/Android.bp"}}
2231func findBlueprintDescendants(paths []string) (descendants map[string][]string, err error) {
2232	// make mapping from dir path to file path
2233	filesByDir := make(map[string]string, len(paths))
2234	for _, path := range paths {
2235		dir := filepath.Dir(path)
2236		_, alreadyFound := filesByDir[dir]
2237		if alreadyFound {
2238			return nil, fmt.Errorf("Found two Blueprint files in directory %v : %v and %v", dir, filesByDir[dir], path)
2239		}
2240		filesByDir[dir] = path
2241	}
2242
2243	findAncestor := func(childFile string) (ancestor string) {
2244		prevAncestorDir := filepath.Dir(childFile)
2245		for {
2246			ancestorDir := filepath.Dir(prevAncestorDir)
2247			if ancestorDir == prevAncestorDir {
2248				// reached the root dir without any matches; assign this as a descendant of ""
2249				return ""
2250			}
2251
2252			ancestorFile, ancestorExists := filesByDir[ancestorDir]
2253			if ancestorExists {
2254				return ancestorFile
2255			}
2256			prevAncestorDir = ancestorDir
2257		}
2258	}
2259	// generate the descendants map
2260	descendants = make(map[string][]string, len(filesByDir))
2261	for _, childFile := range filesByDir {
2262		ancestorFile := findAncestor(childFile)
2263		descendants[ancestorFile] = append(descendants[ancestorFile], childFile)
2264	}
2265	return descendants, nil
2266}
2267
2268type visitOrderer interface {
2269	// returns the number of modules that this module needs to wait for
2270	waitCount(module *moduleInfo) int
2271	// returns the list of modules that are waiting for this module
2272	propagate(module *moduleInfo) []*moduleInfo
2273	// visit modules in order
2274	visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool)
2275}
2276
2277type unorderedVisitorImpl struct{}
2278
2279func (unorderedVisitorImpl) waitCount(module *moduleInfo) int {
2280	return 0
2281}
2282
2283func (unorderedVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
2284	return nil
2285}
2286
2287func (unorderedVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
2288	for _, module := range modules {
2289		if visit(module, nil) {
2290			return
2291		}
2292	}
2293}
2294
2295type bottomUpVisitorImpl struct{}
2296
2297func (bottomUpVisitorImpl) waitCount(module *moduleInfo) int {
2298	return len(module.forwardDeps)
2299}
2300
2301func (bottomUpVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
2302	return module.reverseDeps
2303}
2304
2305func (bottomUpVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
2306	for _, module := range modules {
2307		if visit(module, nil) {
2308			return
2309		}
2310	}
2311}
2312
2313type topDownVisitorImpl struct{}
2314
2315func (topDownVisitorImpl) waitCount(module *moduleInfo) int {
2316	return len(module.reverseDeps)
2317}
2318
2319func (topDownVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
2320	return module.forwardDeps
2321}
2322
2323func (topDownVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
2324	for i := 0; i < len(modules); i++ {
2325		module := modules[len(modules)-1-i]
2326		if visit(module, nil) {
2327			return
2328		}
2329	}
2330}
2331
2332var (
2333	bottomUpVisitor bottomUpVisitorImpl
2334	topDownVisitor  topDownVisitorImpl
2335)
2336
2337// pauseSpec describes a pause that a module needs to occur until another module has been visited,
2338// at which point the unpause channel will be closed.
2339type pauseSpec struct {
2340	paused  *moduleInfo
2341	until   *moduleInfo
2342	unpause unpause
2343}
2344
2345type unpause chan struct{}
2346
2347const parallelVisitLimit = 1000
2348
2349// Calls visit on each module, guaranteeing that visit is not called on a module until visit on all
2350// of its dependencies has finished.  A visit function can write a pauseSpec to the pause channel
2351// to wait for another dependency to be visited.  If a visit function returns true to cancel
2352// while another visitor is paused, the paused visitor will never be resumed and its goroutine
2353// will stay paused forever.
2354func parallelVisit(modules []*moduleInfo, order visitOrderer, limit int,
2355	visit func(module *moduleInfo, pause chan<- pauseSpec) bool) []error {
2356
2357	doneCh := make(chan *moduleInfo)
2358	cancelCh := make(chan bool)
2359	pauseCh := make(chan pauseSpec)
2360	cancel := false
2361
2362	var backlog []*moduleInfo      // Visitors that are ready to start but backlogged due to limit.
2363	var unpauseBacklog []pauseSpec // Visitors that are ready to unpause but backlogged due to limit.
2364
2365	active := 0  // Number of visitors running, not counting paused visitors.
2366	visited := 0 // Number of finished visitors.
2367
2368	pauseMap := make(map[*moduleInfo][]pauseSpec)
2369
2370	for _, module := range modules {
2371		module.waitingCount = order.waitCount(module)
2372	}
2373
2374	// Call the visitor on a module if there are fewer active visitors than the parallelism
2375	// limit, otherwise add it to the backlog.
2376	startOrBacklog := func(module *moduleInfo) {
2377		if active < limit {
2378			active++
2379			go func() {
2380				ret := visit(module, pauseCh)
2381				if ret {
2382					cancelCh <- true
2383				}
2384				doneCh <- module
2385			}()
2386		} else {
2387			backlog = append(backlog, module)
2388		}
2389	}
2390
2391	// Unpause the already-started but paused  visitor on a module if there are fewer active
2392	// visitors than the parallelism limit, otherwise add it to the backlog.
2393	unpauseOrBacklog := func(pauseSpec pauseSpec) {
2394		if active < limit {
2395			active++
2396			close(pauseSpec.unpause)
2397		} else {
2398			unpauseBacklog = append(unpauseBacklog, pauseSpec)
2399		}
2400	}
2401
2402	// Start any modules in the backlog up to the parallelism limit.  Unpause paused modules first
2403	// since they may already be holding resources.
2404	unpauseOrStartFromBacklog := func() {
2405		for active < limit && len(unpauseBacklog) > 0 {
2406			unpause := unpauseBacklog[0]
2407			unpauseBacklog = unpauseBacklog[1:]
2408			unpauseOrBacklog(unpause)
2409		}
2410		for active < limit && len(backlog) > 0 {
2411			toVisit := backlog[0]
2412			backlog = backlog[1:]
2413			startOrBacklog(toVisit)
2414		}
2415	}
2416
2417	toVisit := len(modules)
2418
2419	// Start or backlog any modules that are not waiting for any other modules.
2420	for _, module := range modules {
2421		if module.waitingCount == 0 {
2422			startOrBacklog(module)
2423		}
2424	}
2425
2426	for active > 0 {
2427		select {
2428		case <-cancelCh:
2429			cancel = true
2430			backlog = nil
2431		case doneModule := <-doneCh:
2432			active--
2433			if !cancel {
2434				// Mark this module as done.
2435				doneModule.waitingCount = -1
2436				visited++
2437
2438				// Unpause or backlog any modules that were waiting for this one.
2439				if unpauses, ok := pauseMap[doneModule]; ok {
2440					delete(pauseMap, doneModule)
2441					for _, unpause := range unpauses {
2442						unpauseOrBacklog(unpause)
2443					}
2444				}
2445
2446				// Start any backlogged modules up to limit.
2447				unpauseOrStartFromBacklog()
2448
2449				// Decrement waitingCount on the next modules in the tree based
2450				// on propagation order, and start or backlog them if they are
2451				// ready to start.
2452				for _, module := range order.propagate(doneModule) {
2453					module.waitingCount--
2454					if module.waitingCount == 0 {
2455						startOrBacklog(module)
2456					}
2457				}
2458			}
2459		case pauseSpec := <-pauseCh:
2460			if pauseSpec.until.waitingCount == -1 {
2461				// Module being paused for is already finished, resume immediately.
2462				close(pauseSpec.unpause)
2463			} else {
2464				// Register for unpausing.
2465				pauseMap[pauseSpec.until] = append(pauseMap[pauseSpec.until], pauseSpec)
2466
2467				// Don't count paused visitors as active so that this can't deadlock
2468				// if 1000 visitors are paused simultaneously.
2469				active--
2470				unpauseOrStartFromBacklog()
2471			}
2472		}
2473	}
2474
2475	if !cancel {
2476		// Invariant check: no backlogged modules, these weren't waiting on anything except
2477		// the parallelism limit so they should have run.
2478		if len(backlog) > 0 {
2479			panic(fmt.Errorf("parallelVisit finished with %d backlogged visitors", len(backlog)))
2480		}
2481
2482		// Invariant check: no backlogged paused modules, these weren't waiting on anything
2483		// except the parallelism limit so they should have run.
2484		if len(unpauseBacklog) > 0 {
2485			panic(fmt.Errorf("parallelVisit finished with %d backlogged unpaused visitors", len(unpauseBacklog)))
2486		}
2487
2488		if len(pauseMap) > 0 {
2489			// Probably a deadlock due to a newly added dependency cycle. Start from each module in
2490			// the order of the input modules list and perform a depth-first search for the module
2491			// it is paused on, ignoring modules that are marked as done.  Note this traverses from
2492			// modules to the modules that would have been unblocked when that module finished, i.e
2493			// the reverse of the visitOrderer.
2494
2495			// In order to reduce duplicated work, once a module has been checked and determined
2496			// not to be part of a cycle add it and everything that depends on it to the checked
2497			// map.
2498			checked := make(map[*moduleInfo]struct{})
2499
2500			var check func(module, end *moduleInfo) []*moduleInfo
2501			check = func(module, end *moduleInfo) []*moduleInfo {
2502				if module.waitingCount == -1 {
2503					// This module was finished, it can't be part of a loop.
2504					return nil
2505				}
2506				if module == end {
2507					// This module is the end of the loop, start rolling up the cycle.
2508					return []*moduleInfo{module}
2509				}
2510
2511				if _, alreadyChecked := checked[module]; alreadyChecked {
2512					return nil
2513				}
2514
2515				for _, dep := range order.propagate(module) {
2516					cycle := check(dep, end)
2517					if cycle != nil {
2518						return append([]*moduleInfo{module}, cycle...)
2519					}
2520				}
2521				for _, depPauseSpec := range pauseMap[module] {
2522					cycle := check(depPauseSpec.paused, end)
2523					if cycle != nil {
2524						return append([]*moduleInfo{module}, cycle...)
2525					}
2526				}
2527
2528				checked[module] = struct{}{}
2529				return nil
2530			}
2531
2532			// Iterate over the modules list instead of pauseMap to provide deterministic ordering.
2533			for _, module := range modules {
2534				for _, pauseSpec := range pauseMap[module] {
2535					cycle := check(pauseSpec.paused, pauseSpec.until)
2536					if len(cycle) > 0 {
2537						return cycleError(cycle)
2538					}
2539				}
2540			}
2541		}
2542
2543		// Invariant check: if there was no deadlock and no cancellation every module
2544		// should have been visited.
2545		if visited != toVisit {
2546			panic(fmt.Errorf("parallelVisit ran %d visitors, expected %d", visited, toVisit))
2547		}
2548
2549		// Invariant check: if there was no deadlock and no cancellation  every module
2550		// should have been visited, so there is nothing left to be paused on.
2551		if len(pauseMap) > 0 {
2552			panic(fmt.Errorf("parallelVisit finished with %d paused visitors", len(pauseMap)))
2553		}
2554	}
2555
2556	return nil
2557}
2558
2559func cycleError(cycle []*moduleInfo) (errs []error) {
2560	// The cycle list is in reverse order because all the 'check' calls append
2561	// their own module to the list.
2562	errs = append(errs, &BlueprintError{
2563		Err: fmt.Errorf("encountered dependency cycle:"),
2564		Pos: cycle[len(cycle)-1].pos,
2565	})
2566
2567	// Iterate backwards through the cycle list.
2568	curModule := cycle[0]
2569	for i := len(cycle) - 1; i >= 0; i-- {
2570		nextModule := cycle[i]
2571		errs = append(errs, &BlueprintError{
2572			Err: fmt.Errorf("    %s depends on %s",
2573				curModule, nextModule),
2574			Pos: curModule.pos,
2575		})
2576		curModule = nextModule
2577	}
2578
2579	return errs
2580}
2581
2582// updateDependencies recursively walks the module dependency graph and updates
2583// additional fields based on the dependencies.  It builds a sorted list of modules
2584// such that dependencies of a module always appear first, and populates reverse
2585// dependency links and counts of total dependencies.  It also reports errors when
2586// it encounters dependency cycles.  This should be called after resolveDependencies,
2587// as well as after any mutator pass has called addDependency
2588func (c *Context) updateDependencies() (errs []error) {
2589	c.cachedDepsModified = true
2590	visited := make(map[*moduleInfo]bool)  // modules that were already checked
2591	checking := make(map[*moduleInfo]bool) // modules actively being checked
2592
2593	sorted := make([]*moduleInfo, 0, len(c.moduleInfo))
2594
2595	var check func(group *moduleInfo) []*moduleInfo
2596
2597	check = func(module *moduleInfo) []*moduleInfo {
2598		visited[module] = true
2599		checking[module] = true
2600		defer delete(checking, module)
2601
2602		// Reset the forward and reverse deps without reducing their capacity to avoid reallocation.
2603		module.reverseDeps = module.reverseDeps[:0]
2604		module.forwardDeps = module.forwardDeps[:0]
2605
2606		// Add an implicit dependency ordering on all earlier modules in the same module group
2607		for _, dep := range module.group.modules {
2608			if dep == module {
2609				break
2610			}
2611			if depModule := dep.module(); depModule != nil {
2612				module.forwardDeps = append(module.forwardDeps, depModule)
2613			}
2614		}
2615
2616	outer:
2617		for _, dep := range module.directDeps {
2618			// use a loop to check for duplicates, average number of directDeps measured to be 9.5.
2619			for _, exists := range module.forwardDeps {
2620				if dep.module == exists {
2621					continue outer
2622				}
2623			}
2624			module.forwardDeps = append(module.forwardDeps, dep.module)
2625		}
2626
2627		for _, dep := range module.forwardDeps {
2628			if checking[dep] {
2629				// This is a cycle.
2630				return []*moduleInfo{dep, module}
2631			}
2632
2633			if !visited[dep] {
2634				cycle := check(dep)
2635				if cycle != nil {
2636					if cycle[0] == module {
2637						// We are the "start" of the cycle, so we're responsible
2638						// for generating the errors.
2639						errs = append(errs, cycleError(cycle)...)
2640
2641						// We can continue processing this module's children to
2642						// find more cycles.  Since all the modules that were
2643						// part of the found cycle were marked as visited we
2644						// won't run into that cycle again.
2645					} else {
2646						// We're not the "start" of the cycle, so we just append
2647						// our module to the list and return it.
2648						return append(cycle, module)
2649					}
2650				}
2651			}
2652
2653			dep.reverseDeps = append(dep.reverseDeps, module)
2654		}
2655
2656		sorted = append(sorted, module)
2657
2658		return nil
2659	}
2660
2661	for _, module := range c.moduleInfo {
2662		if !visited[module] {
2663			cycle := check(module)
2664			if cycle != nil {
2665				if cycle[len(cycle)-1] != module {
2666					panic("inconceivable!")
2667				}
2668				errs = append(errs, cycleError(cycle)...)
2669			}
2670		}
2671	}
2672
2673	c.modulesSorted = sorted
2674
2675	return
2676}
2677
2678type jsonVariations []Variation
2679
2680type jsonModuleName struct {
2681	Name                 string
2682	Variant              string
2683	Variations           jsonVariations
2684	DependencyVariations jsonVariations
2685}
2686
2687type jsonDep struct {
2688	jsonModuleName
2689	Tag string
2690}
2691
2692type JsonModule struct {
2693	jsonModuleName
2694	Deps      []jsonDep
2695	Type      string
2696	Blueprint string
2697	CreatedBy *string
2698	Module    map[string]interface{}
2699}
2700
2701func toJsonVariationMap(vm variationMap) jsonVariations {
2702	m := make(jsonVariations, 0, len(vm))
2703	for k, v := range vm {
2704		m = append(m, Variation{k, v})
2705	}
2706	sort.Slice(m, func(i, j int) bool {
2707		if m[i].Mutator != m[j].Mutator {
2708			return m[i].Mutator < m[j].Mutator
2709		}
2710		return m[i].Variation < m[j].Variation
2711	})
2712	return m
2713}
2714
2715func jsonModuleNameFromModuleInfo(m *moduleInfo) *jsonModuleName {
2716	return &jsonModuleName{
2717		Name:                 m.Name(),
2718		Variant:              m.variant.name,
2719		Variations:           toJsonVariationMap(m.variant.variations),
2720		DependencyVariations: toJsonVariationMap(m.variant.dependencyVariations),
2721	}
2722}
2723
2724type JSONDataSupplier interface {
2725	AddJSONData(d *map[string]interface{})
2726}
2727
2728// JSONAction contains the action-related info we expose to json module graph
2729type JSONAction struct {
2730	Inputs  []string
2731	Outputs []string
2732}
2733
2734// JSONActionSupplier allows JSON representation of additional actions that are not registered in
2735// Ninja
2736type JSONActionSupplier interface {
2737	JSONActions() []JSONAction
2738}
2739
2740func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule {
2741	result := &JsonModule{
2742		jsonModuleName: *jsonModuleNameFromModuleInfo(m),
2743		Deps:           make([]jsonDep, 0),
2744		Type:           m.typeName,
2745		Blueprint:      m.relBlueprintsFile,
2746		Module:         make(map[string]interface{}),
2747	}
2748	if m.createdBy != nil {
2749		n := m.createdBy.Name()
2750		result.CreatedBy = &n
2751	}
2752	if j, ok := m.logicModule.(JSONDataSupplier); ok {
2753		j.AddJSONData(&result.Module)
2754	}
2755	for _, p := range m.providers {
2756		if j, ok := p.(JSONDataSupplier); ok {
2757			j.AddJSONData(&result.Module)
2758		}
2759	}
2760	return result
2761}
2762
2763func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule {
2764	result := &JsonModule{
2765		jsonModuleName: jsonModuleName{
2766			Name:    m.Name(),
2767			Variant: m.variant.name,
2768		},
2769		Deps:      make([]jsonDep, 0),
2770		Type:      m.typeName,
2771		Blueprint: m.relBlueprintsFile,
2772		Module:    make(map[string]interface{}),
2773	}
2774	var actions []JSONAction
2775	for _, bDef := range m.actionDefs.buildDefs {
2776		actions = append(actions, JSONAction{
2777			Inputs: append(
2778				getNinjaStringsWithNilPkgNames(bDef.Inputs),
2779				getNinjaStringsWithNilPkgNames(bDef.Implicits)...),
2780			Outputs: append(
2781				getNinjaStringsWithNilPkgNames(bDef.Outputs),
2782				getNinjaStringsWithNilPkgNames(bDef.ImplicitOutputs)...),
2783		})
2784	}
2785
2786	if j, ok := m.logicModule.(JSONActionSupplier); ok {
2787		actions = append(actions, j.JSONActions()...)
2788	}
2789	for _, p := range m.providers {
2790		if j, ok := p.(JSONActionSupplier); ok {
2791			actions = append(actions, j.JSONActions()...)
2792		}
2793	}
2794
2795	result.Module["Actions"] = actions
2796	return result
2797}
2798
2799// Gets a list of strings from the given list of ninjaStrings by invoking ninjaString.Value with
2800// nil pkgNames on each of the input ninjaStrings.
2801func getNinjaStringsWithNilPkgNames(nStrs []ninjaString) []string {
2802	var strs []string
2803	for _, nstr := range nStrs {
2804		strs = append(strs, nstr.Value(nil))
2805	}
2806	return strs
2807}
2808
2809func (c *Context) GetOutputsFromModuleNames(moduleNames []string) map[string][]string {
2810	modulesToOutputs := make(map[string][]string)
2811	for _, m := range c.modulesSorted {
2812		if inList(m.Name(), moduleNames) {
2813			jmWithActions := jsonModuleWithActionsFromModuleInfo(m)
2814			for _, a := range jmWithActions.Module["Actions"].([]JSONAction) {
2815				modulesToOutputs[m.Name()] = append(modulesToOutputs[m.Name()], a.Outputs...)
2816			}
2817			// There could be several modules with the same name, so keep looping
2818		}
2819	}
2820
2821	return modulesToOutputs
2822}
2823
2824func inList(s string, l []string) bool {
2825	for _, element := range l {
2826		if s == element {
2827			return true
2828		}
2829	}
2830	return false
2831}
2832
2833// PrintJSONGraph prints info of modules in a JSON file.
2834func (c *Context) PrintJSONGraphAndActions(wGraph io.Writer, wActions io.Writer) {
2835	modulesToGraph := make([]*JsonModule, 0)
2836	modulesToActions := make([]*JsonModule, 0)
2837	for _, m := range c.modulesSorted {
2838		jm := jsonModuleFromModuleInfo(m)
2839		jmWithActions := jsonModuleWithActionsFromModuleInfo(m)
2840		for _, d := range m.directDeps {
2841			jm.Deps = append(jm.Deps, jsonDep{
2842				jsonModuleName: *jsonModuleNameFromModuleInfo(d.module),
2843				Tag:            fmt.Sprintf("%T %+v", d.tag, d.tag),
2844			})
2845			jmWithActions.Deps = append(jmWithActions.Deps, jsonDep{
2846				jsonModuleName: jsonModuleName{
2847					Name: d.module.Name(),
2848				},
2849			})
2850
2851		}
2852		modulesToGraph = append(modulesToGraph, jm)
2853		modulesToActions = append(modulesToActions, jmWithActions)
2854	}
2855	writeJson(wGraph, modulesToGraph)
2856	writeJson(wActions, modulesToActions)
2857}
2858
2859func writeJson(w io.Writer, modules []*JsonModule) {
2860	e := json.NewEncoder(w)
2861	e.SetIndent("", "\t")
2862	e.Encode(modules)
2863}
2864
2865// PrepareBuildActions generates an internal representation of all the build
2866// actions that need to be performed.  This process involves invoking the
2867// GenerateBuildActions method on each of the Module objects created during the
2868// parse phase and then on each of the registered Singleton objects.
2869//
2870// If the ResolveDependencies method has not already been called it is called
2871// automatically by this method.
2872//
2873// The config argument is made available to all of the Module and Singleton
2874// objects via the Config method on the ModuleContext and SingletonContext
2875// objects passed to GenerateBuildActions.  It is also passed to the functions
2876// specified via PoolFunc, RuleFunc, and VariableFunc so that they can compute
2877// config-specific values.
2878//
2879// The returned deps is a list of the ninja files dependencies that were added
2880// by the modules and singletons via the ModuleContext.AddNinjaFileDeps(),
2881// SingletonContext.AddNinjaFileDeps(), and PackageContext.AddNinjaFileDeps()
2882// methods.
2883
2884func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs []error) {
2885	c.BeginEvent("prepare_build_actions")
2886	defer c.EndEvent("prepare_build_actions")
2887	pprof.Do(c.Context, pprof.Labels("blueprint", "PrepareBuildActions"), func(ctx context.Context) {
2888		c.buildActionsReady = false
2889
2890		if !c.dependenciesReady {
2891			var extraDeps []string
2892			extraDeps, errs = c.resolveDependencies(ctx, config)
2893			if len(errs) > 0 {
2894				return
2895			}
2896			deps = append(deps, extraDeps...)
2897		}
2898
2899		var depsModules []string
2900		depsModules, errs = c.generateModuleBuildActions(config, c.liveGlobals)
2901		if len(errs) > 0 {
2902			return
2903		}
2904
2905		var depsSingletons []string
2906		depsSingletons, errs = c.generateSingletonBuildActions(config, c.singletonInfo, c.liveGlobals)
2907		if len(errs) > 0 {
2908			return
2909		}
2910
2911		deps = append(deps, depsModules...)
2912		deps = append(deps, depsSingletons...)
2913
2914		if c.outDir != nil {
2915			err := c.liveGlobals.addNinjaStringDeps(c.outDir)
2916			if err != nil {
2917				errs = []error{err}
2918				return
2919			}
2920		}
2921
2922		pkgNames, depsPackages := c.makeUniquePackageNames(c.liveGlobals)
2923
2924		deps = append(deps, depsPackages...)
2925
2926		c.memoizeFullNames(c.liveGlobals, pkgNames)
2927
2928		// This will panic if it finds a problem since it's a programming error.
2929		c.checkForVariableReferenceCycles(c.liveGlobals.variables, pkgNames)
2930
2931		c.pkgNames = pkgNames
2932		c.globalVariables = c.liveGlobals.variables
2933		c.globalPools = c.liveGlobals.pools
2934		c.globalRules = c.liveGlobals.rules
2935
2936		c.buildActionsReady = true
2937	})
2938
2939	if len(errs) > 0 {
2940		return nil, errs
2941	}
2942
2943	return deps, nil
2944}
2945
2946func (c *Context) runMutators(ctx context.Context, config interface{}) (deps []string, errs []error) {
2947	pprof.Do(ctx, pprof.Labels("blueprint", "runMutators"), func(ctx context.Context) {
2948		for _, mutator := range c.mutatorInfo {
2949			pprof.Do(ctx, pprof.Labels("mutator", mutator.name), func(context.Context) {
2950				c.BeginEvent(mutator.name)
2951				defer c.EndEvent(mutator.name)
2952				var newDeps []string
2953				if mutator.topDownMutator != nil {
2954					newDeps, errs = c.runMutator(config, mutator, topDownMutator)
2955				} else if mutator.bottomUpMutator != nil {
2956					newDeps, errs = c.runMutator(config, mutator, bottomUpMutator)
2957				} else {
2958					panic("no mutator set on " + mutator.name)
2959				}
2960				if len(errs) > 0 {
2961					return
2962				}
2963				deps = append(deps, newDeps...)
2964			})
2965			if len(errs) > 0 {
2966				return
2967			}
2968		}
2969	})
2970
2971	if len(errs) > 0 {
2972		return nil, errs
2973	}
2974
2975	return deps, nil
2976}
2977
2978type mutatorDirection interface {
2979	run(mutator *mutatorInfo, ctx *mutatorContext)
2980	orderer() visitOrderer
2981	fmt.Stringer
2982}
2983
2984type bottomUpMutatorImpl struct{}
2985
2986func (bottomUpMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
2987	mutator.bottomUpMutator(ctx)
2988}
2989
2990func (bottomUpMutatorImpl) orderer() visitOrderer {
2991	return bottomUpVisitor
2992}
2993
2994func (bottomUpMutatorImpl) String() string {
2995	return "bottom up mutator"
2996}
2997
2998type topDownMutatorImpl struct{}
2999
3000func (topDownMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
3001	mutator.topDownMutator(ctx)
3002}
3003
3004func (topDownMutatorImpl) orderer() visitOrderer {
3005	return topDownVisitor
3006}
3007
3008func (topDownMutatorImpl) String() string {
3009	return "top down mutator"
3010}
3011
3012var (
3013	topDownMutator  topDownMutatorImpl
3014	bottomUpMutator bottomUpMutatorImpl
3015)
3016
3017type reverseDep struct {
3018	module *moduleInfo
3019	dep    depInfo
3020}
3021
3022func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
3023	direction mutatorDirection) (deps []string, errs []error) {
3024
3025	newModuleInfo := make(map[Module]*moduleInfo)
3026	for k, v := range c.moduleInfo {
3027		newModuleInfo[k] = v
3028	}
3029
3030	type globalStateChange struct {
3031		reverse    []reverseDep
3032		rename     []rename
3033		replace    []replace
3034		newModules []*moduleInfo
3035		deps       []string
3036	}
3037
3038	reverseDeps := make(map[*moduleInfo][]depInfo)
3039	var rename []rename
3040	var replace []replace
3041	var newModules []*moduleInfo
3042
3043	errsCh := make(chan []error)
3044	globalStateCh := make(chan globalStateChange)
3045	newVariationsCh := make(chan modulesOrAliases)
3046	done := make(chan bool)
3047
3048	c.depsModified = 0
3049
3050	visit := func(module *moduleInfo, pause chan<- pauseSpec) bool {
3051		if module.splitModules != nil {
3052			panic("split module found in sorted module list")
3053		}
3054
3055		mctx := &mutatorContext{
3056			baseModuleContext: baseModuleContext{
3057				context: c,
3058				config:  config,
3059				module:  module,
3060			},
3061			name:    mutator.name,
3062			pauseCh: pause,
3063		}
3064
3065		module.startedMutator = mutator
3066
3067		func() {
3068			defer func() {
3069				if r := recover(); r != nil {
3070					in := fmt.Sprintf("%s %q for %s", direction, mutator.name, module)
3071					if err, ok := r.(panicError); ok {
3072						err.addIn(in)
3073						mctx.error(err)
3074					} else {
3075						mctx.error(newPanicErrorf(r, in))
3076					}
3077				}
3078			}()
3079			direction.run(mutator, mctx)
3080		}()
3081
3082		module.finishedMutator = mutator
3083
3084		if len(mctx.errs) > 0 {
3085			errsCh <- mctx.errs
3086			return true
3087		}
3088
3089		if len(mctx.newVariations) > 0 {
3090			newVariationsCh <- mctx.newVariations
3091		}
3092
3093		if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 || len(mctx.newModules) > 0 || len(mctx.ninjaFileDeps) > 0 {
3094			globalStateCh <- globalStateChange{
3095				reverse:    mctx.reverseDeps,
3096				replace:    mctx.replace,
3097				rename:     mctx.rename,
3098				newModules: mctx.newModules,
3099				deps:       mctx.ninjaFileDeps,
3100			}
3101		}
3102
3103		return false
3104	}
3105
3106	// Process errs and reverseDeps in a single goroutine
3107	go func() {
3108		for {
3109			select {
3110			case newErrs := <-errsCh:
3111				errs = append(errs, newErrs...)
3112			case globalStateChange := <-globalStateCh:
3113				for _, r := range globalStateChange.reverse {
3114					reverseDeps[r.module] = append(reverseDeps[r.module], r.dep)
3115				}
3116				replace = append(replace, globalStateChange.replace...)
3117				rename = append(rename, globalStateChange.rename...)
3118				newModules = append(newModules, globalStateChange.newModules...)
3119				deps = append(deps, globalStateChange.deps...)
3120			case newVariations := <-newVariationsCh:
3121				for _, moduleOrAlias := range newVariations {
3122					if m := moduleOrAlias.module(); m != nil {
3123						newModuleInfo[m.logicModule] = m
3124					}
3125				}
3126			case <-done:
3127				return
3128			}
3129		}
3130	}()
3131
3132	c.startedMutator = mutator
3133
3134	var visitErrs []error
3135	if mutator.parallel {
3136		visitErrs = parallelVisit(c.modulesSorted, direction.orderer(), parallelVisitLimit, visit)
3137	} else {
3138		direction.orderer().visit(c.modulesSorted, visit)
3139	}
3140
3141	if len(visitErrs) > 0 {
3142		return nil, visitErrs
3143	}
3144
3145	c.finishedMutators[mutator] = true
3146
3147	done <- true
3148
3149	if len(errs) > 0 {
3150		return nil, errs
3151	}
3152
3153	c.moduleInfo = newModuleInfo
3154
3155	for _, group := range c.moduleGroups {
3156		for i := 0; i < len(group.modules); i++ {
3157			module := group.modules[i].module()
3158			if module == nil {
3159				// Existing alias, skip it
3160				continue
3161			}
3162
3163			// Update module group to contain newly split variants
3164			if module.splitModules != nil {
3165				group.modules, i = spliceModules(group.modules, i, module.splitModules)
3166			}
3167
3168			// Fix up any remaining dependencies on modules that were split into variants
3169			// by replacing them with the first variant
3170			for j, dep := range module.directDeps {
3171				if dep.module.logicModule == nil {
3172					module.directDeps[j].module = dep.module.splitModules.firstModule()
3173				}
3174			}
3175
3176			if module.createdBy != nil && module.createdBy.logicModule == nil {
3177				module.createdBy = module.createdBy.splitModules.firstModule()
3178			}
3179
3180			// Add in any new direct dependencies that were added by the mutator
3181			module.directDeps = append(module.directDeps, module.newDirectDeps...)
3182			module.newDirectDeps = nil
3183		}
3184
3185		findAliasTarget := func(variant variant) *moduleInfo {
3186			for _, moduleOrAlias := range group.modules {
3187				if alias := moduleOrAlias.alias(); alias != nil {
3188					if alias.variant.variations.equal(variant.variations) {
3189						return alias.target
3190					}
3191				}
3192			}
3193			return nil
3194		}
3195
3196		// Forward or delete any dangling aliases.
3197		// Use a manual loop instead of range because len(group.modules) can
3198		// change inside the loop
3199		for i := 0; i < len(group.modules); i++ {
3200			if alias := group.modules[i].alias(); alias != nil {
3201				if alias.target.logicModule == nil {
3202					newTarget := findAliasTarget(alias.target.variant)
3203					if newTarget != nil {
3204						alias.target = newTarget
3205					} else {
3206						// The alias was left dangling, remove it.
3207						group.modules = append(group.modules[:i], group.modules[i+1:]...)
3208						i--
3209					}
3210				}
3211			}
3212		}
3213	}
3214
3215	// Add in any new reverse dependencies that were added by the mutator
3216	for module, deps := range reverseDeps {
3217		sort.Sort(depSorter(deps))
3218		module.directDeps = append(module.directDeps, deps...)
3219		c.depsModified++
3220	}
3221
3222	for _, module := range newModules {
3223		errs = c.addModule(module)
3224		if len(errs) > 0 {
3225			return nil, errs
3226		}
3227		atomic.AddUint32(&c.depsModified, 1)
3228	}
3229
3230	errs = c.handleRenames(rename)
3231	if len(errs) > 0 {
3232		return nil, errs
3233	}
3234
3235	errs = c.handleReplacements(replace)
3236	if len(errs) > 0 {
3237		return nil, errs
3238	}
3239
3240	if c.depsModified > 0 {
3241		errs = c.updateDependencies()
3242		if len(errs) > 0 {
3243			return nil, errs
3244		}
3245	}
3246
3247	return deps, errs
3248}
3249
3250// Replaces every build logic module with a clone of itself.  Prevents introducing problems where
3251// a mutator sets a non-property member variable on a module, which works until a later mutator
3252// creates variants of that module.
3253func (c *Context) cloneModules() {
3254	type update struct {
3255		orig  Module
3256		clone *moduleInfo
3257	}
3258	ch := make(chan update)
3259	doneCh := make(chan bool)
3260	go func() {
3261		errs := parallelVisit(c.modulesSorted, unorderedVisitorImpl{}, parallelVisitLimit,
3262			func(m *moduleInfo, pause chan<- pauseSpec) bool {
3263				origLogicModule := m.logicModule
3264				m.logicModule, m.properties = c.cloneLogicModule(m)
3265				ch <- update{origLogicModule, m}
3266				return false
3267			})
3268		if len(errs) > 0 {
3269			panic(errs)
3270		}
3271		doneCh <- true
3272	}()
3273
3274	done := false
3275	for !done {
3276		select {
3277		case <-doneCh:
3278			done = true
3279		case update := <-ch:
3280			delete(c.moduleInfo, update.orig)
3281			c.moduleInfo[update.clone.logicModule] = update.clone
3282		}
3283	}
3284}
3285
3286// Removes modules[i] from the list and inserts newModules... where it was located, returning
3287// the new slice and the index of the last inserted element
3288func spliceModules(modules modulesOrAliases, i int, newModules modulesOrAliases) (modulesOrAliases, int) {
3289	spliceSize := len(newModules)
3290	newLen := len(modules) + spliceSize - 1
3291	var dest modulesOrAliases
3292	if cap(modules) >= len(modules)-1+len(newModules) {
3293		// We can fit the splice in the existing capacity, do everything in place
3294		dest = modules[:newLen]
3295	} else {
3296		dest = make(modulesOrAliases, newLen)
3297		copy(dest, modules[:i])
3298	}
3299
3300	// Move the end of the slice over by spliceSize-1
3301	copy(dest[i+spliceSize:], modules[i+1:])
3302
3303	// Copy the new modules into the slice
3304	copy(dest[i:], newModules)
3305
3306	return dest, i + spliceSize - 1
3307}
3308
3309func (c *Context) generateModuleBuildActions(config interface{},
3310	liveGlobals *liveTracker) ([]string, []error) {
3311
3312	var deps []string
3313	var errs []error
3314
3315	cancelCh := make(chan struct{})
3316	errsCh := make(chan []error)
3317	depsCh := make(chan []string)
3318
3319	go func() {
3320		for {
3321			select {
3322			case <-cancelCh:
3323				close(cancelCh)
3324				return
3325			case newErrs := <-errsCh:
3326				errs = append(errs, newErrs...)
3327			case newDeps := <-depsCh:
3328				deps = append(deps, newDeps...)
3329
3330			}
3331		}
3332	}()
3333
3334	visitErrs := parallelVisit(c.modulesSorted, bottomUpVisitor, parallelVisitLimit,
3335		func(module *moduleInfo, pause chan<- pauseSpec) bool {
3336			uniqueName := c.nameInterface.UniqueName(newNamespaceContext(module), module.group.name)
3337			sanitizedName := toNinjaName(uniqueName)
3338			sanitizedVariant := toNinjaName(module.variant.name)
3339
3340			prefix := moduleNamespacePrefix(sanitizedName + "_" + sanitizedVariant)
3341
3342			// The parent scope of the moduleContext's local scope gets overridden to be that of the
3343			// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
3344			// just set it to nil.
3345			scope := newLocalScope(nil, prefix)
3346
3347			mctx := &moduleContext{
3348				baseModuleContext: baseModuleContext{
3349					context: c,
3350					config:  config,
3351					module:  module,
3352				},
3353				scope:              scope,
3354				handledMissingDeps: module.missingDeps == nil,
3355			}
3356
3357			mctx.module.startedGenerateBuildActions = true
3358
3359			func() {
3360				defer func() {
3361					if r := recover(); r != nil {
3362						in := fmt.Sprintf("GenerateBuildActions for %s", module)
3363						if err, ok := r.(panicError); ok {
3364							err.addIn(in)
3365							mctx.error(err)
3366						} else {
3367							mctx.error(newPanicErrorf(r, in))
3368						}
3369					}
3370				}()
3371				mctx.module.logicModule.GenerateBuildActions(mctx)
3372			}()
3373
3374			mctx.module.finishedGenerateBuildActions = true
3375
3376			if len(mctx.errs) > 0 {
3377				errsCh <- mctx.errs
3378				return true
3379			}
3380
3381			if module.missingDeps != nil && !mctx.handledMissingDeps {
3382				var errs []error
3383				for _, depName := range module.missingDeps {
3384					errs = append(errs, c.missingDependencyError(module, depName))
3385				}
3386				errsCh <- errs
3387				return true
3388			}
3389
3390			depsCh <- mctx.ninjaFileDeps
3391
3392			newErrs := c.processLocalBuildActions(&module.actionDefs,
3393				&mctx.actionDefs, liveGlobals)
3394			if len(newErrs) > 0 {
3395				errsCh <- newErrs
3396				return true
3397			}
3398			return false
3399		})
3400
3401	cancelCh <- struct{}{}
3402	<-cancelCh
3403
3404	errs = append(errs, visitErrs...)
3405
3406	return deps, errs
3407}
3408
3409func (c *Context) generateSingletonBuildActions(config interface{},
3410	singletons []*singletonInfo, liveGlobals *liveTracker) ([]string, []error) {
3411
3412	var deps []string
3413	var errs []error
3414
3415	for _, info := range singletons {
3416		// The parent scope of the singletonContext's local scope gets overridden to be that of the
3417		// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
3418		// just set it to nil.
3419		scope := newLocalScope(nil, singletonNamespacePrefix(info.name))
3420
3421		sctx := &singletonContext{
3422			name:    info.name,
3423			context: c,
3424			config:  config,
3425			scope:   scope,
3426			globals: liveGlobals,
3427		}
3428
3429		func() {
3430			defer func() {
3431				if r := recover(); r != nil {
3432					in := fmt.Sprintf("GenerateBuildActions for singleton %s", info.name)
3433					if err, ok := r.(panicError); ok {
3434						err.addIn(in)
3435						sctx.error(err)
3436					} else {
3437						sctx.error(newPanicErrorf(r, in))
3438					}
3439				}
3440			}()
3441			info.singleton.GenerateBuildActions(sctx)
3442		}()
3443
3444		if len(sctx.errs) > 0 {
3445			errs = append(errs, sctx.errs...)
3446			if len(errs) > maxErrors {
3447				break
3448			}
3449			continue
3450		}
3451
3452		deps = append(deps, sctx.ninjaFileDeps...)
3453
3454		newErrs := c.processLocalBuildActions(&info.actionDefs,
3455			&sctx.actionDefs, liveGlobals)
3456		errs = append(errs, newErrs...)
3457		if len(errs) > maxErrors {
3458			break
3459		}
3460	}
3461
3462	return deps, errs
3463}
3464
3465func (c *Context) processLocalBuildActions(out, in *localBuildActions,
3466	liveGlobals *liveTracker) []error {
3467
3468	var errs []error
3469
3470	// First we go through and add everything referenced by the module's
3471	// buildDefs to the live globals set.  This will end up adding the live
3472	// locals to the set as well, but we'll take them out after.
3473	for _, def := range in.buildDefs {
3474		err := liveGlobals.AddBuildDefDeps(def)
3475		if err != nil {
3476			errs = append(errs, err)
3477		}
3478	}
3479
3480	if len(errs) > 0 {
3481		return errs
3482	}
3483
3484	out.buildDefs = append(out.buildDefs, in.buildDefs...)
3485
3486	// We use the now-incorrect set of live "globals" to determine which local
3487	// definitions are live.  As we go through copying those live locals to the
3488	// moduleGroup we remove them from the live globals set.
3489	for _, v := range in.variables {
3490		isLive := liveGlobals.RemoveVariableIfLive(v)
3491		if isLive {
3492			out.variables = append(out.variables, v)
3493		}
3494	}
3495
3496	for _, r := range in.rules {
3497		isLive := liveGlobals.RemoveRuleIfLive(r)
3498		if isLive {
3499			out.rules = append(out.rules, r)
3500		}
3501	}
3502
3503	return nil
3504}
3505
3506func (c *Context) walkDeps(topModule *moduleInfo, allowDuplicates bool,
3507	visitDown func(depInfo, *moduleInfo) bool, visitUp func(depInfo, *moduleInfo)) {
3508
3509	visited := make(map[*moduleInfo]bool)
3510	var visiting *moduleInfo
3511
3512	defer func() {
3513		if r := recover(); r != nil {
3514			panic(newPanicErrorf(r, "WalkDeps(%s, %s, %s) for dependency %s",
3515				topModule, funcName(visitDown), funcName(visitUp), visiting))
3516		}
3517	}()
3518
3519	var walk func(module *moduleInfo)
3520	walk = func(module *moduleInfo) {
3521		for _, dep := range module.directDeps {
3522			if allowDuplicates || !visited[dep.module] {
3523				visiting = dep.module
3524				recurse := true
3525				if visitDown != nil {
3526					recurse = visitDown(dep, module)
3527				}
3528				if recurse && !visited[dep.module] {
3529					walk(dep.module)
3530					visited[dep.module] = true
3531				}
3532				if visitUp != nil {
3533					visitUp(dep, module)
3534				}
3535			}
3536		}
3537	}
3538
3539	walk(topModule)
3540}
3541
3542type replace struct {
3543	from, to  *moduleInfo
3544	predicate ReplaceDependencyPredicate
3545}
3546
3547type rename struct {
3548	group *moduleGroup
3549	name  string
3550}
3551
3552func (c *Context) moduleMatchingVariant(module *moduleInfo, name string) *moduleInfo {
3553	group := c.moduleGroupFromName(name, module.namespace())
3554
3555	if group == nil {
3556		return nil
3557	}
3558
3559	for _, m := range group.modules {
3560		if module.variant.name == m.moduleOrAliasVariant().name {
3561			return m.moduleOrAliasTarget()
3562		}
3563	}
3564
3565	return nil
3566}
3567
3568func (c *Context) handleRenames(renames []rename) []error {
3569	var errs []error
3570	for _, rename := range renames {
3571		group, name := rename.group, rename.name
3572		if name == group.name || len(group.modules) < 1 {
3573			continue
3574		}
3575
3576		errs = append(errs, c.nameInterface.Rename(group.name, rename.name, group.namespace)...)
3577	}
3578
3579	return errs
3580}
3581
3582func (c *Context) handleReplacements(replacements []replace) []error {
3583	var errs []error
3584	changedDeps := false
3585	for _, replace := range replacements {
3586		for _, m := range replace.from.reverseDeps {
3587			for i, d := range m.directDeps {
3588				if d.module == replace.from {
3589					// If the replacement has a predicate then check it.
3590					if replace.predicate == nil || replace.predicate(m.logicModule, d.tag, d.module.logicModule) {
3591						m.directDeps[i].module = replace.to
3592						changedDeps = true
3593					}
3594				}
3595			}
3596		}
3597
3598	}
3599
3600	if changedDeps {
3601		atomic.AddUint32(&c.depsModified, 1)
3602	}
3603	return errs
3604}
3605
3606func (c *Context) discoveredMissingDependencies(module *moduleInfo, depName string, depVariations variationMap) (errs []error) {
3607	if depVariations != nil {
3608		depName = depName + "{" + c.prettyPrintVariant(depVariations) + "}"
3609	}
3610	if c.allowMissingDependencies {
3611		module.missingDeps = append(module.missingDeps, depName)
3612		return nil
3613	}
3614	return []error{c.missingDependencyError(module, depName)}
3615}
3616
3617func (c *Context) missingDependencyError(module *moduleInfo, depName string) (errs error) {
3618	guess := namesLike(depName, module.Name(), c.moduleGroups)
3619	err := c.nameInterface.MissingDependencyError(module.Name(), module.namespace(), depName, guess)
3620	return &BlueprintError{
3621		Err: err,
3622		Pos: module.pos,
3623	}
3624}
3625
3626func (c *Context) moduleGroupFromName(name string, namespace Namespace) *moduleGroup {
3627	group, exists := c.nameInterface.ModuleFromName(name, namespace)
3628	if exists {
3629		return group.moduleGroup
3630	}
3631	return nil
3632}
3633
3634func (c *Context) sortedModuleGroups() []*moduleGroup {
3635	if c.cachedSortedModuleGroups == nil || c.cachedDepsModified {
3636		unwrap := func(wrappers []ModuleGroup) []*moduleGroup {
3637			result := make([]*moduleGroup, 0, len(wrappers))
3638			for _, group := range wrappers {
3639				result = append(result, group.moduleGroup)
3640			}
3641			return result
3642		}
3643
3644		c.cachedSortedModuleGroups = unwrap(c.nameInterface.AllModules())
3645		c.cachedDepsModified = false
3646	}
3647
3648	return c.cachedSortedModuleGroups
3649}
3650
3651func (c *Context) visitAllModules(visit func(Module)) {
3652	var module *moduleInfo
3653
3654	defer func() {
3655		if r := recover(); r != nil {
3656			panic(newPanicErrorf(r, "VisitAllModules(%s) for %s",
3657				funcName(visit), module))
3658		}
3659	}()
3660
3661	for _, moduleGroup := range c.sortedModuleGroups() {
3662		for _, moduleOrAlias := range moduleGroup.modules {
3663			if module = moduleOrAlias.module(); module != nil {
3664				visit(module.logicModule)
3665			}
3666		}
3667	}
3668}
3669
3670func (c *Context) visitAllModulesIf(pred func(Module) bool,
3671	visit func(Module)) {
3672
3673	var module *moduleInfo
3674
3675	defer func() {
3676		if r := recover(); r != nil {
3677			panic(newPanicErrorf(r, "VisitAllModulesIf(%s, %s) for %s",
3678				funcName(pred), funcName(visit), module))
3679		}
3680	}()
3681
3682	for _, moduleGroup := range c.sortedModuleGroups() {
3683		for _, moduleOrAlias := range moduleGroup.modules {
3684			if module = moduleOrAlias.module(); module != nil {
3685				if pred(module.logicModule) {
3686					visit(module.logicModule)
3687				}
3688			}
3689		}
3690	}
3691}
3692
3693func (c *Context) visitAllModuleVariants(module *moduleInfo,
3694	visit func(Module)) {
3695
3696	var variant *moduleInfo
3697
3698	defer func() {
3699		if r := recover(); r != nil {
3700			panic(newPanicErrorf(r, "VisitAllModuleVariants(%s, %s) for %s",
3701				module, funcName(visit), variant))
3702		}
3703	}()
3704
3705	for _, moduleOrAlias := range module.group.modules {
3706		if variant = moduleOrAlias.module(); variant != nil {
3707			visit(variant.logicModule)
3708		}
3709	}
3710}
3711
3712func (c *Context) requireNinjaVersion(major, minor, micro int) {
3713	if major != 1 {
3714		panic("ninja version with major version != 1 not supported")
3715	}
3716	if c.requiredNinjaMinor < minor {
3717		c.requiredNinjaMinor = minor
3718		c.requiredNinjaMicro = micro
3719	}
3720	if c.requiredNinjaMinor == minor && c.requiredNinjaMicro < micro {
3721		c.requiredNinjaMicro = micro
3722	}
3723}
3724
3725func (c *Context) setOutDir(value ninjaString) {
3726	if c.outDir == nil {
3727		c.outDir = value
3728	}
3729}
3730
3731func (c *Context) makeUniquePackageNames(
3732	liveGlobals *liveTracker) (map[*packageContext]string, []string) {
3733
3734	pkgs := make(map[string]*packageContext)
3735	pkgNames := make(map[*packageContext]string)
3736	longPkgNames := make(map[*packageContext]bool)
3737
3738	processPackage := func(pctx *packageContext) {
3739		if pctx == nil {
3740			// This is a built-in rule and has no package.
3741			return
3742		}
3743		if _, ok := pkgNames[pctx]; ok {
3744			// We've already processed this package.
3745			return
3746		}
3747
3748		otherPkg, present := pkgs[pctx.shortName]
3749		if present {
3750			// Short name collision.  Both this package and the one that's
3751			// already there need to use their full names.  We leave the short
3752			// name in pkgNames for now so future collisions still get caught.
3753			longPkgNames[pctx] = true
3754			longPkgNames[otherPkg] = true
3755		} else {
3756			// No collision so far.  Tentatively set the package's name to be
3757			// its short name.
3758			pkgNames[pctx] = pctx.shortName
3759			pkgs[pctx.shortName] = pctx
3760		}
3761	}
3762
3763	// We try to give all packages their short name, but when we get collisions
3764	// we need to use the full unique package name.
3765	for v, _ := range liveGlobals.variables {
3766		processPackage(v.packageContext())
3767	}
3768	for p, _ := range liveGlobals.pools {
3769		processPackage(p.packageContext())
3770	}
3771	for r, _ := range liveGlobals.rules {
3772		processPackage(r.packageContext())
3773	}
3774
3775	// Add the packages that had collisions using their full unique names.  This
3776	// will overwrite any short names that were added in the previous step.
3777	for pctx := range longPkgNames {
3778		pkgNames[pctx] = pctx.fullName
3779	}
3780
3781	// Create deps list from calls to PackageContext.AddNinjaFileDeps
3782	deps := []string{}
3783	for _, pkg := range pkgs {
3784		deps = append(deps, pkg.ninjaFileDeps...)
3785	}
3786
3787	return pkgNames, deps
3788}
3789
3790// memoizeFullNames stores the full name of each live global variable, rule and pool since each is
3791// guaranteed to be used at least twice, once in the definition and once for each usage, and many
3792// are used much more than once.
3793func (c *Context) memoizeFullNames(liveGlobals *liveTracker, pkgNames map[*packageContext]string) {
3794	for v := range liveGlobals.variables {
3795		v.memoizeFullName(pkgNames)
3796	}
3797	for r := range liveGlobals.rules {
3798		r.memoizeFullName(pkgNames)
3799	}
3800	for p := range liveGlobals.pools {
3801		p.memoizeFullName(pkgNames)
3802	}
3803}
3804
3805func (c *Context) checkForVariableReferenceCycles(
3806	variables map[Variable]ninjaString, pkgNames map[*packageContext]string) {
3807
3808	visited := make(map[Variable]bool)  // variables that were already checked
3809	checking := make(map[Variable]bool) // variables actively being checked
3810
3811	var check func(v Variable) []Variable
3812
3813	check = func(v Variable) []Variable {
3814		visited[v] = true
3815		checking[v] = true
3816		defer delete(checking, v)
3817
3818		value := variables[v]
3819		for _, dep := range value.Variables() {
3820			if checking[dep] {
3821				// This is a cycle.
3822				return []Variable{dep, v}
3823			}
3824
3825			if !visited[dep] {
3826				cycle := check(dep)
3827				if cycle != nil {
3828					if cycle[0] == v {
3829						// We are the "start" of the cycle, so we're responsible
3830						// for generating the errors.  The cycle list is in
3831						// reverse order because all the 'check' calls append
3832						// their own module to the list.
3833						msgs := []string{"detected variable reference cycle:"}
3834
3835						// Iterate backwards through the cycle list.
3836						curName := v.fullName(pkgNames)
3837						curValue := value.Value(pkgNames)
3838						for i := len(cycle) - 1; i >= 0; i-- {
3839							next := cycle[i]
3840							nextName := next.fullName(pkgNames)
3841							nextValue := variables[next].Value(pkgNames)
3842
3843							msgs = append(msgs, fmt.Sprintf(
3844								"    %q depends on %q", curName, nextName))
3845							msgs = append(msgs, fmt.Sprintf(
3846								"    [%s = %s]", curName, curValue))
3847
3848							curName = nextName
3849							curValue = nextValue
3850						}
3851
3852						// Variable reference cycles are a programming error,
3853						// not the fault of the Blueprint file authors.
3854						panic(strings.Join(msgs, "\n"))
3855					} else {
3856						// We're not the "start" of the cycle, so we just append
3857						// our module to the list and return it.
3858						return append(cycle, v)
3859					}
3860				}
3861			}
3862		}
3863
3864		return nil
3865	}
3866
3867	for v := range variables {
3868		if !visited[v] {
3869			cycle := check(v)
3870			if cycle != nil {
3871				panic("inconceivable!")
3872			}
3873		}
3874	}
3875}
3876
3877// AllTargets returns a map all the build target names to the rule used to build
3878// them.  This is the same information that is output by running 'ninja -t
3879// targets all'.  If this is called before PrepareBuildActions successfully
3880// completes then ErrbuildActionsNotReady is returned.
3881func (c *Context) AllTargets() (map[string]string, error) {
3882	if !c.buildActionsReady {
3883		return nil, ErrBuildActionsNotReady
3884	}
3885
3886	targets := map[string]string{}
3887	var collectTargets = func(actionDefs localBuildActions) error {
3888		for _, buildDef := range actionDefs.buildDefs {
3889			ruleName := buildDef.Rule.fullName(c.pkgNames)
3890			for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
3891				outputValue, err := output.Eval(c.globalVariables)
3892				if err != nil {
3893					return err
3894				}
3895				targets[outputValue] = ruleName
3896			}
3897		}
3898		return nil
3899	}
3900	// Collect all the module build targets.
3901	for _, module := range c.moduleInfo {
3902		if err := collectTargets(module.actionDefs); err != nil {
3903			return nil, err
3904		}
3905	}
3906
3907	// Collect all the singleton build targets.
3908	for _, info := range c.singletonInfo {
3909		if err := collectTargets(info.actionDefs); err != nil {
3910			return nil, err
3911		}
3912	}
3913
3914	return targets, nil
3915}
3916
3917func (c *Context) OutDir() (string, error) {
3918	if c.outDir != nil {
3919		return c.outDir.Eval(c.globalVariables)
3920	} else {
3921		return "", nil
3922	}
3923}
3924
3925// ModuleTypePropertyStructs returns a mapping from module type name to a list of pointers to
3926// property structs returned by the factory for that module type.
3927func (c *Context) ModuleTypePropertyStructs() map[string][]interface{} {
3928	ret := make(map[string][]interface{})
3929	for moduleType, factory := range c.moduleFactories {
3930		_, ret[moduleType] = factory()
3931	}
3932
3933	return ret
3934}
3935
3936func (c *Context) ModuleTypeFactories() map[string]ModuleFactory {
3937	ret := make(map[string]ModuleFactory)
3938	for k, v := range c.moduleFactories {
3939		ret[k] = v
3940	}
3941	return ret
3942}
3943
3944func (c *Context) ModuleName(logicModule Module) string {
3945	module := c.moduleInfo[logicModule]
3946	return module.Name()
3947}
3948
3949func (c *Context) ModuleDir(logicModule Module) string {
3950	return filepath.Dir(c.BlueprintFile(logicModule))
3951}
3952
3953func (c *Context) ModuleSubDir(logicModule Module) string {
3954	module := c.moduleInfo[logicModule]
3955	return module.variant.name
3956}
3957
3958func (c *Context) ModuleType(logicModule Module) string {
3959	module := c.moduleInfo[logicModule]
3960	return module.typeName
3961}
3962
3963// ModuleProvider returns the value, if any, for the provider for a module.  If the value for the
3964// provider was not set it returns the zero value of the type of the provider, which means the
3965// return value can always be type-asserted to the type of the provider.  The return value should
3966// always be considered read-only.  It panics if called before the appropriate mutator or
3967// GenerateBuildActions pass for the provider on the module.  The value returned may be a deep
3968// copy of the value originally passed to SetProvider.
3969func (c *Context) ModuleProvider(logicModule Module, provider ProviderKey) interface{} {
3970	module := c.moduleInfo[logicModule]
3971	value, _ := c.provider(module, provider)
3972	return value
3973}
3974
3975// ModuleHasProvider returns true if the provider for the given module has been set.
3976func (c *Context) ModuleHasProvider(logicModule Module, provider ProviderKey) bool {
3977	module := c.moduleInfo[logicModule]
3978	_, ok := c.provider(module, provider)
3979	return ok
3980}
3981
3982func (c *Context) BlueprintFile(logicModule Module) string {
3983	module := c.moduleInfo[logicModule]
3984	return module.relBlueprintsFile
3985}
3986
3987func (c *Context) ModuleErrorf(logicModule Module, format string,
3988	args ...interface{}) error {
3989
3990	module := c.moduleInfo[logicModule]
3991	return &BlueprintError{
3992		Err: fmt.Errorf(format, args...),
3993		Pos: module.pos,
3994	}
3995}
3996
3997func (c *Context) VisitAllModules(visit func(Module)) {
3998	c.visitAllModules(visit)
3999}
4000
4001func (c *Context) VisitAllModulesIf(pred func(Module) bool,
4002	visit func(Module)) {
4003
4004	c.visitAllModulesIf(pred, visit)
4005}
4006
4007func (c *Context) VisitDirectDeps(module Module, visit func(Module)) {
4008	topModule := c.moduleInfo[module]
4009
4010	var visiting *moduleInfo
4011
4012	defer func() {
4013		if r := recover(); r != nil {
4014			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
4015				topModule, funcName(visit), visiting))
4016		}
4017	}()
4018
4019	for _, dep := range topModule.directDeps {
4020		visiting = dep.module
4021		visit(dep.module.logicModule)
4022	}
4023}
4024
4025func (c *Context) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
4026	topModule := c.moduleInfo[module]
4027
4028	var visiting *moduleInfo
4029
4030	defer func() {
4031		if r := recover(); r != nil {
4032			panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s",
4033				topModule, funcName(pred), funcName(visit), visiting))
4034		}
4035	}()
4036
4037	for _, dep := range topModule.directDeps {
4038		visiting = dep.module
4039		if pred(dep.module.logicModule) {
4040			visit(dep.module.logicModule)
4041		}
4042	}
4043}
4044
4045func (c *Context) VisitDepsDepthFirst(module Module, visit func(Module)) {
4046	topModule := c.moduleInfo[module]
4047
4048	var visiting *moduleInfo
4049
4050	defer func() {
4051		if r := recover(); r != nil {
4052			panic(newPanicErrorf(r, "VisitDepsDepthFirst(%s, %s) for dependency %s",
4053				topModule, funcName(visit), visiting))
4054		}
4055	}()
4056
4057	c.walkDeps(topModule, false, nil, func(dep depInfo, parent *moduleInfo) {
4058		visiting = dep.module
4059		visit(dep.module.logicModule)
4060	})
4061}
4062
4063func (c *Context) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
4064	topModule := c.moduleInfo[module]
4065
4066	var visiting *moduleInfo
4067
4068	defer func() {
4069		if r := recover(); r != nil {
4070			panic(newPanicErrorf(r, "VisitDepsDepthFirstIf(%s, %s, %s) for dependency %s",
4071				topModule, funcName(pred), funcName(visit), visiting))
4072		}
4073	}()
4074
4075	c.walkDeps(topModule, false, nil, func(dep depInfo, parent *moduleInfo) {
4076		if pred(dep.module.logicModule) {
4077			visiting = dep.module
4078			visit(dep.module.logicModule)
4079		}
4080	})
4081}
4082
4083func (c *Context) PrimaryModule(module Module) Module {
4084	return c.moduleInfo[module].group.modules.firstModule().logicModule
4085}
4086
4087func (c *Context) FinalModule(module Module) Module {
4088	return c.moduleInfo[module].group.modules.lastModule().logicModule
4089}
4090
4091func (c *Context) VisitAllModuleVariants(module Module,
4092	visit func(Module)) {
4093
4094	c.visitAllModuleVariants(c.moduleInfo[module], visit)
4095}
4096
4097// Singletons returns a list of all registered Singletons.
4098func (c *Context) Singletons() []Singleton {
4099	var ret []Singleton
4100	for _, s := range c.singletonInfo {
4101		ret = append(ret, s.singleton)
4102	}
4103	return ret
4104}
4105
4106// SingletonName returns the name that the given singleton was registered with.
4107func (c *Context) SingletonName(singleton Singleton) string {
4108	for _, s := range c.singletonInfo {
4109		if s.singleton == singleton {
4110			return s.name
4111		}
4112	}
4113	return ""
4114}
4115
4116// WriteBuildFile writes the Ninja manifest text for the generated build
4117// actions to w.  If this is called before PrepareBuildActions successfully
4118// completes then ErrBuildActionsNotReady is returned.
4119func (c *Context) WriteBuildFile(w io.StringWriter) error {
4120	var err error
4121	pprof.Do(c.Context, pprof.Labels("blueprint", "WriteBuildFile"), func(ctx context.Context) {
4122		if !c.buildActionsReady {
4123			err = ErrBuildActionsNotReady
4124			return
4125		}
4126
4127		nw := newNinjaWriter(w)
4128
4129		if err = c.writeBuildFileHeader(nw); err != nil {
4130			return
4131		}
4132
4133		if err = c.writeNinjaRequiredVersion(nw); err != nil {
4134			return
4135		}
4136
4137		if err = c.writeSubninjas(nw); err != nil {
4138			return
4139		}
4140
4141		// TODO: Group the globals by package.
4142
4143		if err = c.writeGlobalVariables(nw); err != nil {
4144			return
4145		}
4146
4147		if err = c.writeGlobalPools(nw); err != nil {
4148			return
4149		}
4150
4151		if err = c.writeBuildDir(nw); err != nil {
4152			return
4153		}
4154
4155		if err = c.writeGlobalRules(nw); err != nil {
4156			return
4157		}
4158
4159		if err = c.writeAllModuleActions(nw); err != nil {
4160			return
4161		}
4162
4163		if err = c.writeAllSingletonActions(nw); err != nil {
4164			return
4165		}
4166	})
4167
4168	return err
4169}
4170
4171type pkgAssociation struct {
4172	PkgName string
4173	PkgPath string
4174}
4175
4176type pkgAssociationSorter struct {
4177	pkgs []pkgAssociation
4178}
4179
4180func (s *pkgAssociationSorter) Len() int {
4181	return len(s.pkgs)
4182}
4183
4184func (s *pkgAssociationSorter) Less(i, j int) bool {
4185	iName := s.pkgs[i].PkgName
4186	jName := s.pkgs[j].PkgName
4187	return iName < jName
4188}
4189
4190func (s *pkgAssociationSorter) Swap(i, j int) {
4191	s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
4192}
4193
4194func (c *Context) writeBuildFileHeader(nw *ninjaWriter) error {
4195	headerTemplate := template.New("fileHeader")
4196	_, err := headerTemplate.Parse(fileHeaderTemplate)
4197	if err != nil {
4198		// This is a programming error.
4199		panic(err)
4200	}
4201
4202	var pkgs []pkgAssociation
4203	maxNameLen := 0
4204	for pkg, name := range c.pkgNames {
4205		pkgs = append(pkgs, pkgAssociation{
4206			PkgName: name,
4207			PkgPath: pkg.pkgPath,
4208		})
4209		if len(name) > maxNameLen {
4210			maxNameLen = len(name)
4211		}
4212	}
4213
4214	for i := range pkgs {
4215		pkgs[i].PkgName += strings.Repeat(" ", maxNameLen-len(pkgs[i].PkgName))
4216	}
4217
4218	sort.Sort(&pkgAssociationSorter{pkgs})
4219
4220	params := map[string]interface{}{
4221		"Pkgs": pkgs,
4222	}
4223
4224	buf := bytes.NewBuffer(nil)
4225	err = headerTemplate.Execute(buf, params)
4226	if err != nil {
4227		return err
4228	}
4229
4230	return nw.Comment(buf.String())
4231}
4232
4233func (c *Context) writeNinjaRequiredVersion(nw *ninjaWriter) error {
4234	value := fmt.Sprintf("%d.%d.%d", c.requiredNinjaMajor, c.requiredNinjaMinor,
4235		c.requiredNinjaMicro)
4236
4237	err := nw.Assign("ninja_required_version", value)
4238	if err != nil {
4239		return err
4240	}
4241
4242	return nw.BlankLine()
4243}
4244
4245func (c *Context) writeSubninjas(nw *ninjaWriter) error {
4246	for _, subninja := range c.subninjas {
4247		err := nw.Subninja(subninja)
4248		if err != nil {
4249			return err
4250		}
4251	}
4252	return nw.BlankLine()
4253}
4254
4255func (c *Context) writeBuildDir(nw *ninjaWriter) error {
4256	if c.outDir != nil {
4257		err := nw.Assign("builddir", c.outDir.Value(c.pkgNames))
4258		if err != nil {
4259			return err
4260		}
4261
4262		err = nw.BlankLine()
4263		if err != nil {
4264			return err
4265		}
4266	}
4267	return nil
4268}
4269
4270type globalEntity interface {
4271	fullName(pkgNames map[*packageContext]string) string
4272}
4273
4274type globalEntitySorter struct {
4275	pkgNames map[*packageContext]string
4276	entities []globalEntity
4277}
4278
4279func (s *globalEntitySorter) Len() int {
4280	return len(s.entities)
4281}
4282
4283func (s *globalEntitySorter) Less(i, j int) bool {
4284	iName := s.entities[i].fullName(s.pkgNames)
4285	jName := s.entities[j].fullName(s.pkgNames)
4286	return iName < jName
4287}
4288
4289func (s *globalEntitySorter) Swap(i, j int) {
4290	s.entities[i], s.entities[j] = s.entities[j], s.entities[i]
4291}
4292
4293func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
4294	visited := make(map[Variable]bool)
4295
4296	var walk func(v Variable) error
4297	walk = func(v Variable) error {
4298		visited[v] = true
4299
4300		// First visit variables on which this variable depends.
4301		value := c.globalVariables[v]
4302		for _, dep := range value.Variables() {
4303			if !visited[dep] {
4304				err := walk(dep)
4305				if err != nil {
4306					return err
4307				}
4308			}
4309		}
4310
4311		err := nw.Assign(v.fullName(c.pkgNames), value.Value(c.pkgNames))
4312		if err != nil {
4313			return err
4314		}
4315
4316		err = nw.BlankLine()
4317		if err != nil {
4318			return err
4319		}
4320
4321		return nil
4322	}
4323
4324	globalVariables := make([]globalEntity, 0, len(c.globalVariables))
4325	for variable := range c.globalVariables {
4326		globalVariables = append(globalVariables, variable)
4327	}
4328
4329	sort.Sort(&globalEntitySorter{c.pkgNames, globalVariables})
4330
4331	for _, entity := range globalVariables {
4332		v := entity.(Variable)
4333		if !visited[v] {
4334			err := walk(v)
4335			if err != nil {
4336				return nil
4337			}
4338		}
4339	}
4340
4341	return nil
4342}
4343
4344func (c *Context) writeGlobalPools(nw *ninjaWriter) error {
4345	globalPools := make([]globalEntity, 0, len(c.globalPools))
4346	for pool := range c.globalPools {
4347		globalPools = append(globalPools, pool)
4348	}
4349
4350	sort.Sort(&globalEntitySorter{c.pkgNames, globalPools})
4351
4352	for _, entity := range globalPools {
4353		pool := entity.(Pool)
4354		name := pool.fullName(c.pkgNames)
4355		def := c.globalPools[pool]
4356		err := def.WriteTo(nw, name)
4357		if err != nil {
4358			return err
4359		}
4360
4361		err = nw.BlankLine()
4362		if err != nil {
4363			return err
4364		}
4365	}
4366
4367	return nil
4368}
4369
4370func (c *Context) writeGlobalRules(nw *ninjaWriter) error {
4371	globalRules := make([]globalEntity, 0, len(c.globalRules))
4372	for rule := range c.globalRules {
4373		globalRules = append(globalRules, rule)
4374	}
4375
4376	sort.Sort(&globalEntitySorter{c.pkgNames, globalRules})
4377
4378	for _, entity := range globalRules {
4379		rule := entity.(Rule)
4380		name := rule.fullName(c.pkgNames)
4381		def := c.globalRules[rule]
4382		err := def.WriteTo(nw, name, c.pkgNames)
4383		if err != nil {
4384			return err
4385		}
4386
4387		err = nw.BlankLine()
4388		if err != nil {
4389			return err
4390		}
4391	}
4392
4393	return nil
4394}
4395
4396type depSorter []depInfo
4397
4398func (s depSorter) Len() int {
4399	return len(s)
4400}
4401
4402func (s depSorter) Less(i, j int) bool {
4403	iName := s[i].module.Name()
4404	jName := s[j].module.Name()
4405	if iName == jName {
4406		iName = s[i].module.variant.name
4407		jName = s[j].module.variant.name
4408	}
4409	return iName < jName
4410}
4411
4412func (s depSorter) Swap(i, j int) {
4413	s[i], s[j] = s[j], s[i]
4414}
4415
4416type moduleSorter struct {
4417	modules       []*moduleInfo
4418	nameInterface NameInterface
4419}
4420
4421func (s moduleSorter) Len() int {
4422	return len(s.modules)
4423}
4424
4425func (s moduleSorter) Less(i, j int) bool {
4426	iMod := s.modules[i]
4427	jMod := s.modules[j]
4428	iName := s.nameInterface.UniqueName(newNamespaceContext(iMod), iMod.group.name)
4429	jName := s.nameInterface.UniqueName(newNamespaceContext(jMod), jMod.group.name)
4430	if iName == jName {
4431		iVariantName := s.modules[i].variant.name
4432		jVariantName := s.modules[j].variant.name
4433		if iVariantName == jVariantName {
4434			panic(fmt.Sprintf("duplicate module name: %s %s: %#v and %#v\n",
4435				iName, iVariantName, iMod.variant.variations, jMod.variant.variations))
4436		} else {
4437			return iVariantName < jVariantName
4438		}
4439	} else {
4440		return iName < jName
4441	}
4442}
4443
4444func (s moduleSorter) Swap(i, j int) {
4445	s.modules[i], s.modules[j] = s.modules[j], s.modules[i]
4446}
4447
4448func (c *Context) writeAllModuleActions(nw *ninjaWriter) error {
4449	c.BeginEvent("modules")
4450	defer c.EndEvent("modules")
4451	headerTemplate := template.New("moduleHeader")
4452	if _, err := headerTemplate.Parse(moduleHeaderTemplate); err != nil {
4453		// This is a programming error.
4454		panic(err)
4455	}
4456
4457	modules := make([]*moduleInfo, 0, len(c.moduleInfo))
4458	for _, module := range c.moduleInfo {
4459		modules = append(modules, module)
4460	}
4461	sort.Sort(moduleSorter{modules, c.nameInterface})
4462
4463	phonys := c.deduplicateOrderOnlyDeps(modules)
4464	if err := c.writeLocalBuildActions(nw, phonys); err != nil {
4465		return err
4466	}
4467
4468	buf := bytes.NewBuffer(nil)
4469
4470	for _, module := range modules {
4471		if len(module.actionDefs.variables)+len(module.actionDefs.rules)+len(module.actionDefs.buildDefs) == 0 {
4472			continue
4473		}
4474
4475		buf.Reset()
4476
4477		// In order to make the bootstrap build manifest independent of the
4478		// build dir we need to output the Blueprints file locations in the
4479		// comments as paths relative to the source directory.
4480		relPos := module.pos
4481		relPos.Filename = module.relBlueprintsFile
4482
4483		// Get the name and location of the factory function for the module.
4484		factoryFunc := runtime.FuncForPC(reflect.ValueOf(module.factory).Pointer())
4485		factoryName := factoryFunc.Name()
4486
4487		infoMap := map[string]interface{}{
4488			"name":      module.Name(),
4489			"typeName":  module.typeName,
4490			"goFactory": factoryName,
4491			"pos":       relPos,
4492			"variant":   module.variant.name,
4493		}
4494		if err := headerTemplate.Execute(buf, infoMap); err != nil {
4495			return err
4496		}
4497
4498		if err := nw.Comment(buf.String()); err != nil {
4499			return err
4500		}
4501
4502		if err := nw.BlankLine(); err != nil {
4503			return err
4504		}
4505
4506		if err := c.writeLocalBuildActions(nw, &module.actionDefs); err != nil {
4507			return err
4508		}
4509
4510		if err := nw.BlankLine(); err != nil {
4511			return err
4512		}
4513	}
4514
4515	return nil
4516}
4517
4518func (c *Context) writeAllSingletonActions(nw *ninjaWriter) error {
4519	c.BeginEvent("singletons")
4520	defer c.EndEvent("singletons")
4521	headerTemplate := template.New("singletonHeader")
4522	_, err := headerTemplate.Parse(singletonHeaderTemplate)
4523	if err != nil {
4524		// This is a programming error.
4525		panic(err)
4526	}
4527
4528	buf := bytes.NewBuffer(nil)
4529
4530	for _, info := range c.singletonInfo {
4531		if len(info.actionDefs.variables)+len(info.actionDefs.rules)+len(info.actionDefs.buildDefs) == 0 {
4532			continue
4533		}
4534
4535		// Get the name of the factory function for the module.
4536		factory := info.factory
4537		factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer())
4538		factoryName := factoryFunc.Name()
4539
4540		buf.Reset()
4541		infoMap := map[string]interface{}{
4542			"name":      info.name,
4543			"goFactory": factoryName,
4544		}
4545		err = headerTemplate.Execute(buf, infoMap)
4546		if err != nil {
4547			return err
4548		}
4549
4550		err = nw.Comment(buf.String())
4551		if err != nil {
4552			return err
4553		}
4554
4555		err = nw.BlankLine()
4556		if err != nil {
4557			return err
4558		}
4559
4560		err = c.writeLocalBuildActions(nw, &info.actionDefs)
4561		if err != nil {
4562			return err
4563		}
4564
4565		err = nw.BlankLine()
4566		if err != nil {
4567			return err
4568		}
4569	}
4570
4571	return nil
4572}
4573
4574func (c *Context) GetEventHandler() *metrics.EventHandler {
4575	return c.EventHandler
4576}
4577
4578func (c *Context) BeginEvent(name string) {
4579	c.EventHandler.Begin(name)
4580}
4581
4582func (c *Context) EndEvent(name string) {
4583	c.EventHandler.End(name)
4584}
4585
4586func (c *Context) SetBeforePrepareBuildActionsHook(hookFn func() error) {
4587	c.BeforePrepareBuildActionsHook = hookFn
4588}
4589
4590// phonyCandidate represents the state of a set of deps that decides its eligibility
4591// to be extracted as a phony output
4592type phonyCandidate struct {
4593	sync.Once
4594	phony *buildDef // the phony buildDef that wraps the set
4595	first *buildDef // the first buildDef that uses this set
4596}
4597
4598// keyForPhonyCandidate gives a unique identifier for a set of deps.
4599// If any of the deps use a variable, we return an empty string to signal
4600// that this set of deps is ineligible for extraction.
4601func keyForPhonyCandidate(deps []ninjaString) string {
4602	hasher := sha256.New()
4603	for _, d := range deps {
4604		if len(d.Variables()) != 0 {
4605			return ""
4606		}
4607		io.WriteString(hasher, d.Value(nil))
4608	}
4609	return base64.RawURLEncoding.EncodeToString(hasher.Sum(nil))
4610}
4611
4612// scanBuildDef is called for every known buildDef `b` that has a non-empty `b.OrderOnly`.
4613// If `b.OrderOnly` is not present in `candidates`, it gets stored.
4614// But if `b.OrderOnly` already exists in `candidates`, then `b.OrderOnly`
4615// (and phonyCandidate#first.OrderOnly) will be replaced with phonyCandidate#phony.Outputs
4616func scanBuildDef(wg *sync.WaitGroup, candidates *sync.Map, phonyCount *atomic.Uint32, b *buildDef) {
4617	defer wg.Done()
4618	key := keyForPhonyCandidate(b.OrderOnly)
4619	if key == "" {
4620		return
4621	}
4622	if v, loaded := candidates.LoadOrStore(key, &phonyCandidate{
4623		first: b,
4624	}); loaded {
4625		m := v.(*phonyCandidate)
4626		m.Do(func() {
4627			// this is the second occurrence and hence it makes sense to
4628			// extract it as a phony output
4629			phonyCount.Add(1)
4630			m.phony = &buildDef{
4631				Rule:     Phony,
4632				Outputs:  []ninjaString{simpleNinjaString("dedup-" + key)},
4633				Inputs:   m.first.OrderOnly, //we could also use b.OrderOnly
4634				Optional: true,
4635			}
4636			// the previously recorded build-def, which first had these deps as its
4637			// order-only deps, should now use this phony output instead
4638			m.first.OrderOnly = m.phony.Outputs
4639			m.first = nil
4640		})
4641		b.OrderOnly = m.phony.Outputs
4642	}
4643}
4644
4645// deduplicateOrderOnlyDeps searches for common sets of order-only dependencies across all
4646// buildDef instances in the provided moduleInfo instances. Each such
4647// common set forms a new buildDef representing a phony output that then becomes
4648// the sole order-only dependency of those buildDef instances
4649func (c *Context) deduplicateOrderOnlyDeps(infos []*moduleInfo) *localBuildActions {
4650	c.BeginEvent("deduplicate_order_only_deps")
4651	defer c.EndEvent("deduplicate_order_only_deps")
4652
4653	candidates := sync.Map{} //used as map[key]*candidate
4654	phonyCount := atomic.Uint32{}
4655	wg := sync.WaitGroup{}
4656	for _, info := range infos {
4657		for _, b := range info.actionDefs.buildDefs {
4658			if len(b.OrderOnly) > 0 {
4659				wg.Add(1)
4660				go scanBuildDef(&wg, &candidates, &phonyCount, b)
4661			}
4662		}
4663	}
4664	wg.Wait()
4665
4666	// now collect all created phonys to return
4667	phonys := make([]*buildDef, 0, phonyCount.Load())
4668	candidates.Range(func(_ any, v any) bool {
4669		candidate := v.(*phonyCandidate)
4670		if candidate.phony != nil {
4671			phonys = append(phonys, candidate.phony)
4672		}
4673		return true
4674	})
4675
4676	c.EventHandler.Do("sort_phony_builddefs", func() {
4677		// sorting for determinism, the phony output names are stable
4678		sort.Slice(phonys, func(i int, j int) bool {
4679			return phonys[i].Outputs[0].Value(nil) < phonys[j].Outputs[0].Value(nil)
4680		})
4681	})
4682
4683	return &localBuildActions{buildDefs: phonys}
4684}
4685
4686func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
4687	defs *localBuildActions) error {
4688
4689	// Write the local variable assignments.
4690	for _, v := range defs.variables {
4691		// A localVariable doesn't need the package names or config to
4692		// determine its name or value.
4693		name := v.fullName(nil)
4694		value, err := v.value(nil, nil)
4695		if err != nil {
4696			panic(err)
4697		}
4698		err = nw.Assign(name, value.Value(c.pkgNames))
4699		if err != nil {
4700			return err
4701		}
4702	}
4703
4704	if len(defs.variables) > 0 {
4705		err := nw.BlankLine()
4706		if err != nil {
4707			return err
4708		}
4709	}
4710
4711	// Write the local rules.
4712	for _, r := range defs.rules {
4713		// A localRule doesn't need the package names or config to determine
4714		// its name or definition.
4715		name := r.fullName(nil)
4716		def, err := r.def(nil)
4717		if err != nil {
4718			panic(err)
4719		}
4720
4721		err = def.WriteTo(nw, name, c.pkgNames)
4722		if err != nil {
4723			return err
4724		}
4725
4726		err = nw.BlankLine()
4727		if err != nil {
4728			return err
4729		}
4730	}
4731
4732	// Write the build definitions.
4733	for _, buildDef := range defs.buildDefs {
4734		err := buildDef.WriteTo(nw, c.pkgNames)
4735		if err != nil {
4736			return err
4737		}
4738
4739		if len(buildDef.Args) > 0 {
4740			err = nw.BlankLine()
4741			if err != nil {
4742				return err
4743			}
4744		}
4745	}
4746
4747	return nil
4748}
4749
4750func beforeInModuleList(a, b *moduleInfo, list modulesOrAliases) bool {
4751	found := false
4752	if a == b {
4753		return false
4754	}
4755	for _, l := range list {
4756		if l.module() == a {
4757			found = true
4758		} else if l.module() == b {
4759			return found
4760		}
4761	}
4762
4763	missing := a
4764	if found {
4765		missing = b
4766	}
4767	panic(fmt.Errorf("element %v not found in list %v", missing, list))
4768}
4769
4770type panicError struct {
4771	panic interface{}
4772	stack []byte
4773	in    string
4774}
4775
4776func newPanicErrorf(panic interface{}, in string, a ...interface{}) error {
4777	buf := make([]byte, 4096)
4778	count := runtime.Stack(buf, false)
4779	return panicError{
4780		panic: panic,
4781		in:    fmt.Sprintf(in, a...),
4782		stack: buf[:count],
4783	}
4784}
4785
4786func (p panicError) Error() string {
4787	return fmt.Sprintf("panic in %s\n%s\n%s\n", p.in, p.panic, p.stack)
4788}
4789
4790func (p *panicError) addIn(in string) {
4791	p.in += " in " + in
4792}
4793
4794func funcName(f interface{}) string {
4795	return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
4796}
4797
4798var fileHeaderTemplate = `******************************************************************************
4799***            This file is generated and should not be edited             ***
4800******************************************************************************
4801{{if .Pkgs}}
4802This file contains variables, rules, and pools with name prefixes indicating
4803they were generated by the following Go packages:
4804{{range .Pkgs}}
4805    {{.PkgName}} [from Go package {{.PkgPath}}]{{end}}{{end}}
4806
4807`
4808
4809var moduleHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4810Module:  {{.name}}
4811Variant: {{.variant}}
4812Type:    {{.typeName}}
4813Factory: {{.goFactory}}
4814Defined: {{.pos}}
4815`
4816
4817var singletonHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4818Singleton: {{.name}}
4819Factory:   {{.goFactory}}
4820`
4821
4822// Blueprint module type that can be used to gate blueprint files beneath this directory
4823type PackageIncludes struct {
4824	properties struct {
4825		// Package will be included if all include tags in this list are set
4826		Match_all []string
4827	}
4828	name *string `blueprint:"mutated"`
4829}
4830
4831func (pi *PackageIncludes) Name() string {
4832	return proptools.String(pi.name)
4833}
4834
4835// This module type does not have any build actions
4836func (pi *PackageIncludes) GenerateBuildActions(ctx ModuleContext) {
4837}
4838
4839func newPackageIncludesFactory() (Module, []interface{}) {
4840	module := &PackageIncludes{}
4841	AddLoadHook(module, func(ctx LoadHookContext) {
4842		module.name = proptools.StringPtr(ctx.ModuleDir() + "_includes") // Generate a synthetic name
4843	})
4844	return module, []interface{}{&module.properties}
4845}
4846
4847func RegisterPackageIncludesModuleType(ctx *Context) {
4848	ctx.RegisterModuleType("blueprint_package_includes", newPackageIncludesFactory)
4849}
4850
4851func (pi *PackageIncludes) MatchAll() []string {
4852	return pi.properties.Match_all
4853}
4854
4855// Returns true if all requested include tags are set in the Context object
4856func (pi *PackageIncludes) MatchesIncludeTags(ctx *Context) bool {
4857	if len(pi.MatchAll()) == 0 {
4858		ctx.ModuleErrorf(pi, "Match_all must be a non-empty list")
4859	}
4860	for _, includeTag := range pi.MatchAll() {
4861		if !ctx.ContainsIncludeTag(includeTag) {
4862			return false
4863		}
4864	}
4865	return true
4866}
4867