Implement bp2build for the `license` module

Also, add ExpectedRuleTarget type to simplify bp2build testing

Bug: 190817312
Test: treehugger
Change-Id: Id3a642680d3518d36360ba957919a6fc96222672
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index d424df0..ab028e5 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -304,6 +304,7 @@
 		// external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails
 		// e.g. ERROR: Analysis of target '@soong_injection//mixed_builds:buildroot' failed
 		"external/bazelbuild-rules_android":/* recursive = */ true,
+		"external/bazelbuild-rules_license":/* recursive = */ true,
 		"external/bazelbuild-kotlin-rules":/* recursive = */ true,
 		"external/bazel-skylib":/* recursive = */ true,
 		"external/guava":/* recursive = */ true,
diff --git a/android/license.go b/android/license.go
index ebee055..c36f488 100644
--- a/android/license.go
+++ b/android/license.go
@@ -15,7 +15,10 @@
 package android
 
 import (
+	"android/soong/bazel"
+	"fmt"
 	"github.com/google/blueprint"
+	"os"
 )
 
 type licenseKindDependencyTag struct {
@@ -48,14 +51,53 @@
 	Visibility []string
 }
 
+var _ Bazelable = &licenseModule{}
+
 type licenseModule struct {
 	ModuleBase
 	DefaultableModuleBase
 	SdkBase
+	BazelModuleBase
 
 	properties licenseProperties
 }
 
+type bazelLicenseAttributes struct {
+	License_kinds    []string
+	Copyright_notice *string
+	License_text     bazel.LabelAttribute
+	Package_name     *string
+	Visibility       []string
+}
+
+func (m *licenseModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+	attrs := &bazelLicenseAttributes{
+		License_kinds:    m.properties.License_kinds,
+		Copyright_notice: m.properties.Copyright_notice,
+		Package_name:     m.properties.Package_name,
+		Visibility:       m.properties.Visibility,
+	}
+
+	// TODO(asmundak): Soong supports multiple license texts while Bazel does not.
+	if len(m.properties.License_text) > 1 {
+		fmt.Fprintf(os.Stderr, "%s:%s: warning: using only the first license_text item\n",
+			ctx.ModuleDir(), m.Name())
+	}
+	if len(m.properties.License_text) >= 1 {
+		attrs.License_text.SetValue(BazelLabelForModuleSrcSingle(ctx, m.properties.License_text[0]))
+	}
+
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "android_license",
+			Bzl_load_location: "//build/bazel/rules/license:license.bzl",
+		},
+		CommonAttributes{
+			Name: m.Name(),
+		},
+		attrs)
+}
+
 func (m *licenseModule) DepsMutator(ctx BottomUpMutatorContext) {
 	ctx.AddVariationDependencies(nil, licenseKindTag, m.properties.License_kinds...)
 }
@@ -78,7 +120,7 @@
 	module := &licenseModule{}
 
 	base := module.base()
-	module.AddProperties(&base.nameProperties, &module.properties)
+	module.AddProperties(&base.nameProperties, &module.properties, &base.commonProperties.BazelConversionStatus)
 
 	// The visibility property needs to be checked and parsed by the visibility module.
 	setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
@@ -86,6 +128,7 @@
 	InitSdkAwareModule(module)
 	initAndroidModuleBase(module)
 	InitDefaultableModule(module)
+	InitBazelModule(module)
 
 	return module
 }