bp2build: framework for generating BazelTargetModules.

This CL creates the framework necessary for generating
BazelTargetModules from regular Soong Android modules.
BazelTargetModules are code-generated into Bazel targets in BUILD files.

See the follow-up CL for examples of creating filegroup/genrule
BazelTargetModules.

Test: GENERATE_BAZEL_FILES=true m nothing # creates out/soong/bp2build
with no BUILD files, because there are no BazelTargetModules in the
module graph.

Change-Id: I33a96365bd439043b13af6db9e439592e9983188
diff --git a/android/module.go b/android/module.go
index 17035bb..a0ee33a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"android/soong/bazel"
 	"fmt"
 	"os"
 	"path"
@@ -491,6 +492,26 @@
 	TransitivePackagingSpecs() []PackagingSpec
 }
 
+type BazelTargetModule interface {
+	Module
+
+	BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties
+}
+
+func InitBazelTargetModule(module BazelTargetModule) {
+	module.AddProperties(module.BazelTargetModuleProperties())
+	InitAndroidModule(module)
+}
+
+type BazelTargetModuleBase struct {
+	ModuleBase
+	Properties bazel.BazelTargetModuleProperties
+}
+
+func (btmb *BazelTargetModuleBase) BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties {
+	return &btmb.Properties
+}
+
 // Qualified id for a module
 type qualifiedModuleName struct {
 	// The package (i.e. directory) in which the module is defined, without trailing /
@@ -1069,6 +1090,9 @@
 	archProperties          [][]interface{}
 	customizableProperties  []interface{}
 
+	// Properties specific to the Blueprint to BUILD migration.
+	bazelTargetModuleProperties bazel.BazelTargetModuleProperties
+
 	// Information about all the properties on the module that contains visibility rules that need
 	// checking.
 	visibilityPropertyInfo []visibilityProperty
diff --git a/android/mutator.go b/android/mutator.go
index 72c68b2..2a2be6c 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -44,9 +44,16 @@
 	}
 }
 
-func registerMutatorsForBazelConversion(ctx *blueprint.Context) {
-	// FIXME(b/171263886): Start bringing in mutators to make the Bionic
-	// module subgraph suitable for automated conversion.
+// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
+func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, bp2buildMutators []RegisterMutatorFunc) {
+	mctx := &registerMutatorsContext{}
+
+	// Register bp2build mutators
+	for _, f := range bp2buildMutators {
+		f(mctx)
+	}
+
+	registerMutatorsToContext(ctx, mctx.mutators)
 }
 
 func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
@@ -196,6 +203,21 @@
 	finalDeps = append(finalDeps, f)
 }
 
+var bp2buildMutators = []RegisterMutatorFunc{}
+
+// RegisterBp2BuildMutator registers specially crafted mutators for
+// converting Blueprint/Android modules into special modules that can
+// be code-generated into Bazel BUILD targets.
+//
+// TODO(b/178068862): bring this into TestContext.
+func RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) {
+	mutatorName := moduleType + "_bp2build"
+	f := func(ctx RegisterMutatorsContext) {
+		ctx.TopDown(mutatorName, m)
+	}
+	bp2buildMutators = append(bp2buildMutators, f)
+}
+
 type BaseMutatorContext interface {
 	BaseModuleContext
 
diff --git a/android/register.go b/android/register.go
index f84acad..02fc97e 100644
--- a/android/register.go
+++ b/android/register.go
@@ -115,7 +115,7 @@
 		ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
 	}
 
-	registerMutatorsForBazelConversion(ctx.Context)
+	RegisterMutatorsForBazelConversion(ctx.Context, bp2buildMutators)
 }
 
 // Register the pipeline of singletons, module types, and mutators for
diff --git a/android/testing.go b/android/testing.go
index 470cfd6..76172d1 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -57,6 +57,7 @@
 type TestContext struct {
 	*Context
 	preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
+	bp2buildMutators                      []RegisterMutatorFunc
 	NameResolver                          *NameResolver
 }
 
@@ -81,12 +82,27 @@
 	ctx.finalDeps = append(ctx.finalDeps, f)
 }
 
+// RegisterBp2BuildMutator registers a BazelTargetModule mutator for converting a module
+// type to the equivalent Bazel target.
+func (ctx *TestContext) RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) {
+	mutatorName := moduleType + "_bp2build"
+	f := func(ctx RegisterMutatorsContext) {
+		ctx.TopDown(mutatorName, m)
+	}
+	bp2buildMutators = append(bp2buildMutators, f)
+}
+
 func (ctx *TestContext) Register() {
 	registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
 
 	ctx.RegisterSingletonType("env", EnvSingleton)
 }
 
+// RegisterForBazelConversion prepares a test context for bp2build conversion.
+func (ctx *TestContext) RegisterForBazelConversion() {
+	RegisterMutatorsForBazelConversion(ctx.Context.Context, bp2buildMutators)
+}
+
 func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
 	// This function adapts the old style ParseFileList calls that are spread throughout the tests
 	// to the new style that takes a config.