Make GetDirectDep implementation match comment

The comment on the interface of GetDirectDep states if there are
multiple deps with different tags, the first will be returned; however,
the current behavior is to panic if there are multiple deps. The
behavior now:
* a single dep, return the module and tag
* a single module with different tags: return module with first tag
* multiple modules: panic
* no module: return nil, nil

Bug: 186488405
Test: ~/aosp/build/bazel/ci/bp2build.sh
Test: m nothing
Change-Id: Id1e7315e7874b4a683ad7357ed2793822315821f
diff --git a/android/module.go b/android/module.go
index 9f923e2..fdb5290 100644
--- a/android/module.go
+++ b/android/module.go
@@ -213,7 +213,7 @@
 
 	// GetDirectDep returns the Module and DependencyTag for the  direct dependency with the specified
 	// name, or nil if none exists.  If there are multiple dependencies on the same module it returns
-	// the first DependencyTag.  It skips any dependencies that are not an android.Module.
+	// the first DependencyTag.
 	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
 
 	// VisitDirectDepsBlueprint calls visit for each direct dependency.  If there are multiple
@@ -2244,11 +2244,12 @@
 	return aModule
 }
 
-func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
-	type dep struct {
-		mod blueprint.Module
-		tag blueprint.DependencyTag
-	}
+type dep struct {
+	mod blueprint.Module
+	tag blueprint.DependencyTag
+}
+
+func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
 	var deps []dep
 	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
 		if aModule, _ := module.(Module); aModule != nil {
@@ -2265,6 +2266,11 @@
 			}
 		}
 	})
+	return deps
+}
+
+func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
+	deps := b.getDirectDepsInternal(name, tag)
 	if len(deps) == 1 {
 		return deps[0].mod, deps[0].tag
 	} else if len(deps) >= 2 {
@@ -2275,6 +2281,25 @@
 	}
 }
 
+func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
+	foundDeps := b.getDirectDepsInternal(name, nil)
+	deps := map[blueprint.Module]bool{}
+	for _, dep := range foundDeps {
+		deps[dep.mod] = true
+	}
+	if len(deps) == 1 {
+		return foundDeps[0].mod, foundDeps[0].tag
+	} else if len(deps) >= 2 {
+		// this could happen if two dependencies have the same name in different namespaces
+		// TODO(b/186554727): this should not occur if namespaces are handled within
+		// getDirectDepsInternal.
+		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
+			name, b.ModuleName()))
+	} else {
+		return nil, nil
+	}
+}
+
 func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
 	var deps []Module
 	b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
@@ -2292,8 +2317,11 @@
 	return module
 }
 
+// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
+// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
+// first DependencyTag.
 func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
-	return b.getDirectDepInternal(name, nil)
+	return b.getDirectDepFirstTag(name)
 }
 
 func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {