Add a new SingletonModule type

A SingletonModule is halfway between a Singleton and a Module.  It has
access to visiting other modules via its GenerateSingletonBuildActions
method, but must be defined in an Android.bp file and can also be
depended on like a module.

Bug: 176904285
Test: singleton_module_test.go
Change-Id: I1b2bfdfb3927c1eabf431c53213cb7c581e33ca4
diff --git a/android/register.go b/android/register.go
index b26f9b9..61889f6 100644
--- a/android/register.go
+++ b/android/register.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"reflect"
 
 	"github.com/google/blueprint"
 )
@@ -26,6 +27,7 @@
 }
 
 var moduleTypes []moduleType
+var moduleTypesForDocs = map[string]reflect.Value{}
 
 type singleton struct {
 	name    string
@@ -69,6 +71,16 @@
 
 func RegisterModuleType(name string, factory ModuleFactory) {
 	moduleTypes = append(moduleTypes, moduleType{name, factory})
+	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
+}
+
+// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
+// function that has documentation for the module type.  It is normally called automatically
+// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
+// override the factory method used for documentation, for example if the method passed to
+// RegisterModuleType was a lambda.
+func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
+	moduleTypesForDocs[name] = factory
 }
 
 func RegisterSingletonType(name string, factory SingletonFactory) {
@@ -142,12 +154,17 @@
 	return ret
 }
 
+func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
+	return moduleTypesForDocs
+}
+
 // Interface for registering build components.
 //
 // Provided to allow registration of build components to be shared between the runtime
 // and test environments.
 type RegistrationContext interface {
 	RegisterModuleType(name string, factory ModuleFactory)
+	RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
 	RegisterSingletonType(name string, factory SingletonFactory)
 	PreArchMutators(f RegisterMutatorFunc)
 
@@ -186,8 +203,9 @@
 var _ RegistrationContext = (*TestContext)(nil)
 
 type initRegistrationContext struct {
-	moduleTypes    map[string]ModuleFactory
-	singletonTypes map[string]SingletonFactory
+	moduleTypes        map[string]ModuleFactory
+	singletonTypes     map[string]SingletonFactory
+	moduleTypesForDocs map[string]reflect.Value
 }
 
 func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
@@ -196,6 +214,17 @@
 	}
 	ctx.moduleTypes[name] = factory
 	RegisterModuleType(name, factory)
+	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
+}
+
+func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
+	s, m := SingletonModuleFactoryAdaptor(name, factory)
+	ctx.RegisterSingletonType(name, s)
+	ctx.RegisterModuleType(name, m)
+	// Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
+	// SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
+	// factory method.
+	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
 }
 
 func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {