Use one mutator for all bp2build conversion.

Each conversion required defining a separate mutator, which will each
operate on _all_ modules and requires each to repeat checks whether the
mutator should operator. Instead, we introduce a single mutator and
modules can define a ConvertWithBp2build to implement bp2build
conversion for that module.

Test: bp2build.sh
Bug: 183079158
Change-Id: I99d4b51f441c2903879092c5b56313d606d4338d
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 95a26a9..1440b6f 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -245,7 +245,7 @@
 		{
 			description: "string props",
 			blueprint: `custom {
-	name: "foo",
+  name: "foo",
     string_list_prop: ["a", "b"],
     string_ptr_prop: "a",
     bazel_module: { bp2build_available: true },
@@ -470,7 +470,7 @@
 			android.FailIfErrored(t, err)
 
 			if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
-				t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
+				t.Errorf("Expected %d bazel target (%s),\ngot %d (%s)", expectedCount, testCase.expectedBazelTargets, actualCount, bazelTargets)
 			} else {
 				for i, expectedBazelTarget := range testCase.expectedBazelTargets {
 					actualBazelTarget := bazelTargets[i]
@@ -596,6 +596,7 @@
 		{
 			bp: `custom {
     name: "bar",
+    one_to_many_prop: true,
     bazel_module: { bp2build_available: true  },
 }`,
 			expectedBazelTarget: `my_library(
@@ -620,7 +621,6 @@
 		config := android.TestConfig(buildDir, nil, testCase.bp, nil)
 		ctx := android.NewTestContext(config)
 		ctx.RegisterModuleType("custom", customModuleFactory)
-		ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutatorFromStarlark)
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
@@ -658,10 +658,9 @@
 func TestModuleTypeBp2Build(t *testing.T) {
 	testCases := []bp2buildTestCase{
 		{
-			description:                        "filegroup with does not specify srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup with does not specify srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     bazel_module: { bp2build_available: true },
@@ -671,10 +670,9 @@
 			},
 		},
 		{
-			description:                        "filegroup with no srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup with no srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: [],
@@ -685,10 +683,9 @@
 			},
 		},
 		{
-			description:                        "filegroup with srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup with srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: ["a", "b"],
@@ -704,10 +701,9 @@
 			},
 		},
 		{
-			description:                        "filegroup with excludes srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup with excludes srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: ["a", "b"],
@@ -721,10 +717,9 @@
 			},
 		},
 		{
-			description:                        "filegroup with glob",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup with glob",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: ["**/*.txt"],
@@ -747,12 +742,10 @@
 			},
 		},
 		{
-			description:                        "filegroup with glob in subdir",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
-			blueprint:                          ``,
-			dir:                                "other",
+			description:                "filegroup with glob in subdir",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
+			dir:                        "other",
 			filesystem: map[string]string{
 				"other/Android.bp": `filegroup {
     name: "fg_foo",
@@ -775,10 +768,9 @@
 			},
 		},
 		{
-			description:                        "depends_on_other_dir_module",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "depends_on_other_dir_module",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: [
@@ -804,26 +796,25 @@
 			},
 		},
 		{
-			description:                        "depends_on_other_unconverted_module_error",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
-			unconvertedDepsMode:                errorModulesUnconvertedDeps,
-			filesystem: map[string]string{
-				"other/Android.bp": `filegroup {
-    name: "foo",
-    srcs: ["a", "b"],
-}`,
-			},
+			description:                "depends_on_other_unconverted_module_error",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
+			unconvertedDepsMode:        errorModulesUnconvertedDeps,
 			blueprint: `filegroup {
-    name: "fg_foo",
+    name: "foobar",
     srcs: [
         ":foo",
         "c",
     ],
     bazel_module: { bp2build_available: true },
 }`,
-			expectedErr: fmt.Errorf(`"fg_foo" depends on unconverted modules: foo`),
+			expectedErr: fmt.Errorf(`"foobar" depends on unconverted modules: foo`),
+			filesystem: map[string]string{
+				"other/Android.bp": `filegroup {
+    name: "foo",
+    srcs: ["a", "b"],
+}`,
+			},
 		},
 	}
 
@@ -838,18 +829,16 @@
 
 func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) {
 	testCases := []struct {
-		moduleTypeUnderTest                string
-		moduleTypeUnderTestFactory         android.ModuleFactory
-		moduleTypeUnderTestBp2BuildMutator bp2buildMutator
-		bp                                 string
-		expectedCount                      int
-		description                        string
+		moduleTypeUnderTest        string
+		moduleTypeUnderTestFactory android.ModuleFactory
+		bp                         string
+		expectedCount              int
+		description                string
 	}{
 		{
-			description:                        "explicitly unavailable",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "explicitly unavailable",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			bp: `filegroup {
     name: "foo",
     srcs: ["a", "b"],
@@ -858,10 +847,9 @@
 			expectedCount: 0,
 		},
 		{
-			description:                        "implicitly unavailable",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "implicitly unavailable",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			bp: `filegroup {
     name: "foo",
     srcs: ["a", "b"],
@@ -869,10 +857,9 @@
 			expectedCount: 0,
 		},
 		{
-			description:                        "explicitly available",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "explicitly available",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			bp: `filegroup {
     name: "foo",
     srcs: ["a", "b"],
@@ -881,12 +868,12 @@
 			expectedCount: 1,
 		},
 		{
-			description:                        "generates more than 1 target if needed",
-			moduleTypeUnderTest:                "custom",
-			moduleTypeUnderTestFactory:         customModuleFactory,
-			moduleTypeUnderTestBp2BuildMutator: customBp2BuildMutatorFromStarlark,
+			description:                "generates more than 1 target if needed",
+			moduleTypeUnderTest:        "custom",
+			moduleTypeUnderTestFactory: customModuleFactory,
 			bp: `custom {
     name: "foo",
+    one_to_many_prop: true,
     bazel_module: { bp2build_available: true },
 }`,
 			expectedCount: 3,
@@ -899,7 +886,6 @@
 			config := android.TestConfig(buildDir, nil, testCase.bp, nil)
 			ctx := android.NewTestContext(config)
 			ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
-			ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
 			ctx.RegisterForBazelConversion()
 
 			_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
@@ -919,20 +905,18 @@
 
 func TestAllowlistingBp2buildTargetsWithConfig(t *testing.T) {
 	testCases := []struct {
-		moduleTypeUnderTest                string
-		moduleTypeUnderTestFactory         android.ModuleFactory
-		moduleTypeUnderTestBp2BuildMutator bp2buildMutator
-		expectedCount                      map[string]int
-		description                        string
-		bp2buildConfig                     android.Bp2BuildConfig
-		checkDir                           string
-		fs                                 map[string]string
+		moduleTypeUnderTest        string
+		moduleTypeUnderTestFactory android.ModuleFactory
+		expectedCount              map[string]int
+		description                string
+		bp2buildConfig             android.Bp2BuildConfig
+		checkDir                   string
+		fs                         map[string]string
 	}{
 		{
-			description:                        "test bp2build config package and subpackages config",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "test bp2build config package and subpackages config",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			expectedCount: map[string]int{
 				"migrated":                           1,
 				"migrated/but_not_really":            0,
@@ -954,10 +938,9 @@
 			},
 		},
 		{
-			description:                        "test bp2build config opt-in and opt-out",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "test bp2build config opt-in and opt-out",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			expectedCount: map[string]int{
 				"package-opt-in":             2,
 				"package-opt-in/subpackage":  0,
@@ -1008,7 +991,6 @@
 		config := android.TestConfig(buildDir, nil, "", fs)
 		ctx := android.NewTestContext(config)
 		ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
-		ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
 		ctx.RegisterBp2BuildConfig(testCase.bp2buildConfig)
 		ctx.RegisterForBazelConversion()
 
@@ -1039,10 +1021,9 @@
 func TestCombineBuildFilesBp2buildTargets(t *testing.T) {
 	testCases := []bp2buildTestCase{
 		{
-			description:                        "filegroup bazel_module.label",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup bazel_module.label",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     bazel_module: { label: "//other:fg_foo" },
@@ -1055,19 +1036,18 @@
 			},
 		},
 		{
-			description:                        "multiple bazel_module.label same BUILD",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "multiple bazel_module.label same BUILD",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
-		    name: "fg_foo",
-		    bazel_module: { label: "//other:fg_foo" },
-		}
+        name: "fg_foo",
+        bazel_module: { label: "//other:fg_foo" },
+    }
 
-		filegroup {
-		    name: "foo",
-		    bazel_module: { label: "//other:foo" },
-		}`,
+    filegroup {
+        name: "foo",
+        bazel_module: { label: "//other:foo" },
+    }`,
 			expectedBazelTargets: []string{
 				`// BUILD file`,
 			},
@@ -1076,25 +1056,24 @@
 			},
 		},
 		{
-			description:                        "filegroup bazel_module.label and bp2build in subdir",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
-			dir:                                "other",
-			blueprint:                          ``,
+			description:                "filegroup bazel_module.label and bp2build in subdir",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
+			dir:                        "other",
+			blueprint:                  ``,
 			filesystem: map[string]string{
 				"other/Android.bp": `filegroup {
-				name: "fg_foo",
-				bazel_module: {
-					bp2build_available: true,
-				},
-			}
-			filegroup {
-				name: "fg_bar",
-				bazel_module: {
-					label: "//other:fg_bar"
-				},
-			}`,
+        name: "fg_foo",
+        bazel_module: {
+          bp2build_available: true,
+        },
+      }
+      filegroup {
+        name: "fg_bar",
+        bazel_module: {
+          label: "//other:fg_bar"
+        },
+      }`,
 				"other/BUILD.bazel": `// definition for fg_bar`,
 			},
 			expectedBazelTargets: []string{
@@ -1103,26 +1082,26 @@
 			},
 		},
 		{
-			description:                        "filegroup bazel_module.label and filegroup bp2build",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup bazel_module.label and filegroup bp2build",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
+
 			filesystem: map[string]string{
 				"other/BUILD.bazel": `// BUILD file`,
 			},
 			blueprint: `filegroup {
-		    name: "fg_foo",
-		    bazel_module: {
-		      label: "//other:fg_foo",
-		    },
-		}
+        name: "fg_foo",
+        bazel_module: {
+          label: "//other:fg_foo",
+        },
+    }
 
-		filegroup {
-		    name: "fg_bar",
-		    bazel_module: {
-		      bp2build_available: true,
-		    },
-		}`,
+    filegroup {
+        name: "fg_bar",
+        bazel_module: {
+          bp2build_available: true,
+        },
+    }`,
 			expectedBazelTargets: []string{
 				makeBazelTarget("filegroup", "fg_bar", map[string]string{}),
 				`// BUILD file`,
@@ -1146,7 +1125,6 @@
 			config := android.TestConfig(buildDir, nil, testCase.blueprint, fs)
 			ctx := android.NewTestContext(config)
 			ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
-			ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
 			ctx.RegisterForBazelConversion()
 
 			_, errs := ctx.ParseFileList(dir, toParse)
@@ -1192,10 +1170,9 @@
 func TestGlobExcludeSrcs(t *testing.T) {
 	testCases := []bp2buildTestCase{
 		{
-			description:                        "filegroup top level exclude_srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "filegroup top level exclude_srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: `filegroup {
     name: "fg_foo",
     srcs: ["**/*.txt"],
@@ -1222,12 +1199,11 @@
 			},
 		},
 		{
-			description:                        "filegroup in subdir exclude_srcs",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
-			blueprint:                          "",
-			dir:                                "dir",
+			description:                "filegroup in subdir exclude_srcs",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
+			blueprint:                  "",
+			dir:                        "dir",
 			filesystem: map[string]string{
 				"dir/Android.bp": `filegroup {
     name: "fg_foo",
@@ -1264,10 +1240,9 @@
 func TestCommonBp2BuildModuleAttrs(t *testing.T) {
 	testCases := []bp2buildTestCase{
 		{
-			description:                        "Required into data test",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "Required into data test",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
 filegroup {
     name: "fg_foo",
@@ -1281,21 +1256,20 @@
 			},
 		},
 		{
-			description:                        "Required via arch into data test",
-			moduleTypeUnderTest:                "python_library",
-			moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
-			moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
+			description:                "Required via arch into data test",
+			moduleTypeUnderTest:        "python_library",
+			moduleTypeUnderTestFactory: python.PythonLibraryFactory,
 			blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqdx86") +
 				simpleModuleDoNotConvertBp2build("python_library", "reqdarm") + `
 python_library {
     name: "fg_foo",
     arch: {
-			 arm: {
-				 required: ["reqdarm"],
-			 },
-			 x86: {
-				 required: ["reqdx86"],
-			 },
+       arm: {
+         required: ["reqdarm"],
+       },
+       x86: {
+         required: ["reqdx86"],
+       },
     },
     bazel_module: { bp2build_available: true },
 }`,
@@ -1311,10 +1285,9 @@
 			},
 		},
 		{
-			description:                        "Required appended to data test",
-			moduleTypeUnderTest:                "python_library",
-			moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
-			moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
+			description:                "Required appended to data test",
+			moduleTypeUnderTest:        "python_library",
+			moduleTypeUnderTestFactory: python.PythonLibraryFactory,
 			filesystem: map[string]string{
 				"data.bin": "",
 				"src.py":   "",
@@ -1337,10 +1310,9 @@
 			},
 		},
 		{
-			description:                        "All props-to-attrs at once together test",
-			moduleTypeUnderTest:                "filegroup",
-			moduleTypeUnderTestFactory:         android.FileGroupFactory,
-			moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+			description:                "All props-to-attrs at once together test",
+			moduleTypeUnderTest:        "filegroup",
+			moduleTypeUnderTestFactory: android.FileGroupFactory,
 			blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
 filegroup {
     name: "fg_foo",