1package bootstrap
2
3import (
4	"fmt"
5	"path/filepath"
6	"reflect"
7
8	"github.com/google/blueprint"
9	"github.com/google/blueprint/bootstrap/bpdoc"
10	"github.com/google/blueprint/pathtools"
11)
12
13// ModuleTypeDocs returns a list of bpdoc.ModuleType objects that contain information relevant
14// to generating documentation for module types supported by the primary builder.
15func ModuleTypeDocs(ctx *blueprint.Context, factories map[string]reflect.Value) ([]*bpdoc.Package, error) {
16	// Find the module that's marked as the "primary builder", which means it's
17	// creating the binary that we'll use to generate the non-bootstrap
18	// build.ninja file.
19	var primaryBuilders []*GoBinary
20	ctx.VisitAllModulesIf(isBootstrapBinaryModule,
21		func(module blueprint.Module) {
22			binaryModule := module.(*GoBinary)
23			if binaryModule.properties.PrimaryBuilder {
24				primaryBuilders = append(primaryBuilders, binaryModule)
25			}
26		})
27
28	var primaryBuilder *GoBinary
29	switch len(primaryBuilders) {
30	case 0:
31		return nil, fmt.Errorf("no primary builder module present")
32
33	case 1:
34		primaryBuilder = primaryBuilders[0]
35
36	default:
37		return nil, fmt.Errorf("multiple primary builder modules present")
38	}
39
40	pkgFiles := make(map[string][]string)
41	ctx.VisitDepsDepthFirst(primaryBuilder, func(module blueprint.Module) {
42		switch m := module.(type) {
43		case (*GoPackage):
44			pkgFiles[m.properties.PkgPath] = pathtools.PrefixPaths(m.properties.Srcs,
45				filepath.Join(ctx.SrcDir(), ctx.ModuleDir(m)))
46		default:
47			panic(fmt.Errorf("unknown dependency type %T", module))
48		}
49	})
50
51	mergedFactories := make(map[string]reflect.Value)
52	for moduleType, factory := range factories {
53		mergedFactories[moduleType] = factory
54	}
55
56	for moduleType, factory := range ctx.ModuleTypeFactories() {
57		if _, exists := mergedFactories[moduleType]; !exists {
58			mergedFactories[moduleType] = reflect.ValueOf(factory)
59		}
60	}
61
62	return bpdoc.AllPackages(pkgFiles, mergedFactories, ctx.ModuleTypePropertyStructs())
63}
64