Detect registration of duplicate module/singleton types

Module type and singleton type names have to be unique but duplicates
are not checked when the relevant android.Register...() func is called.
Instead they are collated in lists and then registered with the Context
later on, at which point duplicates are detected. That loses
information that can be helpful in fixing the issue.

This is not an issue when testing as the module and singleton types
are registered directly with the Context.

This change adds duplicate detection to the initRegistrationContext
Register... methods prior to calling the android.Register... methods
which should make it easier to detect duplicates registered from an
init() function.

Test: m checkbuild
Bug: 146540677
Change-Id: I7f1a4b649072867717a9829c737a44454b12266c
diff --git a/android/register.go b/android/register.go
index 9182f8b..e7efe47 100644
--- a/android/register.go
+++ b/android/register.go
@@ -15,6 +15,8 @@
 package android
 
 import (
+	"fmt"
+
 	"github.com/google/blueprint"
 )
 
@@ -141,21 +143,35 @@
 //
 //   ctx := android.NewTestContext()
 //   RegisterBuildComponents(ctx)
-var InitRegistrationContext RegistrationContext = initRegistrationContext{}
+var InitRegistrationContext RegistrationContext = &initRegistrationContext{
+	moduleTypes:    make(map[string]ModuleFactory),
+	singletonTypes: make(map[string]SingletonFactory),
+}
 
 // Make sure the TestContext implements RegistrationContext.
 var _ RegistrationContext = (*TestContext)(nil)
 
-type initRegistrationContext struct{}
+type initRegistrationContext struct {
+	moduleTypes    map[string]ModuleFactory
+	singletonTypes map[string]SingletonFactory
+}
 
-func (ctx initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
+func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
+	if _, present := ctx.moduleTypes[name]; present {
+		panic(fmt.Sprintf("module type %q is already registered", name))
+	}
+	ctx.moduleTypes[name] = factory
 	RegisterModuleType(name, factory)
 }
 
-func (ctx initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
+func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
+	if _, present := ctx.singletonTypes[name]; present {
+		panic(fmt.Sprintf("singleton type %q is already registered", name))
+	}
+	ctx.singletonTypes[name] = factory
 	RegisterSingletonType(name, factory)
 }
 
-func (ctx initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
+func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
 	PreArchMutators(f)
 }