Remove infrastructure to run bp2build

Bug: 315353489
Test: m blueprint_tests
Change-Id: Idcf6377d389b94c39e4e6ff4b8efa8a9f9e78b17
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index aff703d..ba12682 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -7,16 +7,11 @@
     pkgPath: "android/soong/bp2build",
     srcs: [
         "androidbp_to_build_templates.go",
-        "bp2build.go",
-        "bp2build_product_config.go",
         "build_conversion.go",
         "bzl_conversion.go",
         "configurability.go",
         "constants.go",
         "conversion.go",
-        "metrics.go",
-        "symlink_forest.go",
-        "testing.go",
     ],
     deps: [
         "blueprint-bootstrap",
@@ -41,7 +36,6 @@
     ],
     testSrcs: [
         "conversion_test.go",
-        "performance_test.go",
     ],
     pluginFor: [
         "soong_build",
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
deleted file mode 100644
index 1496ca7..0000000
--- a/bp2build/bp2build.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"android/soong/android"
-	"android/soong/bazel"
-	"android/soong/shared"
-	"android/soong/starlark_import"
-)
-
-func deleteFilesExcept(ctx *CodegenContext, rootOutputPath android.OutputPath, except []BazelFile) {
-	// Delete files that should no longer be present.
-	bp2buildDirAbs := shared.JoinPath(ctx.topDir, rootOutputPath.String())
-
-	filesToDelete := make(map[string]struct{})
-	err := filepath.Walk(bp2buildDirAbs,
-		func(path string, info os.FileInfo, err error) error {
-			if err != nil {
-				return err
-			}
-			if !info.IsDir() {
-				relPath, err := filepath.Rel(bp2buildDirAbs, path)
-				if err != nil {
-					return err
-				}
-				filesToDelete[relPath] = struct{}{}
-			}
-			return nil
-		})
-	if err != nil {
-		fmt.Printf("ERROR reading %s: %s", bp2buildDirAbs, err)
-		os.Exit(1)
-	}
-
-	for _, bazelFile := range except {
-		filePath := filepath.Join(bazelFile.Dir, bazelFile.Basename)
-		delete(filesToDelete, filePath)
-	}
-	for f, _ := range filesToDelete {
-		absPath := shared.JoinPath(bp2buildDirAbs, f)
-		if err := os.RemoveAll(absPath); err != nil {
-			fmt.Printf("ERROR deleting %s: %s", absPath, err)
-			os.Exit(1)
-		}
-	}
-}
-
-// Codegen is the backend of bp2build. The code generator is responsible for
-// writing .bzl files that are equivalent to Android.bp files that are capable
-// of being built with Bazel.
-func Codegen(ctx *CodegenContext) *CodegenMetrics {
-	ctx.Context().BeginEvent("Codegen")
-	defer ctx.Context().EndEvent("Codegen")
-	// This directory stores BUILD files that could be eventually checked-in.
-	bp2buildDir := android.PathForOutput(ctx, "bp2build")
-
-	res, errs := GenerateBazelTargets(ctx, true)
-	if len(errs) > 0 {
-		errMsgs := make([]string, len(errs))
-		for i, err := range errs {
-			errMsgs[i] = fmt.Sprintf("%q", err)
-		}
-		fmt.Printf("ERROR: Encountered %d error(s): \nERROR: %s", len(errs), strings.Join(errMsgs, "\n"))
-		os.Exit(1)
-	}
-	var bp2buildFiles []BazelFile
-	productConfig, err := createProductConfigFiles(ctx, res.moduleNameToPartition, res.metrics.convertedModulePathMap)
-	ctx.Context().EventHandler.Do("CreateBazelFile", func() {
-		allTargets := make(map[string]BazelTargets)
-		for k, v := range res.buildFileToTargets {
-			allTargets[k] = append(allTargets[k], v...)
-		}
-		for k, v := range productConfig.bp2buildTargets {
-			allTargets[k] = append(allTargets[k], v...)
-		}
-		bp2buildFiles = CreateBazelFiles(nil, allTargets, ctx.mode)
-	})
-	bp2buildFiles = append(bp2buildFiles, productConfig.bp2buildFiles...)
-	injectionFiles, err := createSoongInjectionDirFiles(ctx, res.metrics)
-	if err != nil {
-		fmt.Printf("%s\n", err.Error())
-		os.Exit(1)
-	}
-	injectionFiles = append(injectionFiles, productConfig.injectionFiles...)
-
-	writeFiles(ctx, bp2buildDir, bp2buildFiles)
-	// Delete files under the bp2build root which weren't just written. An
-	// alternative would have been to delete the whole directory and write these
-	// files. However, this would regenerate files which were otherwise unchanged
-	// since the last bp2build run, which would have negative incremental
-	// performance implications.
-	deleteFilesExcept(ctx, bp2buildDir, bp2buildFiles)
-
-	writeFiles(ctx, android.PathForOutput(ctx, bazel.SoongInjectionDirName), injectionFiles)
-	starlarkDeps, err := starlark_import.GetNinjaDeps()
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "%s\n", err)
-		os.Exit(1)
-	}
-	ctx.AddNinjaFileDeps(starlarkDeps...)
-	return &res.metrics
-}
-
-// Get the output directory and create it if it doesn't exist.
-func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath {
-	dirPath := outputDir.Join(ctx, dir)
-	if err := android.CreateOutputDirIfNonexistent(dirPath, os.ModePerm); err != nil {
-		fmt.Printf("ERROR: path %s: %s", dirPath, err.Error())
-	}
-	return dirPath
-}
-
-// writeFiles materializes a list of BazelFile rooted at outputDir.
-func writeFiles(ctx android.PathContext, outputDir android.OutputPath, files []BazelFile) {
-	for _, f := range files {
-		p := getOrCreateOutputDir(outputDir, ctx, f.Dir).Join(ctx, f.Basename)
-		if err := writeFile(p, f.Contents); err != nil {
-			panic(fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err))
-		}
-	}
-}
-
-func writeFile(pathToFile android.OutputPath, content string) error {
-	// These files are made editable to allow users to modify and iterate on them
-	// in the source tree.
-	return android.WriteFileToOutputDir(pathToFile, []byte(content), 0644)
-}
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
deleted file mode 100644
index 4c09d67..0000000
--- a/bp2build/bp2build_product_config.go
+++ /dev/null
@@ -1,885 +0,0 @@
-package bp2build
-
-import (
-	"encoding/json"
-	"fmt"
-	"path/filepath"
-	"reflect"
-	"sort"
-	"strings"
-
-	"android/soong/android"
-	"android/soong/android/soongconfig"
-	"android/soong/starlark_import"
-
-	"github.com/google/blueprint/proptools"
-	"go.starlark.net/starlark"
-)
-
-type createProductConfigFilesResult struct {
-	injectionFiles  []BazelFile
-	bp2buildFiles   []BazelFile
-	bp2buildTargets map[string]BazelTargets
-}
-
-type bazelLabel struct {
-	repo   string
-	pkg    string
-	target string
-}
-
-const releaseAconfigValueSetsName = "release_aconfig_value_sets"
-
-func (l *bazelLabel) Less(other *bazelLabel) bool {
-	if l.repo < other.repo {
-		return true
-	}
-	if l.repo > other.repo {
-		return false
-	}
-	if l.pkg < other.pkg {
-		return true
-	}
-	if l.pkg > other.pkg {
-		return false
-	}
-	return l.target < other.target
-}
-
-func (l *bazelLabel) String() string {
-	return fmt.Sprintf("@%s//%s:%s", l.repo, l.pkg, l.target)
-}
-
-func createProductConfigFiles(
-	ctx *CodegenContext,
-	moduleNameToPartition map[string]string,
-	convertedModulePathMap map[string]string) (createProductConfigFilesResult, error) {
-	cfg := &ctx.config
-	targetProduct := "unknown"
-	if cfg.HasDeviceProduct() {
-		targetProduct = cfg.DeviceProduct()
-	}
-	targetBuildVariant := "user"
-	if cfg.Eng() {
-		targetBuildVariant = "eng"
-	} else if cfg.Debuggable() {
-		targetBuildVariant = "userdebug"
-	}
-
-	var res createProductConfigFilesResult
-
-	productVariables := ctx.Config().ProductVariables()
-	// TODO(b/306243251): For some reason, using the real value of native_coverage makes some select
-	// statements ambiguous
-	productVariables.Native_coverage = nil
-	productVariablesBytes, err := json.Marshal(productVariables)
-	if err != nil {
-		return res, err
-	}
-
-	currentProductFolder := fmt.Sprintf("build/bazel/products/%s", targetProduct)
-	if len(productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory) > 0 {
-		currentProductFolder = fmt.Sprintf("%s%s", productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory, targetProduct)
-	}
-
-	productReplacer := strings.NewReplacer(
-		"{PRODUCT}", targetProduct,
-		"{VARIANT}", targetBuildVariant,
-		"{PRODUCT_FOLDER}", currentProductFolder)
-
-	productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
-	if err != nil {
-		return res, err
-	}
-	productsForTesting := android.SortedKeys(productsForTestingMap)
-	for i := range productsForTesting {
-		productsForTesting[i] = fmt.Sprintf("  \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
-	}
-
-	productLabelsToVariables := make(map[bazelLabel]*android.ProductVariables)
-	productLabelsToVariables[bazelLabel{
-		repo:   "",
-		pkg:    currentProductFolder,
-		target: targetProduct,
-	}] = &productVariables
-	for product, productVariablesStarlark := range productsForTestingMap {
-		productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
-		if err != nil {
-			return res, err
-		}
-		productLabelsToVariables[bazelLabel{
-			repo:   "",
-			pkg:    "build/bazel/tests/products",
-			target: product,
-		}] = &productVariables
-	}
-
-	res.bp2buildTargets = make(map[string]BazelTargets)
-	res.bp2buildTargets[currentProductFolder] = append(res.bp2buildTargets[currentProductFolder], BazelTarget{
-		name:        productReplacer.Replace("{PRODUCT}"),
-		packageName: currentProductFolder,
-		content: productReplacer.Replace(`android_product(
-    name = "{PRODUCT}",
-    soong_variables = _soong_variables,
-)`),
-		ruleClass: "android_product",
-		loads: []BazelLoad{
-			{
-				file: ":soong.variables.bzl",
-				symbols: []BazelLoadSymbol{{
-					symbol: "variables",
-					alias:  "_soong_variables",
-				}},
-			},
-			{
-				file:    "//build/bazel/product_config:android_product.bzl",
-				symbols: []BazelLoadSymbol{{symbol: "android_product"}},
-			},
-		},
-	})
-	createTargets(ctx, productLabelsToVariables, moduleNameToPartition, convertedModulePathMap, res.bp2buildTargets)
-
-	platformMappingContent, err := platformMappingContent(
-		productLabelsToVariables,
-		ctx.Config().Bp2buildSoongConfigDefinitions,
-		convertedModulePathMap)
-	if err != nil {
-		return res, err
-	}
-
-	res.injectionFiles = []BazelFile{
-		newFile(
-			"product_config_platforms",
-			"BUILD.bazel",
-			productReplacer.Replace(`
-package(default_visibility = [
-	"@//build/bazel/product_config:__subpackages__",
-	"@soong_injection//product_config_platforms:__subpackages__",
-])
-
-load("@//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables")
-load("@//build/bazel/product_config:android_product.bzl", "android_product")
-
-# Bazel will qualify its outputs by the platform name. When switching between products, this
-# means that soong-built files that depend on bazel-built files will suddenly get different
-# dependency files, because the path changes, and they will be rebuilt. In order to avoid this
-# extra rebuilding, make mixed builds always use a single platform so that the bazel artifacts
-# are always under the same path.
-android_product(
-    name = "mixed_builds_product",
-    soong_variables = _soong_variables,
-    extra_constraints = ["@//build/bazel/platforms:mixed_builds"],
-)
-`)),
-		newFile(
-			"product_config_platforms",
-			"product_labels.bzl",
-			productReplacer.Replace(`
-# This file keeps a list of all the products in the android source tree, because they're
-# discovered as part of a preprocessing step before bazel runs.
-# TODO: When we start generating the platforms for more than just the
-# currently lunched product, they should all be listed here
-product_labels = [
-  "@soong_injection//product_config_platforms:mixed_builds_product",
-  "@//{PRODUCT_FOLDER}:{PRODUCT}",
-`)+strings.Join(productsForTesting, "\n")+"\n]\n"),
-		newFile(
-			"product_config_platforms",
-			"common.bazelrc",
-			productReplacer.Replace(`
-build --platform_mappings=platform_mappings
-build --platforms @//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
-build --//build/bazel/product_config:target_build_variant={VARIANT}
-
-build:android --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}
-build:linux_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86
-build:linux_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
-build:linux_bionic_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_bionic_x86_64
-build:linux_musl_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_musl_x86
-build:linux_musl_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_musl_x86_64
-`)),
-		newFile(
-			"product_config_platforms",
-			"linux.bazelrc",
-			productReplacer.Replace(`
-build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
-`)),
-		newFile(
-			"product_config_platforms",
-			"darwin.bazelrc",
-			productReplacer.Replace(`
-build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}_darwin_x86_64
-`)),
-	}
-	res.bp2buildFiles = []BazelFile{
-		newFile(
-			"",
-			"platform_mappings",
-			platformMappingContent),
-		newFile(
-			currentProductFolder,
-			"soong.variables.bzl",
-			`variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
-	}
-
-	return res, nil
-}
-
-func platformMappingContent(
-	productLabelToVariables map[bazelLabel]*android.ProductVariables,
-	soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
-	convertedModulePathMap map[string]string) (string, error) {
-	var result strings.Builder
-
-	mergedConvertedModulePathMap := make(map[string]string)
-	for k, v := range convertedModulePathMap {
-		mergedConvertedModulePathMap[k] = v
-	}
-	additionalModuleNamesToPackages, err := starlark_import.GetStarlarkValue[map[string]string]("additional_module_names_to_packages")
-	if err != nil {
-		return "", err
-	}
-	for k, v := range additionalModuleNamesToPackages {
-		mergedConvertedModulePathMap[k] = v
-	}
-
-	productLabels := make([]bazelLabel, 0, len(productLabelToVariables))
-	for k := range productLabelToVariables {
-		productLabels = append(productLabels, k)
-	}
-	sort.Slice(productLabels, func(i, j int) bool {
-		return productLabels[i].Less(&productLabels[j])
-	})
-	result.WriteString("platforms:\n")
-	for _, productLabel := range productLabels {
-		platformMappingSingleProduct(productLabel, productLabelToVariables[productLabel], soongConfigDefinitions, mergedConvertedModulePathMap, &result)
-	}
-	return result.String(), nil
-}
-
-var bazelPlatformSuffixes = []string{
-	"",
-	"_darwin_arm64",
-	"_darwin_x86_64",
-	"_linux_bionic_arm64",
-	"_linux_bionic_x86_64",
-	"_linux_musl_x86",
-	"_linux_musl_x86_64",
-	"_linux_x86",
-	"_linux_x86_64",
-	"_windows_x86",
-	"_windows_x86_64",
-}
-
-func platformMappingSingleProduct(
-	label bazelLabel,
-	productVariables *android.ProductVariables,
-	soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
-	convertedModulePathMap map[string]string,
-	result *strings.Builder) {
-
-	platform_sdk_version := -1
-	if productVariables.Platform_sdk_version != nil {
-		platform_sdk_version = *productVariables.Platform_sdk_version
-	}
-
-	defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup"
-	if proptools.String(productVariables.DefaultAppCertificate) != "" {
-		defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory"
-	}
-
-	// TODO: b/301598690 - commas can't be escaped in a string-list passed in a platform mapping,
-	// so commas are switched for ":" here, and must be back-substituted into commas
-	// wherever the AAPTCharacteristics product config variable is used.
-	AAPTConfig := []string{}
-	for _, conf := range productVariables.AAPTConfig {
-		AAPTConfig = append(AAPTConfig, strings.Replace(conf, ",", ":", -1))
-	}
-
-	for _, suffix := range bazelPlatformSuffixes {
-		result.WriteString("  ")
-		result.WriteString(label.String())
-		result.WriteString(suffix)
-		result.WriteString("\n")
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:aapt_characteristics=%s\n", proptools.String(productVariables.AAPTCharacteristics)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:aapt_config=%s\n", strings.Join(AAPTConfig, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:aapt_preferred_config=%s\n", proptools.String(productVariables.AAPTPreferredConfig)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:compressed_apex=%t\n", proptools.Bool(productVariables.CompressedApex)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:default_app_certificate=%s\n", proptools.String(productVariables.DefaultAppCertificate)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:default_app_certificate_filegroup=%s\n", defaultAppCertificateFilegroup))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_max_page_size_supported=%s\n", proptools.String(productVariables.DeviceMaxPageSizeSupported)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_no_bionic_page_size_macro=%t\n", proptools.Bool(productVariables.DeviceNoBionicPageSizeMacro)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_platform=%s\n", label.String()))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:enforce_vintf_manifest=%t\n", proptools.Bool(productVariables.Enforce_vintf_manifest)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_pattern_fill_contents=%t\n", proptools.Bool(productVariables.Malloc_pattern_fill_contents)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_zero_contents=%t\n", proptools.Bool(productVariables.Malloc_zero_contents)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:memtag_heap_exclude_paths=%s\n", strings.Join(productVariables.MemtagHeapExcludePaths, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:memtag_heap_async_include_paths=%s\n", strings.Join(productVariables.MemtagHeapAsyncIncludePaths, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:memtag_heap_sync_include_paths=%s\n", strings.Join(productVariables.MemtagHeapSyncIncludePaths, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_sdk_final=%t\n", proptools.Bool(productVariables.Platform_sdk_final)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_security_patch=%s\n", proptools.String(productVariables.Platform_security_patch)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_version_last_stable=%s\n", proptools.String(productVariables.Platform_version_last_stable)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:release_aconfig_flag_default_permission=%s\n", productVariables.ReleaseAconfigFlagDefaultPermission))
-		releaseAconfigValueSets := "//build/bazel/product_config:empty_aconfig_value_sets"
-		if len(productVariables.ReleaseAconfigValueSets) > 0 {
-			releaseAconfigValueSets = "@//" + label.pkg + ":" + releaseAconfigValueSetsName + "_" + label.target
-		}
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:release_aconfig_value_sets=%s\n", releaseAconfigValueSets))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:release_version=%s\n", productVariables.ReleaseVersion))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_sdk_version=%d\n", platform_sdk_version))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:safestack=%t\n", proptools.Bool(productVariables.Safestack)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:treble_linker_namespaces=%t\n", proptools.Bool(productVariables.Treble_linker_namespaces)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:tidy_checks=%s\n", proptools.String(productVariables.TidyChecks)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:uml=%t\n", proptools.Bool(productVariables.Uml)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build=%t\n", proptools.Bool(productVariables.Unbundled_build)))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build_apps=%s\n", strings.Join(productVariables.Unbundled_build_apps, ",")))
-
-		for _, override := range productVariables.CertificateOverrides {
-			parts := strings.SplitN(override, ":", 2)
-			if apexPath, ok := convertedModulePathMap[parts[0]]; ok {
-				if overrideCertPath, ok := convertedModulePathMap[parts[1]]; ok {
-					result.WriteString(fmt.Sprintf("    --%s:%s_certificate_override=%s:%s\n", apexPath, parts[0], overrideCertPath, parts[1]))
-				}
-			}
-		}
-
-		for _, namespace := range android.SortedKeys(productVariables.VendorVars) {
-			for _, variable := range android.SortedKeys(productVariables.VendorVars[namespace]) {
-				value := productVariables.VendorVars[namespace][variable]
-				key := namespace + "__" + variable
-				_, hasBool := soongConfigDefinitions.BoolVars[key]
-				_, hasString := soongConfigDefinitions.StringVars[key]
-				_, hasValue := soongConfigDefinitions.ValueVars[key]
-				if !hasBool && !hasString && !hasValue {
-					// Not all soong config variables are defined in Android.bp files. For example,
-					// prebuilt_bootclasspath_fragment uses soong config variables in a nonstandard
-					// way, that causes them to be present in the soong.variables file but not
-					// defined in an Android.bp file. There's also nothing stopping you from setting
-					// a variable in make that doesn't exist in soong. We only generate build
-					// settings for the ones that exist in soong, so skip all others.
-					continue
-				}
-				if hasBool && hasString || hasBool && hasValue || hasString && hasValue {
-					panic(fmt.Sprintf("Soong config variable %s:%s appears to be of multiple types. bool? %t, string? %t, value? %t", namespace, variable, hasBool, hasString, hasValue))
-				}
-				if hasBool {
-					// Logic copied from soongConfig.Bool()
-					value = strings.ToLower(value)
-					if value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" {
-						value = "true"
-					} else {
-						value = "false"
-					}
-				}
-				result.WriteString(fmt.Sprintf("    --//build/bazel/product_config/soong_config_variables:%s=%s\n", strings.ToLower(key), value))
-			}
-		}
-	}
-}
-
-func starlarkMapToProductVariables(in map[string]starlark.Value) (android.ProductVariables, error) {
-	result := android.ProductVariables{}
-	productVarsReflect := reflect.ValueOf(&result).Elem()
-	for i := 0; i < productVarsReflect.NumField(); i++ {
-		field := productVarsReflect.Field(i)
-		fieldType := productVarsReflect.Type().Field(i)
-		name := fieldType.Name
-		if name == "BootJars" || name == "ApexBootJars" || name == "VendorSnapshotModules" ||
-			name == "RecoverySnapshotModules" {
-			// These variables have more complicated types, and we don't need them right now
-			continue
-		}
-		if _, ok := in[name]; ok {
-			if name == "VendorVars" {
-				vendorVars, err := starlark_import.Unmarshal[map[string]map[string]string](in[name])
-				if err != nil {
-					return result, err
-				}
-				field.Set(reflect.ValueOf(vendorVars))
-				continue
-			}
-			switch field.Type().Kind() {
-			case reflect.Bool:
-				val, err := starlark_import.Unmarshal[bool](in[name])
-				if err != nil {
-					return result, err
-				}
-				field.SetBool(val)
-			case reflect.String:
-				val, err := starlark_import.Unmarshal[string](in[name])
-				if err != nil {
-					return result, err
-				}
-				field.SetString(val)
-			case reflect.Slice:
-				if field.Type().Elem().Kind() != reflect.String {
-					return result, fmt.Errorf("slices of types other than strings are unimplemented")
-				}
-				val, err := starlark_import.UnmarshalReflect(in[name], field.Type())
-				if err != nil {
-					return result, err
-				}
-				field.Set(val)
-			case reflect.Pointer:
-				switch field.Type().Elem().Kind() {
-				case reflect.Bool:
-					val, err := starlark_import.UnmarshalNoneable[bool](in[name])
-					if err != nil {
-						return result, err
-					}
-					field.Set(reflect.ValueOf(val))
-				case reflect.String:
-					val, err := starlark_import.UnmarshalNoneable[string](in[name])
-					if err != nil {
-						return result, err
-					}
-					field.Set(reflect.ValueOf(val))
-				case reflect.Int:
-					val, err := starlark_import.UnmarshalNoneable[int](in[name])
-					if err != nil {
-						return result, err
-					}
-					field.Set(reflect.ValueOf(val))
-				default:
-					return result, fmt.Errorf("pointers of types other than strings/bools are unimplemented: %s", field.Type().Elem().Kind().String())
-				}
-			default:
-				return result, fmt.Errorf("unimplemented type: %s", field.Type().String())
-			}
-		}
-	}
-
-	result.Native_coverage = proptools.BoolPtr(
-		proptools.Bool(result.GcovCoverage) ||
-			proptools.Bool(result.ClangCoverage))
-
-	return result, nil
-}
-
-func createTargets(
-	ctx *CodegenContext,
-	productLabelsToVariables map[bazelLabel]*android.ProductVariables,
-	moduleNameToPartition map[string]string,
-	convertedModulePathMap map[string]string,
-	res map[string]BazelTargets) {
-	createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
-	createAvbKeyFilegroups(productLabelsToVariables, res)
-	createReleaseAconfigValueSetsFilegroup(productLabelsToVariables, res)
-	for label, variables := range productLabelsToVariables {
-		createSystemPartition(ctx, label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, moduleNameToPartition, convertedModulePathMap, res)
-	}
-}
-
-func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
-	var allDefaultAppCertificateDirs []string
-	for _, productVariables := range productLabelsToVariables {
-		if proptools.String(productVariables.DefaultAppCertificate) != "" {
-			d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate))
-			if !android.InList(d, allDefaultAppCertificateDirs) {
-				allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d)
-			}
-		}
-	}
-	for _, dir := range allDefaultAppCertificateDirs {
-		content := `filegroup(
-    name = "generated_android_certificate_directory",
-    srcs = glob([
-        "*.pk8",
-        "*.pem",
-        "*.avbpubkey",
-    ]),
-    visibility = ["//visibility:public"],
-)`
-		targets[dir] = append(targets[dir], BazelTarget{
-			name:        "generated_android_certificate_directory",
-			packageName: dir,
-			content:     content,
-			ruleClass:   "filegroup",
-		})
-	}
-}
-
-func createReleaseAconfigValueSetsFilegroup(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
-	for label, productVariables := range productLabelsToVariables {
-		if len(productVariables.ReleaseAconfigValueSets) > 0 {
-			key := label.target
-			dir := label.pkg
-			var value_sets strings.Builder
-			for _, value_set := range productVariables.ReleaseAconfigValueSets {
-				value_sets.WriteString("        \"" + value_set + "\",\n")
-			}
-
-			name := releaseAconfigValueSetsName + "_" + key
-			content := "aconfig_value_sets(\n" +
-				"    name = \"" + name + "\",\n" +
-				"    value_sets = [\n" +
-				value_sets.String() +
-				"    ],\n" +
-				"    visibility = [\"//visibility:public\"],\n" +
-				")"
-			targets[dir] = append(targets[dir], BazelTarget{
-				name:        name,
-				packageName: dir,
-				content:     content,
-				ruleClass:   "aconfig_value_sets",
-				loads: []BazelLoad{{
-					file: "//build/bazel/rules/aconfig:aconfig_value_sets.bzl",
-					symbols: []BazelLoadSymbol{{
-						symbol: "aconfig_value_sets",
-					}},
-				}},
-			})
-		}
-	}
-}
-
-func createAvbKeyFilegroups(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
-	var allAvbKeys []string
-	for _, productVariables := range productLabelsToVariables {
-		for _, partitionVariables := range productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.PartitionQualifiedVariables {
-			if partitionVariables.BoardAvbKeyPath != "" {
-				if !android.InList(partitionVariables.BoardAvbKeyPath, allAvbKeys) {
-					allAvbKeys = append(allAvbKeys, partitionVariables.BoardAvbKeyPath)
-				}
-			}
-		}
-	}
-	for _, key := range allAvbKeys {
-		dir := filepath.Dir(key)
-		name := filepath.Base(key)
-		content := fmt.Sprintf(`filegroup(
-    name = "%s_filegroup",
-    srcs = ["%s"],
-    visibility = ["//visibility:public"],
-)`, name, name)
-		targets[dir] = append(targets[dir], BazelTarget{
-			name:        name + "_filegroup",
-			packageName: dir,
-			content:     content,
-			ruleClass:   "filegroup",
-		})
-	}
-}
-
-func createSystemPartition(
-	ctx *CodegenContext,
-	platformLabel bazelLabel,
-	variables *android.PartitionVariables,
-	moduleNameToPartition map[string]string,
-	convertedModulePathMap map[string]string,
-	targets map[string]BazelTargets) {
-	if !variables.PartitionQualifiedVariables["system"].BuildingImage {
-		return
-	}
-	qualifiedVariables := variables.PartitionQualifiedVariables["system"]
-
-	imageProps := generateImagePropDictionary(variables, "system")
-	imageProps["skip_fsck"] = "true"
-
-	var properties strings.Builder
-	for _, prop := range android.SortedKeys(imageProps) {
-		properties.WriteString(prop)
-		properties.WriteRune('=')
-		properties.WriteString(imageProps[prop])
-		properties.WriteRune('\n')
-	}
-
-	var extraProperties strings.Builder
-	if variables.BoardAvbEnable {
-		extraProperties.WriteString("    avb_enable = True,\n")
-		extraProperties.WriteString(fmt.Sprintf("    avb_add_hashtree_footer_args = %q,\n", qualifiedVariables.BoardAvbAddHashtreeFooterArgs))
-		keypath := qualifiedVariables.BoardAvbKeyPath
-		if keypath != "" {
-			extraProperties.WriteString(fmt.Sprintf("    avb_key = \"//%s:%s\",\n", filepath.Dir(keypath), filepath.Base(keypath)+"_filegroup"))
-			extraProperties.WriteString(fmt.Sprintf("    avb_algorithm = %q,\n", qualifiedVariables.BoardAvbAlgorithm))
-			extraProperties.WriteString(fmt.Sprintf("    avb_rollback_index = %s,\n", qualifiedVariables.BoardAvbRollbackIndex))
-			extraProperties.WriteString(fmt.Sprintf("    avb_rollback_index_location = %s,\n", qualifiedVariables.BoardAvbRollbackIndexLocation))
-		}
-	}
-
-	var deps []string
-	for _, mod := range variables.ProductPackages {
-		if path, ok := convertedModulePathMap[mod]; ok && ctx.Config().BazelContext.IsModuleNameAllowed(mod, false) {
-			if partition, ok := moduleNameToPartition[mod]; ok && partition == "system" {
-				if path == "//." {
-					path = "//"
-				}
-				deps = append(deps, fmt.Sprintf("        \"%s:%s\",\n", path, mod))
-			}
-		}
-	}
-	if len(deps) > 0 {
-		sort.Strings(deps)
-		extraProperties.WriteString("    deps = [\n")
-		for _, dep := range deps {
-			extraProperties.WriteString(dep)
-		}
-		extraProperties.WriteString("    ],\n")
-	}
-
-	targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{
-		name:        "system_image",
-		packageName: platformLabel.pkg,
-		content: fmt.Sprintf(`partition(
-    name = "system_image",
-    base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir",
-    base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list",
-    root_dir = "//build/bazel/bazel_sandwich:root_staging_dir",
-    selinux_file_contexts = "//build/bazel/bazel_sandwich:selinux_file_contexts",
-    image_properties = """
-%s
-""",
-%s
-    type = "system",
-)`, properties.String(), extraProperties.String()),
-		ruleClass: "partition",
-		loads: []BazelLoad{{
-			file: "//build/bazel/rules/partitions:partition.bzl",
-			symbols: []BazelLoadSymbol{{
-				symbol: "partition",
-			}},
-		}},
-	}, BazelTarget{
-		name:        "system_image_test",
-		packageName: platformLabel.pkg,
-		content: `partition_diff_test(
-    name = "system_image_test",
-    partition1 = "//build/bazel/bazel_sandwich:make_system_image",
-    partition2 = ":system_image",
-)`,
-		ruleClass: "partition_diff_test",
-		loads: []BazelLoad{{
-			file: "//build/bazel/rules/partitions/diff:partition_diff.bzl",
-			symbols: []BazelLoadSymbol{{
-				symbol: "partition_diff_test",
-			}},
-		}},
-	}, BazelTarget{
-		name:        "run_system_image_test",
-		packageName: platformLabel.pkg,
-		content: `run_test_in_build(
-    name = "run_system_image_test",
-    test = ":system_image_test",
-)`,
-		ruleClass: "run_test_in_build",
-		loads: []BazelLoad{{
-			file: "//build/bazel/bazel_sandwich:run_test_in_build.bzl",
-			symbols: []BazelLoadSymbol{{
-				symbol: "run_test_in_build",
-			}},
-		}},
-	})
-}
-
-var allPartitionTypes = []string{
-	"system",
-	"vendor",
-	"cache",
-	"userdata",
-	"product",
-	"system_ext",
-	"oem",
-	"odm",
-	"vendor_dlkm",
-	"odm_dlkm",
-	"system_dlkm",
-}
-
-// An equivalent of make's generate-image-prop-dictionary function
-func generateImagePropDictionary(variables *android.PartitionVariables, partitionType string) map[string]string {
-	partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
-	if !ok {
-		panic("Unknown partitionType: " + partitionType)
-	}
-	ret := map[string]string{}
-	if partitionType == "system" {
-		if len(variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize) > 0 {
-			ret["system_other_size"] = variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize
-		}
-		if len(partitionQualifiedVariables.ProductHeadroom) > 0 {
-			ret["system_headroom"] = partitionQualifiedVariables.ProductHeadroom
-		}
-		addCommonRoFlagsToImageProps(variables, partitionType, ret)
-	}
-	// TODO: other partition-specific logic
-	if variables.TargetUserimagesUseExt2 {
-		ret["fs_type"] = "ext2"
-	} else if variables.TargetUserimagesUseExt3 {
-		ret["fs_type"] = "ext3"
-	} else if variables.TargetUserimagesUseExt4 {
-		ret["fs_type"] = "ext4"
-	}
-
-	if !variables.TargetUserimagesSparseExtDisabled {
-		ret["extfs_sparse_flag"] = "-s"
-	}
-	if !variables.TargetUserimagesSparseErofsDisabled {
-		ret["erofs_sparse_flag"] = "-s"
-	}
-	if !variables.TargetUserimagesSparseSquashfsDisabled {
-		ret["squashfs_sparse_flag"] = "-s"
-	}
-	if !variables.TargetUserimagesSparseF2fsDisabled {
-		ret["f2fs_sparse_flag"] = "-S"
-	}
-	erofsCompressor := variables.BoardErofsCompressor
-	if len(erofsCompressor) == 0 && hasErofsPartition(variables) {
-		if len(variables.BoardErofsUseLegacyCompression) > 0 {
-			erofsCompressor = "lz4"
-		} else {
-			erofsCompressor = "lz4hc,9"
-		}
-	}
-	if len(erofsCompressor) > 0 {
-		ret["erofs_default_compressor"] = erofsCompressor
-	}
-	if len(variables.BoardErofsCompressorHints) > 0 {
-		ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
-	}
-	if len(variables.BoardErofsCompressorHints) > 0 {
-		ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
-	}
-	if len(variables.BoardErofsPclusterSize) > 0 {
-		ret["erofs_pcluster_size"] = variables.BoardErofsPclusterSize
-	}
-	if len(variables.BoardErofsShareDupBlocks) > 0 {
-		ret["erofs_share_dup_blocks"] = variables.BoardErofsShareDupBlocks
-	}
-	if len(variables.BoardErofsUseLegacyCompression) > 0 {
-		ret["erofs_use_legacy_compression"] = variables.BoardErofsUseLegacyCompression
-	}
-	if len(variables.BoardExt4ShareDupBlocks) > 0 {
-		ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
-	}
-	if len(variables.BoardFlashLogicalBlockSize) > 0 {
-		ret["flash_logical_block_size"] = variables.BoardFlashLogicalBlockSize
-	}
-	if len(variables.BoardFlashEraseBlockSize) > 0 {
-		ret["flash_erase_block_size"] = variables.BoardFlashEraseBlockSize
-	}
-	if len(variables.BoardExt4ShareDupBlocks) > 0 {
-		ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
-	}
-	if len(variables.BoardExt4ShareDupBlocks) > 0 {
-		ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
-	}
-	for _, partitionType := range allPartitionTypes {
-		if qualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]; ok && len(qualifiedVariables.ProductVerityPartition) > 0 {
-			ret[partitionType+"_verity_block_device"] = qualifiedVariables.ProductVerityPartition
-		}
-	}
-	// TODO: Vboot
-	// TODO: AVB
-	if variables.BoardUsesRecoveryAsBoot {
-		ret["recovery_as_boot"] = "true"
-	}
-	if variables.ProductUseDynamicPartitionSize {
-		ret["use_dynamic_partition_size"] = "true"
-	}
-	if variables.CopyImagesForTargetFilesZip {
-		ret["use_fixed_timestamp"] = "true"
-	}
-	return ret
-}
-
-// Soong equivalent of make's add-common-ro-flags-to-image-props
-func addCommonRoFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
-	partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
-	if !ok {
-		panic("Unknown partitionType: " + partitionType)
-	}
-	if len(partitionQualifiedVariables.BoardErofsCompressor) > 0 {
-		ret[partitionType+"_erofs_compressor"] = partitionQualifiedVariables.BoardErofsCompressor
-	}
-	if len(partitionQualifiedVariables.BoardErofsCompressHints) > 0 {
-		ret[partitionType+"_erofs_compress_hints"] = partitionQualifiedVariables.BoardErofsCompressHints
-	}
-	if len(partitionQualifiedVariables.BoardErofsPclusterSize) > 0 {
-		ret[partitionType+"_erofs_pcluster_size"] = partitionQualifiedVariables.BoardErofsPclusterSize
-	}
-	if len(partitionQualifiedVariables.BoardExtfsRsvPct) > 0 {
-		ret[partitionType+"_extfs_rsv_pct"] = partitionQualifiedVariables.BoardExtfsRsvPct
-	}
-	if len(partitionQualifiedVariables.BoardF2fsSloadCompressFlags) > 0 {
-		ret[partitionType+"_f2fs_sldc_flags"] = partitionQualifiedVariables.BoardF2fsSloadCompressFlags
-	}
-	if len(partitionQualifiedVariables.BoardFileSystemCompress) > 0 {
-		ret[partitionType+"_f2fs_compress"] = partitionQualifiedVariables.BoardFileSystemCompress
-	}
-	if len(partitionQualifiedVariables.BoardFileSystemType) > 0 {
-		ret[partitionType+"_fs_type"] = partitionQualifiedVariables.BoardFileSystemType
-	}
-	if len(partitionQualifiedVariables.BoardJournalSize) > 0 {
-		ret[partitionType+"_journal_size"] = partitionQualifiedVariables.BoardJournalSize
-	}
-	if len(partitionQualifiedVariables.BoardPartitionReservedSize) > 0 {
-		ret[partitionType+"_reserved_size"] = partitionQualifiedVariables.BoardPartitionReservedSize
-	}
-	if len(partitionQualifiedVariables.BoardPartitionSize) > 0 {
-		ret[partitionType+"_size"] = partitionQualifiedVariables.BoardPartitionSize
-	}
-	if len(partitionQualifiedVariables.BoardSquashfsBlockSize) > 0 {
-		ret[partitionType+"_squashfs_block_size"] = partitionQualifiedVariables.BoardSquashfsBlockSize
-	}
-	if len(partitionQualifiedVariables.BoardSquashfsCompressor) > 0 {
-		ret[partitionType+"_squashfs_compressor"] = partitionQualifiedVariables.BoardSquashfsCompressor
-	}
-	if len(partitionQualifiedVariables.BoardSquashfsCompressorOpt) > 0 {
-		ret[partitionType+"_squashfs_compressor_opt"] = partitionQualifiedVariables.BoardSquashfsCompressorOpt
-	}
-	if len(partitionQualifiedVariables.BoardSquashfsDisable4kAlign) > 0 {
-		ret[partitionType+"_squashfs_disable_4k_align"] = partitionQualifiedVariables.BoardSquashfsDisable4kAlign
-	}
-	if len(partitionQualifiedVariables.BoardPartitionSize) == 0 && len(partitionQualifiedVariables.BoardPartitionReservedSize) == 0 && len(partitionQualifiedVariables.ProductHeadroom) == 0 {
-		ret[partitionType+"_disable_sparse"] = "true"
-	}
-	addCommonFlagsToImageProps(variables, partitionType, ret)
-}
-
-func hasErofsPartition(variables *android.PartitionVariables) bool {
-	return variables.PartitionQualifiedVariables["product"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["system_ext"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["odm"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["vendor"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["system"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["vendor_dlkm"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["odm_dlkm"].BoardFileSystemType == "erofs" ||
-		variables.PartitionQualifiedVariables["system_dlkm"].BoardFileSystemType == "erofs"
-}
-
-// Soong equivalent of make's add-common-flags-to-image-props
-func addCommonFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
-	// The selinux_fc will be handled separately
-	partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
-	if !ok {
-		panic("Unknown partitionType: " + partitionType)
-	}
-	ret["building_"+partitionType+"_image"] = boolToMakeString(partitionQualifiedVariables.BuildingImage)
-}
-
-func boolToMakeString(b bool) string {
-	if b {
-		return "true"
-	}
-	return ""
-}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index d2187ff..af2f550 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -28,10 +28,7 @@
 	"android/soong/android"
 	"android/soong/bazel"
 	"android/soong/starlark_fmt"
-	"android/soong/ui/metrics/bp2build_metrics_proto"
-
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -201,18 +198,13 @@
 type CodegenMode int
 
 const (
-	// Bp2Build - generate BUILD files with targets buildable by Bazel directly.
-	//
-	// This mode is used for the Soong->Bazel build definition conversion.
-	Bp2Build CodegenMode = iota
-
 	// QueryView - generate BUILD files with targets representing fully mutated
 	// Soong modules, representing the fully configured Soong module graph with
 	// variants and dependency edges.
 	//
 	// This mode is used for discovering and introspecting the existing Soong
 	// module graph.
-	QueryView
+	QueryView CodegenMode = iota
 )
 
 type unconvertedDepsMode int
@@ -227,8 +219,6 @@
 
 func (mode CodegenMode) String() string {
 	switch mode {
-	case Bp2Build:
-		return "Bp2Build"
 	case QueryView:
 		return "QueryView"
 	default:
@@ -256,9 +246,6 @@
 // writing BUILD files in the output directory.
 func NewCodegenContext(config android.Config, context *android.Context, mode CodegenMode, topDir string) *CodegenContext {
 	var unconvertedDeps unconvertedDepsMode
-	if config.IsEnvTrue("BP2BUILD_ERROR_UNCONVERTED") {
-		unconvertedDeps = errorModulesUnconvertedDeps
-	}
 	return &CodegenContext{
 		context:            context,
 		config:             config,
@@ -281,526 +268,30 @@
 type conversionResults struct {
 	buildFileToTargets    map[string]BazelTargets
 	moduleNameToPartition map[string]string
-	metrics               CodegenMetrics
 }
 
 func (r conversionResults) BuildDirToTargets() map[string]BazelTargets {
 	return r.buildFileToTargets
 }
 
-// struct to store state of b bazel targets (e.g. go targets which do not implement android.Module)
-// this implements bp2buildModule interface and is passed to generateBazelTargets
-type bTarget struct {
-	targetName            string
-	targetPackage         string
-	bazelRuleClass        string
-	bazelRuleLoadLocation string
-	bazelAttributes       []interface{}
-}
-
-var _ bp2buildModule = (*bTarget)(nil)
-
-func (b bTarget) TargetName() string {
-	return b.targetName
-}
-
-func (b bTarget) TargetPackage() string {
-	return b.targetPackage
-}
-
-func (b bTarget) BazelRuleClass() string {
-	return b.bazelRuleClass
-}
-
-func (b bTarget) BazelRuleLoadLocation() string {
-	return b.bazelRuleLoadLocation
-}
-
-func (b bTarget) BazelAttributes() []interface{} {
-	return b.bazelAttributes
-}
-
-// Creates a target_compatible_with entry that is *not* compatible with android
-func targetNotCompatibleWithAndroid() bazel.LabelListAttribute {
-	ret := bazel.LabelListAttribute{}
-	ret.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid,
-		bazel.MakeLabelList(
-			[]bazel.Label{
-				bazel.Label{
-					Label: "@platforms//:incompatible",
-				},
-			},
-		),
-	)
-	return ret
-}
-
-// helper function to return labels for srcs used in bootstrap_go_package and bootstrap_go_binary
-// this function has the following limitations which make it unsuitable for widespread use
-// - wildcard patterns in srcs
-// This is ok for go since build/blueprint does not support it.
-//
-// Prefer to use `BazelLabelForModuleSrc` instead
-func goSrcLabels(cfg android.Config, moduleDir string, srcs []string, linuxSrcs, darwinSrcs []string) bazel.LabelListAttribute {
-	labels := func(srcs []string) bazel.LabelList {
-		ret := []bazel.Label{}
-		for _, src := range srcs {
-			srcLabel := bazel.Label{
-				Label: src,
-			}
-			ret = append(ret, srcLabel)
-		}
-		// Respect package boundaries
-		return android.TransformSubpackagePaths(
-			cfg,
-			moduleDir,
-			bazel.MakeLabelList(ret),
-		)
-	}
-
-	ret := bazel.LabelListAttribute{}
-	// common
-	ret.SetSelectValue(bazel.NoConfigAxis, "", labels(srcs))
-	// linux
-	ret.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsLinux, labels(linuxSrcs))
-	// darwin
-	ret.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsDarwin, labels(darwinSrcs))
-	return ret
-}
-
-func goDepLabels(deps []string, goModulesMap nameToGoLibraryModule) bazel.LabelListAttribute {
-	labels := []bazel.Label{}
-	for _, dep := range deps {
-		moduleDir := goModulesMap[dep].Dir
-		if moduleDir == "." {
-			moduleDir = ""
-		}
-		label := bazel.Label{
-			Label: fmt.Sprintf("//%s:%s", moduleDir, dep),
-		}
-		labels = append(labels, label)
-	}
-	return bazel.MakeLabelListAttribute(bazel.MakeLabelList(labels))
-}
-
-// attributes common to blueprint_go_binary and bootstap_go_package
-type goAttributes struct {
-	Importpath             bazel.StringAttribute
-	Srcs                   bazel.LabelListAttribute
-	Deps                   bazel.LabelListAttribute
-	Data                   bazel.LabelListAttribute
-	Target_compatible_with bazel.LabelListAttribute
-
-	// attributes for the dynamically generated go_test target
-	Embed bazel.LabelListAttribute
-}
-
-type goTestProperties struct {
-	name           string
-	dir            string
-	testSrcs       []string
-	linuxTestSrcs  []string
-	darwinTestSrcs []string
-	testData       []string
-	// Name of the target that should be compiled together with the test
-	embedName string
-}
-
-// Creates a go_test target for bootstrap_go_package / blueprint_go_binary
-func generateBazelTargetsGoTest(ctx *android.Context, goModulesMap nameToGoLibraryModule, gp goTestProperties) (BazelTarget, error) {
-	ca := android.CommonAttributes{
-		Name: gp.name,
-	}
-	ga := goAttributes{
-		Srcs: goSrcLabels(ctx.Config(), gp.dir, gp.testSrcs, gp.linuxTestSrcs, gp.darwinTestSrcs),
-		Data: goSrcLabels(ctx.Config(), gp.dir, gp.testData, []string{}, []string{}),
-		Embed: bazel.MakeLabelListAttribute(
-			bazel.MakeLabelList(
-				[]bazel.Label{bazel.Label{Label: ":" + gp.embedName}},
-			),
-		),
-		Target_compatible_with: targetNotCompatibleWithAndroid(),
-	}
-
-	libTest := bTarget{
-		targetName:            gp.name,
-		targetPackage:         gp.dir,
-		bazelRuleClass:        "go_test",
-		bazelRuleLoadLocation: "@io_bazel_rules_go//go:def.bzl",
-		bazelAttributes:       []interface{}{&ca, &ga},
-	}
-	return generateBazelTarget(ctx, libTest)
-}
-
-// TODO - b/288491147: testSrcs of certain bootstrap_go_package/blueprint_go_binary are not hermetic and depend on
-// testdata checked into the filesystem.
-// Denylist the generation of go_test targets for these Soong modules.
-// The go_library/go_binary will still be generated, since those are hermitic.
-var (
-	goTestsDenylist = []string{
-		"android-archive-zip",
-		"bazel_notice_gen",
-		"blueprint-bootstrap-bpdoc",
-		"blueprint-microfactory",
-		"blueprint-pathtools",
-		"bssl_ar",
-		"compliance_checkmetadata",
-		"compliance_checkshare",
-		"compliance_dumpgraph",
-		"compliance_dumpresolutions",
-		"compliance_listshare",
-		"compliance-module",
-		"compliancenotice_bom",
-		"compliancenotice_shippedlibs",
-		"compliance_rtrace",
-		"compliance_sbom",
-		"golang-protobuf-internal-fuzz-jsonfuzz",
-		"golang-protobuf-internal-fuzz-textfuzz",
-		"golang-protobuf-internal-fuzz-wirefuzz",
-		"htmlnotice",
-		"protoc-gen-go",
-		"rbcrun-module",
-		"spdx-tools-builder",
-		"spdx-tools-builder2v1",
-		"spdx-tools-builder2v2",
-		"spdx-tools-builder2v3",
-		"spdx-tools-idsearcher",
-		"spdx-tools-spdx-json",
-		"spdx-tools-utils",
-		"soong-ui-build",
-		"textnotice",
-		"xmlnotice",
-	}
-)
-
-func testOfGoPackageIsIncompatible(g *bootstrap.GoPackage) bool {
-	return android.InList(g.Name(), goTestsDenylist) ||
-		// Denylist tests of soong_build
-		// Theses tests have a guard that prevent usage outside a test environment
-		// The guard (`ensureTestOnly`) looks for a `-test` in os.Args, which is present in soong's gotestrunner, but missing in `b test`
-		g.IsPluginFor("soong_build") ||
-		// soong-android is a dep of soong_build
-		// This dependency is created by soong_build by listing it in its deps explicitly in Android.bp, and not via `plugin_for` in `soong-android`
-		g.Name() == "soong-android"
-}
-
-func testOfGoBinaryIsIncompatible(g *bootstrap.GoBinary) bool {
-	return android.InList(g.Name(), goTestsDenylist)
-}
-
-func generateBazelTargetsGoPackage(ctx *android.Context, g *bootstrap.GoPackage, goModulesMap nameToGoLibraryModule) ([]BazelTarget, []error) {
-	ca := android.CommonAttributes{
-		Name: g.Name(),
-	}
-
-	// For this bootstrap_go_package dep chain,
-	// A --> B --> C ( ---> depends on)
-	// Soong provides the convenience of only listing B as deps of A even if a src file of A imports C
-	// Bazel OTOH
-	// 1. requires C to be listed in `deps` expllicity.
-	// 2. does not require C to be listed if src of A does not import C
-	//
-	// bp2build does not have sufficient info on whether C is a direct dep of A or not, so for now collect all transitive deps and add them to deps
-	transitiveDeps := transitiveGoDeps(g.Deps(), goModulesMap)
-
-	ga := goAttributes{
-		Importpath: bazel.StringAttribute{
-			Value: proptools.StringPtr(g.GoPkgPath()),
-		},
-		Srcs: goSrcLabels(ctx.Config(), ctx.ModuleDir(g), g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs()),
-		Deps: goDepLabels(
-			android.FirstUniqueStrings(transitiveDeps),
-			goModulesMap,
-		),
-		Target_compatible_with: targetNotCompatibleWithAndroid(),
-	}
-
-	lib := bTarget{
-		targetName:            g.Name(),
-		targetPackage:         ctx.ModuleDir(g),
-		bazelRuleClass:        "go_library",
-		bazelRuleLoadLocation: "@io_bazel_rules_go//go:def.bzl",
-		bazelAttributes:       []interface{}{&ca, &ga},
-	}
-	retTargets := []BazelTarget{}
-	var retErrs []error
-	if libTarget, err := generateBazelTarget(ctx, lib); err == nil {
-		retTargets = append(retTargets, libTarget)
-	} else {
-		retErrs = []error{err}
-	}
-
-	// If the library contains test srcs, create an additional go_test target
-	if !testOfGoPackageIsIncompatible(g) && (len(g.TestSrcs()) > 0 || len(g.LinuxTestSrcs()) > 0 || len(g.DarwinTestSrcs()) > 0) {
-		gp := goTestProperties{
-			name:           g.Name() + "-test",
-			dir:            ctx.ModuleDir(g),
-			testSrcs:       g.TestSrcs(),
-			linuxTestSrcs:  g.LinuxTestSrcs(),
-			darwinTestSrcs: g.DarwinTestSrcs(),
-			testData:       g.TestData(),
-			embedName:      g.Name(), // embed the source go_library in the test so that its .go files are included in the compilation unit
-		}
-		if libTestTarget, err := generateBazelTargetsGoTest(ctx, goModulesMap, gp); err == nil {
-			retTargets = append(retTargets, libTestTarget)
-		} else {
-			retErrs = append(retErrs, err)
-		}
-	}
-
-	return retTargets, retErrs
-}
-
-type goLibraryModule struct {
-	Dir  string
-	Deps []string
-}
-
-type buildConversionMetadata struct {
-	nameToGoLibraryModule nameToGoLibraryModule
-	ndkHeaders            []blueprint.Module
-}
-
-type nameToGoLibraryModule map[string]goLibraryModule
-
-// Visit each module in the graph, and collect metadata about the build graph
-// If a module is of type `bootstrap_go_package`, return a map containing metadata like its dir and deps
-// If a module is of type `ndk_headers`, add it to a list and return the list
-func createBuildConversionMetadata(ctx *android.Context) buildConversionMetadata {
-	goMap := nameToGoLibraryModule{}
-	ndkHeaders := []blueprint.Module{}
-	ctx.VisitAllModules(func(m blueprint.Module) {
-		moduleType := ctx.ModuleType(m)
-		// We do not need to store information about blueprint_go_binary since it does not have any rdeps
-		if moduleType == "bootstrap_go_package" {
-			goMap[m.Name()] = goLibraryModule{
-				Dir:  ctx.ModuleDir(m),
-				Deps: m.(*bootstrap.GoPackage).Deps(),
-			}
-		} else if moduleType == "ndk_headers" || moduleType == "versioned_ndk_headers" {
-			ndkHeaders = append(ndkHeaders, m)
-		}
-	})
-	return buildConversionMetadata{
-		nameToGoLibraryModule: goMap,
-		ndkHeaders:            ndkHeaders,
-	}
-}
-
-// Returns the deps in the transitive closure of a go target
-func transitiveGoDeps(directDeps []string, goModulesMap nameToGoLibraryModule) []string {
-	allDeps := directDeps
-	i := 0
-	for i < len(allDeps) {
-		curr := allDeps[i]
-		allDeps = append(allDeps, goModulesMap[curr].Deps...)
-		i += 1
-	}
-	allDeps = android.SortedUniqueStrings(allDeps)
-	return allDeps
-}
-
-func generateBazelTargetsGoBinary(ctx *android.Context, g *bootstrap.GoBinary, goModulesMap nameToGoLibraryModule) ([]BazelTarget, []error) {
-	ca := android.CommonAttributes{
-		Name: g.Name(),
-	}
-
-	retTargets := []BazelTarget{}
-	var retErrs []error
-
-	// For this bootstrap_go_package dep chain,
-	// A --> B --> C ( ---> depends on)
-	// Soong provides the convenience of only listing B as deps of A even if a src file of A imports C
-	// Bazel OTOH
-	// 1. requires C to be listed in `deps` expllicity.
-	// 2. does not require C to be listed if src of A does not import C
-	//
-	// bp2build does not have sufficient info on whether C is a direct dep of A or not, so for now collect all transitive deps and add them to deps
-	transitiveDeps := transitiveGoDeps(g.Deps(), goModulesMap)
-
-	goSource := ""
-	// If the library contains test srcs, create an additional go_test target
-	// The go_test target will embed a go_source containining the source .go files it tests
-	if !testOfGoBinaryIsIncompatible(g) && (len(g.TestSrcs()) > 0 || len(g.LinuxTestSrcs()) > 0 || len(g.DarwinTestSrcs()) > 0) {
-		// Create a go_source containing the source .go files of go_library
-		// This target will be an `embed` of the go_binary and go_test
-		goSource = g.Name() + "-source"
-		ca := android.CommonAttributes{
-			Name: goSource,
-		}
-		ga := goAttributes{
-			Srcs:                   goSrcLabels(ctx.Config(), ctx.ModuleDir(g), g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs()),
-			Deps:                   goDepLabels(transitiveDeps, goModulesMap),
-			Target_compatible_with: targetNotCompatibleWithAndroid(),
-		}
-		libTestSource := bTarget{
-			targetName:            goSource,
-			targetPackage:         ctx.ModuleDir(g),
-			bazelRuleClass:        "go_source",
-			bazelRuleLoadLocation: "@io_bazel_rules_go//go:def.bzl",
-			bazelAttributes:       []interface{}{&ca, &ga},
-		}
-		if libSourceTarget, err := generateBazelTarget(ctx, libTestSource); err == nil {
-			retTargets = append(retTargets, libSourceTarget)
-		} else {
-			retErrs = append(retErrs, err)
-		}
-
-		// Create a go_test target
-		gp := goTestProperties{
-			name:           g.Name() + "-test",
-			dir:            ctx.ModuleDir(g),
-			testSrcs:       g.TestSrcs(),
-			linuxTestSrcs:  g.LinuxTestSrcs(),
-			darwinTestSrcs: g.DarwinTestSrcs(),
-			testData:       g.TestData(),
-			// embed the go_source in the test
-			embedName: g.Name() + "-source",
-		}
-		if libTestTarget, err := generateBazelTargetsGoTest(ctx, goModulesMap, gp); err == nil {
-			retTargets = append(retTargets, libTestTarget)
-		} else {
-			retErrs = append(retErrs, err)
-		}
-
-	}
-
-	// Create a go_binary target
-	ga := goAttributes{
-		Deps:                   goDepLabels(transitiveDeps, goModulesMap),
-		Target_compatible_with: targetNotCompatibleWithAndroid(),
-	}
-
-	// If the binary has testSrcs, embed the common `go_source`
-	if goSource != "" {
-		ga.Embed = bazel.MakeLabelListAttribute(
-			bazel.MakeLabelList(
-				[]bazel.Label{bazel.Label{Label: ":" + goSource}},
-			),
-		)
-	} else {
-		ga.Srcs = goSrcLabels(ctx.Config(), ctx.ModuleDir(g), g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs())
-	}
-
-	bin := bTarget{
-		targetName:            g.Name(),
-		targetPackage:         ctx.ModuleDir(g),
-		bazelRuleClass:        "go_binary",
-		bazelRuleLoadLocation: "@io_bazel_rules_go//go:def.bzl",
-		bazelAttributes:       []interface{}{&ca, &ga},
-	}
-
-	if binTarget, err := generateBazelTarget(ctx, bin); err == nil {
-		retTargets = append(retTargets, binTarget)
-	} else {
-		retErrs = []error{err}
-	}
-
-	return retTargets, retErrs
-}
-
 func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
 	ctx.Context().BeginEvent("GenerateBazelTargets")
 	defer ctx.Context().EndEvent("GenerateBazelTargets")
 	buildFileToTargets := make(map[string]BazelTargets)
 
-	// Simple metrics tracking for bp2build
-	metrics := CreateCodegenMetrics()
-
 	dirs := make(map[string]bool)
 	moduleNameToPartition := make(map[string]string)
 
 	var errs []error
 
-	// Visit go libraries in a pre-run and store its state in a map
-	// The time complexity remains O(N), and this does not add significant wall time.
-	meta := createBuildConversionMetadata(ctx.Context())
-	nameToGoLibMap := meta.nameToGoLibraryModule
-	ndkHeaders := meta.ndkHeaders
-
 	bpCtx := ctx.Context()
 	bpCtx.VisitAllModules(func(m blueprint.Module) {
 		dir := bpCtx.ModuleDir(m)
-		moduleType := bpCtx.ModuleType(m)
 		dirs[dir] = true
 
 		var targets []BazelTarget
-		var targetErrs []error
 
 		switch ctx.Mode() {
-		case Bp2Build:
-			if aModule, ok := m.(android.Module); ok {
-				reason := aModule.GetUnconvertedReason()
-				if reason != nil {
-					// If this module was force-enabled, cause an error.
-					if _, ok := ctx.Config().BazelModulesForceEnabledByFlag()[m.Name()]; ok && m.Name() != "" {
-						err := fmt.Errorf("Force Enabled Module %s not converted", m.Name())
-						errs = append(errs, err)
-					}
-
-					// Log the module isn't to be converted by bp2build.
-					// TODO: b/291598248 - Log handcrafted modules differently than other unconverted modules.
-					metrics.AddUnconvertedModule(m, moduleType, dir, *reason)
-					return
-				}
-				if len(aModule.Bp2buildTargets()) == 0 {
-					panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", aModule.Name()))
-				}
-
-				// Handle modules converted to generated targets.
-				targets, targetErrs = generateBazelTargets(bpCtx, aModule)
-				errs = append(errs, targetErrs...)
-				for _, t := range targets {
-					// A module can potentially generate more than 1 Bazel
-					// target, each of a different rule class.
-					metrics.IncrementRuleClassCount(t.ruleClass)
-				}
-
-				// record the partition
-				moduleNameToPartition[android.RemoveOptionalPrebuiltPrefix(aModule.Name())] = aModule.GetPartitionForBp2build()
-
-				// Log the module.
-				metrics.AddConvertedModule(aModule, moduleType, dir)
-
-				// Handle modules with unconverted deps. By default, emit a warning.
-				if unconvertedDeps := aModule.GetUnconvertedBp2buildDeps(); len(unconvertedDeps) > 0 {
-					msg := fmt.Sprintf("%s %s:%s depends on unconverted modules: %s",
-						moduleType, bpCtx.ModuleDir(m), m.Name(), strings.Join(unconvertedDeps, ", "))
-					switch ctx.unconvertedDepMode {
-					case warnUnconvertedDeps:
-						metrics.moduleWithUnconvertedDepsMsgs = append(metrics.moduleWithUnconvertedDepsMsgs, msg)
-					case errorModulesUnconvertedDeps:
-						errs = append(errs, fmt.Errorf(msg))
-						return
-					}
-				}
-				if unconvertedDeps := aModule.GetMissingBp2buildDeps(); len(unconvertedDeps) > 0 {
-					msg := fmt.Sprintf("%s %s:%s depends on missing modules: %s",
-						moduleType, bpCtx.ModuleDir(m), m.Name(), strings.Join(unconvertedDeps, ", "))
-					switch ctx.unconvertedDepMode {
-					case warnUnconvertedDeps:
-						metrics.moduleWithMissingDepsMsgs = append(metrics.moduleWithMissingDepsMsgs, msg)
-					case errorModulesUnconvertedDeps:
-						errs = append(errs, fmt.Errorf(msg))
-						return
-					}
-				}
-			} else if glib, ok := m.(*bootstrap.GoPackage); ok {
-				targets, targetErrs = generateBazelTargetsGoPackage(bpCtx, glib, nameToGoLibMap)
-				errs = append(errs, targetErrs...)
-				metrics.IncrementRuleClassCount("bootstrap_go_package")
-				metrics.AddConvertedModule(glib, "bootstrap_go_package", dir)
-			} else if gbin, ok := m.(*bootstrap.GoBinary); ok {
-				targets, targetErrs = generateBazelTargetsGoBinary(bpCtx, gbin, nameToGoLibMap)
-				errs = append(errs, targetErrs...)
-				metrics.IncrementRuleClassCount("blueprint_go_binary")
-				metrics.AddConvertedModule(gbin, "blueprint_go_binary", dir)
-			} else {
-				metrics.AddUnconvertedModule(m, moduleType, dir, android.UnconvertedReason{
-					ReasonType: int(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED),
-				})
-				return
-			}
 		case QueryView:
 			// Blocklist certain module types from being generated.
 			if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" {
@@ -824,37 +315,6 @@
 		}
 	})
 
-	// Create an ndk_sysroot target that has a dependency edge on every target corresponding to Soong's ndk_headers
-	// This root target will provide headers to sdk variants of jni libraries
-	if ctx.Mode() == Bp2Build {
-		var depLabels bazel.LabelList
-		for _, ndkHeader := range ndkHeaders {
-			depLabel := bazel.Label{
-				Label: "//" + bpCtx.ModuleDir(ndkHeader) + ":" + ndkHeader.Name(),
-			}
-			depLabels.Add(&depLabel)
-		}
-		a := struct {
-			Deps bazel.LabelListAttribute
-		}{
-			Deps: bazel.MakeLabelListAttribute(bazel.UniqueSortedBazelLabelList(depLabels)),
-		}
-		ndkSysroot := bTarget{
-			targetName:            "ndk_sysroot",
-			targetPackage:         "build/bazel/rules/cc", // The location is subject to change, use build/bazel for now
-			bazelRuleClass:        "cc_library_headers",
-			bazelRuleLoadLocation: "//build/bazel/rules/cc:cc_library_headers.bzl",
-			bazelAttributes:       []interface{}{&a},
-		}
-
-		if t, err := generateBazelTarget(bpCtx, ndkSysroot); err == nil {
-			dir := ndkSysroot.targetPackage
-			buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
-		} else {
-			errs = append(errs, err)
-		}
-	}
-
 	if len(errs) > 0 {
 		return conversionResults{}, errs
 	}
@@ -883,72 +343,9 @@
 	return conversionResults{
 		buildFileToTargets:    buildFileToTargets,
 		moduleNameToPartition: moduleNameToPartition,
-		metrics:               metrics,
 	}, errs
 }
 
-func generateBazelTargets(ctx bpToBuildContext, m android.Module) ([]BazelTarget, []error) {
-	var targets []BazelTarget
-	var errs []error
-	for _, m := range m.Bp2buildTargets() {
-		target, err := generateBazelTarget(ctx, m)
-		if err != nil {
-			errs = append(errs, err)
-			return targets, errs
-		}
-		targets = append(targets, target)
-	}
-	return targets, errs
-}
-
-type bp2buildModule interface {
-	TargetName() string
-	TargetPackage() string
-	BazelRuleClass() string
-	BazelRuleLoadLocation() string
-	BazelAttributes() []interface{}
-}
-
-func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) (BazelTarget, error) {
-	ruleClass := m.BazelRuleClass()
-	bzlLoadLocation := m.BazelRuleLoadLocation()
-
-	// extract the bazel attributes from the module.
-	attrs := m.BazelAttributes()
-	props, err := extractModuleProperties(attrs, true)
-	if err != nil {
-		return BazelTarget{}, err
-	}
-
-	// name is handled in a special manner
-	delete(props.Attrs, "name")
-
-	// Return the Bazel target with rule class and attributes, ready to be
-	// code-generated.
-	attributes := propsToAttributes(props.Attrs)
-	var content string
-	targetName := m.TargetName()
-	if targetName != "" {
-		content = fmt.Sprintf(ruleTargetTemplate, ruleClass, targetName, attributes)
-	} else {
-		content = fmt.Sprintf(unnamedRuleTargetTemplate, ruleClass, attributes)
-	}
-	var loads []BazelLoad
-	if bzlLoadLocation != "" {
-		loads = append(loads, BazelLoad{
-			file:    bzlLoadLocation,
-			symbols: []BazelLoadSymbol{{symbol: ruleClass}},
-		})
-	}
-	return BazelTarget{
-		name:        targetName,
-		packageName: m.TargetPackage(),
-		ruleClass:   ruleClass,
-		loads:       loads,
-		content:     content,
-	}, nil
-}
-
 // Convert a module and its deps and props into a Bazel macro/rule
 // representation in the BUILD file.
 func generateSoongModuleTarget(ctx bpToBuildContext, m blueprint.Module) (BazelTarget, error) {
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index be3c7ff..9f1aa09 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -1,15 +1,10 @@
 package bp2build
 
 import (
-	"encoding/json"
-	"fmt"
 	"reflect"
-	"strconv"
 	"strings"
 
 	"android/soong/android"
-	"android/soong/starlark_fmt"
-
 	"github.com/google/blueprint/proptools"
 )
 
@@ -19,79 +14,6 @@
 	Contents string
 }
 
-// createSoongInjectionDirFiles returns most of the files to write to the soong_injection directory.
-// Some other files also come from CreateProductConfigFiles
-func createSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, error) {
-	cfg := ctx.Config()
-	var files []BazelFile
-
-	files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
-	files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg)))
-
-	if buf, err := json.MarshalIndent(metrics.convertedModuleWithType, "", "  "); err != nil {
-		return []BazelFile{}, err
-	} else {
-		files = append(files, newFile("metrics", "converted_modules.json", string(buf)))
-	}
-
-	convertedModulePathMap, err := json.MarshalIndent(metrics.convertedModulePathMap, "", "\t")
-	if err != nil {
-		panic(err)
-	}
-	files = append(files, newFile("metrics", GeneratedBuildFileName, "")) // Creates a //metrics package.
-	files = append(files, newFile("metrics", "converted_modules_path_map.json", string(convertedModulePathMap)))
-	files = append(files, newFile("metrics", "converted_modules_path_map.bzl", "modules = "+strings.ReplaceAll(string(convertedModulePathMap), "\\", "\\\\")))
-
-	files = append(files, newFile("product_config", "soong_config_variables.bzl", cfg.Bp2buildSoongConfigDefinitions.String()))
-
-	files = append(files, newFile("product_config", "arch_configuration.bzl", android.StarlarkArchConfigurations()))
-
-	apiLevelsMap, err := android.GetApiLevelsMap(cfg)
-	if err != nil {
-		return nil, err
-	}
-	apiLevelsContent, err := json.Marshal(apiLevelsMap)
-	if err != nil {
-		return nil, err
-	}
-	files = append(files, newFile("api_levels", GeneratedBuildFileName, `exports_files(["api_levels.json"])`))
-	// TODO(b/269691302)  value of apiLevelsContent is product variable dependent and should be avoided for soong injection
-	files = append(files, newFile("api_levels", "api_levels.json", string(apiLevelsContent)))
-	files = append(files, newFile("api_levels", "platform_versions.bzl", platformVersionContents(cfg)))
-
-	files = append(files, newFile("allowlists", GeneratedBuildFileName, ""))
-	// TODO(b/262781701): Create an alternate soong_build entrypoint for writing out these files only when requested
-	files = append(files, newFile("allowlists", "mixed_build_prod_allowlist.txt", strings.Join(android.GetBazelEnabledModules(android.BazelProdMode), "\n")+"\n"))
-	files = append(files, newFile("allowlists", "mixed_build_staging_allowlist.txt", strings.Join(android.GetBazelEnabledModules(android.BazelStagingMode), "\n")+"\n"))
-
-	return files, nil
-}
-
-func platformVersionContents(cfg android.Config) string {
-	// Despite these coming from cfg.productVariables, they are actually hardcoded in global
-	// makefiles, not set in individual product config makesfiles, so they're safe to just export
-	// and load() directly.
-
-	platformVersionActiveCodenames := make([]string, 0, len(cfg.PlatformVersionActiveCodenames()))
-	for _, codename := range cfg.PlatformVersionActiveCodenames() {
-		platformVersionActiveCodenames = append(platformVersionActiveCodenames, fmt.Sprintf("%q", codename))
-	}
-
-	platformSdkVersion := "None"
-	if cfg.RawPlatformSdkVersion() != nil {
-		platformSdkVersion = strconv.Itoa(*cfg.RawPlatformSdkVersion())
-	}
-
-	return fmt.Sprintf(`
-platform_versions = struct(
-    platform_sdk_final = %s,
-    platform_sdk_version = %s,
-    platform_sdk_codename = %q,
-    platform_version_active_codenames = [%s],
-)
-`, starlark_fmt.PrintBool(cfg.PlatformSdkFinal()), platformSdkVersion, cfg.PlatformSdkCodename(), strings.Join(platformVersionActiveCodenames, ", "))
-}
-
 func CreateBazelFiles(ruleShims map[string]RuleShim, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
 	var files []BazelFile
 
@@ -125,20 +47,7 @@
 		targets.sort()
 
 		var content string
-		if mode == Bp2Build {
-			content = `# READ THIS FIRST:
-# This file was automatically generated by bp2build for the Bazel migration project.
-# Feel free to edit or test it, but do *not* check it into your version control system.
-`
-			content += targets.LoadStatements()
-			content += "\n\n"
-			// Get package rule from the handcrafted BUILD file, otherwise emit the default one.
-			prText := "package(default_visibility = [\"//visibility:public\"])\n"
-			if pr := targets.packageRule(); pr != nil {
-				prText = pr.content
-			}
-			content += prText
-		} else if mode == QueryView {
+		if mode == QueryView {
 			content = soongModuleLoad
 		}
 		if content != "" {
@@ -161,14 +70,6 @@
 
 const (
 	bazelRulesSubDir = "build/bazel/queryview_rules"
-
-	// additional files:
-	//  * workspace file
-	//  * base BUILD file
-	//  * rules BUILD file
-	//  * rules providers.bzl file
-	//  * rules soong_module.bzl file
-	numAdditionalFiles = 5
 )
 
 var (
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
deleted file mode 100644
index 20002c6..0000000
--- a/bp2build/metrics.go
+++ /dev/null
@@ -1,231 +0,0 @@
-package bp2build
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"android/soong/android"
-	"android/soong/shared"
-	"android/soong/ui/metrics/bp2build_metrics_proto"
-
-	"google.golang.org/protobuf/proto"
-
-	"github.com/google/blueprint"
-)
-
-type moduleInfo struct {
-	Name string `json:"name"`
-	Type string `json:"type"`
-}
-
-// CodegenMetrics represents information about the Blueprint-to-BUILD
-// conversion process.
-// Use CreateCodegenMetrics() to get a properly initialized instance
-type CodegenMetrics struct {
-	serialized *bp2build_metrics_proto.Bp2BuildMetrics
-	// List of modules with unconverted deps
-	// NOTE: NOT in the .proto
-	moduleWithUnconvertedDepsMsgs []string
-
-	// List of modules with missing deps
-	// NOTE: NOT in the .proto
-	moduleWithMissingDepsMsgs []string
-
-	// Map of converted modules and paths to call
-	// NOTE: NOT in the .proto
-	convertedModulePathMap map[string]string
-
-	// Name and type of converted modules
-	convertedModuleWithType []moduleInfo
-}
-
-func CreateCodegenMetrics() CodegenMetrics {
-	return CodegenMetrics{
-		serialized: &bp2build_metrics_proto.Bp2BuildMetrics{
-			RuleClassCount:           make(map[string]uint64),
-			ConvertedModuleTypeCount: make(map[string]uint64),
-			TotalModuleTypeCount:     make(map[string]uint64),
-			UnconvertedModules:       make(map[string]*bp2build_metrics_proto.UnconvertedReason),
-		},
-		convertedModulePathMap: make(map[string]string),
-	}
-}
-
-// Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics
-func (metrics *CodegenMetrics) Serialize() *bp2build_metrics_proto.Bp2BuildMetrics {
-	return metrics.serialized
-}
-
-// Print the codegen metrics to stdout.
-func (metrics *CodegenMetrics) Print() {
-	generatedTargetCount := uint64(0)
-	for _, ruleClass := range android.SortedKeys(metrics.serialized.RuleClassCount) {
-		count := metrics.serialized.RuleClassCount[ruleClass]
-		fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count)
-		generatedTargetCount += count
-	}
-	fmt.Printf(
-		`[bp2build] Converted %d Android.bp modules to %d total generated BUILD targets. Included %d handcrafted BUILD targets. There are %d total Android.bp modules.
-%d converted modules have unconverted deps:
-	%s
-%d converted modules have missing deps:
-	%s
-`,
-		metrics.serialized.GeneratedModuleCount,
-		generatedTargetCount,
-		metrics.serialized.HandCraftedModuleCount,
-		metrics.TotalModuleCount(),
-		len(metrics.moduleWithUnconvertedDepsMsgs),
-		strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"),
-		len(metrics.moduleWithMissingDepsMsgs),
-		strings.Join(metrics.moduleWithMissingDepsMsgs, "\n\t"),
-	)
-}
-
-const bp2buildMetricsFilename = "bp2build_metrics.pb"
-
-// fail prints $PWD to stderr, followed by the given printf string and args (vals),
-// then the given alert, and then exits with 1 for failure
-func fail(err error, alertFmt string, vals ...interface{}) {
-	cwd, wderr := os.Getwd()
-	if wderr != nil {
-		cwd = "FAILED TO GET $PWD: " + wderr.Error()
-	}
-	fmt.Fprintf(os.Stderr, "\nIn "+cwd+":\n"+alertFmt+"\n"+err.Error()+"\n", vals...)
-	os.Exit(1)
-}
-
-// Write the bp2build-protoized codegen metrics into the given directory
-func (metrics *CodegenMetrics) Write(dir string) {
-	if _, err := os.Stat(dir); os.IsNotExist(err) {
-		// The metrics dir doesn't already exist, so create it (and parents)
-		if err := os.MkdirAll(dir, 0755); err != nil { // rx for all; w for user
-			fail(err, "Failed to `mkdir -p` %s", dir)
-		}
-	} else if err != nil {
-		fail(err, "Failed to `stat` %s", dir)
-	}
-	metricsFile := filepath.Join(dir, bp2buildMetricsFilename)
-	if err := metrics.dump(metricsFile); err != nil {
-		fail(err, "Error outputting %s", metricsFile)
-	}
-	if _, err := os.Stat(metricsFile); err != nil {
-		if os.IsNotExist(err) {
-			fail(err, "MISSING BP2BUILD METRICS OUTPUT: %s", metricsFile)
-		} else {
-			fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile)
-		}
-	}
-}
-
-// ReadCodegenMetrics loads CodegenMetrics from `dir`
-// returns a nil pointer if the file doesn't exist
-func ReadCodegenMetrics(dir string) *CodegenMetrics {
-	metricsFile := filepath.Join(dir, bp2buildMetricsFilename)
-	if _, err := os.Stat(metricsFile); err != nil {
-		if os.IsNotExist(err) {
-			return nil
-		} else {
-			fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile)
-			panic("unreachable after fail")
-		}
-	}
-	if buf, err := os.ReadFile(metricsFile); err != nil {
-		fail(err, "FAILED TO READ BP2BUILD METRICS OUTPUT: %s", metricsFile)
-		panic("unreachable after fail")
-	} else {
-		bp2BuildMetrics := bp2build_metrics_proto.Bp2BuildMetrics{
-			RuleClassCount:           make(map[string]uint64),
-			ConvertedModuleTypeCount: make(map[string]uint64),
-			TotalModuleTypeCount:     make(map[string]uint64),
-		}
-		if err := proto.Unmarshal(buf, &bp2BuildMetrics); err != nil {
-			fail(err, "FAILED TO PARSE BP2BUILD METRICS OUTPUT: %s", metricsFile)
-		}
-		return &CodegenMetrics{
-			serialized:             &bp2BuildMetrics,
-			convertedModulePathMap: make(map[string]string),
-		}
-	}
-}
-
-func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) {
-	metrics.serialized.RuleClassCount[ruleClass] += 1
-}
-
-func (metrics *CodegenMetrics) AddEvent(event *bp2build_metrics_proto.Event) {
-	metrics.serialized.Events = append(metrics.serialized.Events, event)
-}
-
-func (metrics *CodegenMetrics) SetSymlinkCount(n uint64) {
-	if m := metrics.serialized.WorkspaceSymlinkCount; m != 0 {
-		fmt.Fprintf(os.Stderr, "unexpected non-zero workspaceSymlinkCount of %d", m)
-	}
-	metrics.serialized.WorkspaceSymlinkCount = n
-}
-
-func (metrics *CodegenMetrics) SetMkDirCount(n uint64) {
-	if m := metrics.serialized.WorkspaceMkDirCount; m != 0 {
-		fmt.Fprintf(os.Stderr, "unexpected non-zero workspaceDirCount of %d", m)
-	}
-	metrics.serialized.WorkspaceMkDirCount = n
-}
-
-func (metrics *CodegenMetrics) TotalModuleCount() uint64 {
-	return metrics.serialized.HandCraftedModuleCount +
-		metrics.serialized.GeneratedModuleCount +
-		metrics.serialized.UnconvertedModuleCount
-}
-
-// Dump serializes the metrics to the given filename
-func (metrics *CodegenMetrics) dump(filename string) (err error) {
-	ser := metrics.Serialize()
-	return shared.Save(ser, filename)
-}
-
-type ConversionType int
-
-const (
-	Generated ConversionType = iota
-	Handcrafted
-)
-
-func (metrics *CodegenMetrics) AddConvertedModule(m blueprint.Module, moduleType string, dir string) {
-	//a package module has empty name
-	if moduleType == "package" {
-		return
-	}
-	// Undo prebuilt_ module name prefix modifications
-	moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
-	metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName)
-	metrics.convertedModuleWithType = append(metrics.convertedModuleWithType, moduleInfo{
-		moduleName,
-		moduleType,
-	})
-	metrics.convertedModulePathMap[moduleName] = "//" + dir
-	metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1
-	metrics.serialized.TotalModuleTypeCount[moduleType] += 1
-	metrics.serialized.GeneratedModuleCount += 1
-}
-
-func (metrics *CodegenMetrics) AddUnconvertedModule(m blueprint.Module, moduleType string, dir string,
-	reason android.UnconvertedReason) {
-	//a package module has empty name
-	if moduleType == "package" {
-		return
-	}
-	// Undo prebuilt_ module name prefix modifications
-	moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
-	metrics.serialized.UnconvertedModules[moduleName] = &bp2build_metrics_proto.UnconvertedReason{
-		Type:   bp2build_metrics_proto.UnconvertedReasonType(reason.ReasonType),
-		Detail: reason.Detail,
-	}
-	metrics.serialized.UnconvertedModuleCount += 1
-	metrics.serialized.TotalModuleTypeCount[moduleType] += 1
-
-	if reason.ReasonType == int(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE) {
-		metrics.serialized.HandCraftedModuleCount += 1
-	}
-}
diff --git a/bp2build/performance_test.go b/bp2build/performance_test.go
deleted file mode 100644
index 5f80b83..0000000
--- a/bp2build/performance_test.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2021 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-// to run the benchmarks in this file, you must run go test with the -bench.
-// The benchmarked portion will run for the specified time (can be set via -benchtime)
-// This can mean if you are benchmarking a faster portion of a larger operation, it will take
-// longer.
-// If you are seeing a small number of iterations for a specific run, the data is less reliable, to
-// run for longer, set -benchtime to a larger value.
-
-import (
-	"fmt"
-	"math"
-	"strings"
-	"testing"
-
-	"android/soong/android"
-)
-
-const (
-	performance_test_dir = "."
-)
-
-func genCustomModule(i int, convert bool) string {
-	var conversionString string
-	if convert {
-		conversionString = `bazel_module: { bp2build_available: true },`
-	}
-	return fmt.Sprintf(`
-custom {
-    name: "arch_paths_%[1]d",
-    string_list_prop: ["\t", "\n"],
-    string_prop: "a\t\n\r",
-    arch_paths: ["outer", ":outer_dep_%[1]d"],
-    arch: {
-      x86: {
-        arch_paths: ["abc", ":x86_dep_%[1]d"],
-      },
-      x86_64: {
-        arch_paths: ["64bit"],
-        arch_paths_exclude: ["outer"],
-      },
-    },
-		%[2]s
-}
-
-custom {
-    name: "outer_dep_%[1]d",
-		%[2]s
-}
-
-custom {
-    name: "x86_dep_%[1]d",
-		%[2]s
-}
-`, i, conversionString)
-}
-
-func genCustomModuleBp(pctConverted float64) string {
-	modules := 100
-
-	bp := make([]string, 0, modules)
-	toConvert := int(math.Round(float64(modules) * pctConverted))
-
-	for i := 0; i < modules; i++ {
-		bp = append(bp, genCustomModule(i, i < toConvert))
-	}
-	return strings.Join(bp, "\n\n")
-}
-
-type testConfig struct {
-	config     android.Config
-	ctx        *android.TestContext
-	codegenCtx *CodegenContext
-}
-
-func (tc testConfig) parse() []error {
-	_, errs := tc.ctx.ParseFileList(performance_test_dir, []string{"Android.bp"})
-	return errs
-}
-
-func (tc testConfig) resolveDependencies() []error {
-	_, errs := tc.ctx.ResolveDependencies(tc.config)
-	return errs
-}
-
-func (tc testConfig) convert() {
-	generateBazelTargetsForDir(tc.codegenCtx, performance_test_dir)
-}
-
-func setup(builddir string, tcSize float64) testConfig {
-	config := android.TestConfig(buildDir, nil, genCustomModuleBp(tcSize), nil)
-	ctx := android.NewTestContext(config)
-
-	registerCustomModuleForBp2buildConversion(ctx)
-	codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "")
-	return testConfig{
-		config,
-		ctx,
-		codegenCtx,
-	}
-}
-
-var pctToConvert = []float64{0.0, 0.01, 0.05, 0.10, 0.25, 0.5, 0.75, 1.0}
-
-// This is not intended to test performance, but to verify performance infra continues to work
-func TestConvertManyModulesFull(t *testing.T) {
-	for _, tcSize := range pctToConvert {
-
-		t.Run(fmt.Sprintf("pctConverted %f", tcSize), func(t *testing.T) {
-			testConfig := setup(buildDir, tcSize)
-
-			errs := testConfig.parse()
-			if len(errs) > 0 {
-				t.Fatalf("Unexpected errors: %s", errs)
-			}
-
-			errs = testConfig.resolveDependencies()
-			if len(errs) > 0 {
-				t.Fatalf("Unexpected errors: %s", errs)
-			}
-
-			testConfig.convert()
-		})
-	}
-}
-
-func BenchmarkManyModulesFull(b *testing.B) {
-	for _, tcSize := range pctToConvert {
-
-		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
-			for n := 0; n < b.N; n++ {
-				b.StopTimer()
-				testConfig := setup(buildDir, tcSize)
-
-				b.StartTimer()
-				errs := testConfig.parse()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				errs = testConfig.resolveDependencies()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				testConfig.convert()
-				b.StopTimer()
-			}
-		})
-	}
-}
-
-func BenchmarkManyModulesResolveDependencies(b *testing.B) {
-	for _, tcSize := range pctToConvert {
-
-		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
-			for n := 0; n < b.N; n++ {
-				b.StopTimer()
-				// setup we don't want to measure
-				testConfig := setup(buildDir, tcSize)
-
-				errs := testConfig.parse()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				b.StartTimer()
-				errs = testConfig.resolveDependencies()
-				b.StopTimer()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				testConfig.convert()
-			}
-		})
-	}
-}
-
-func BenchmarkManyModulesGenerateBazelTargetsForDir(b *testing.B) {
-	for _, tcSize := range pctToConvert {
-
-		b.Run(fmt.Sprintf("pctConverted %f", tcSize), func(b *testing.B) {
-			for n := 0; n < b.N; n++ {
-				b.StopTimer()
-				// setup we don't want to measure
-				testConfig := setup(buildDir, tcSize)
-
-				errs := testConfig.parse()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				errs = testConfig.resolveDependencies()
-				if len(errs) > 0 {
-					b.Fatalf("Unexpected errors: %s", errs)
-				}
-
-				b.StartTimer()
-				testConfig.convert()
-				b.StopTimer()
-			}
-		})
-	}
-}
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
deleted file mode 100644
index 15a6df0..0000000
--- a/bp2build/symlink_forest.go
+++ /dev/null
@@ -1,511 +0,0 @@
-// Copyright 2022 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"regexp"
-	"sort"
-	"strconv"
-	"sync"
-	"sync/atomic"
-
-	"android/soong/shared"
-
-	"github.com/google/blueprint/pathtools"
-)
-
-// A tree structure that describes what to do at each directory in the created
-// symlink tree. Currently, it is used to enumerate which files/directories
-// should be excluded from symlinking. Each instance of "node" represents a file
-// or a directory. If excluded is true, then that file/directory should be
-// excluded from symlinking. Otherwise, the node is not excluded, but one of its
-// descendants is (otherwise the node in question would not exist)
-
-type instructionsNode struct {
-	name     string
-	excluded bool // If false, this is just an intermediate node
-	children map[string]*instructionsNode
-}
-
-type symlinkForestContext struct {
-	verbose bool
-	topdir  string // $TOPDIR
-
-	// State
-	wg           sync.WaitGroup
-	depCh        chan string
-	mkdirCount   atomic.Uint64
-	symlinkCount atomic.Uint64
-}
-
-// Ensures that the node for the given path exists in the tree and returns it.
-func ensureNodeExists(root *instructionsNode, path string) *instructionsNode {
-	if path == "" {
-		return root
-	}
-
-	if path[len(path)-1] == '/' {
-		path = path[:len(path)-1] // filepath.Split() leaves a trailing slash
-	}
-
-	dir, base := filepath.Split(path)
-
-	// First compute the parent node...
-	dn := ensureNodeExists(root, dir)
-
-	// then create the requested node as its direct child, if needed.
-	if child, ok := dn.children[base]; ok {
-		return child
-	} else {
-		dn.children[base] = &instructionsNode{base, false, make(map[string]*instructionsNode)}
-		return dn.children[base]
-	}
-}
-
-// Turns a list of paths to be excluded into a tree
-func instructionsFromExcludePathList(paths []string) *instructionsNode {
-	result := &instructionsNode{"", false, make(map[string]*instructionsNode)}
-
-	for _, p := range paths {
-		ensureNodeExists(result, p).excluded = true
-	}
-
-	return result
-}
-
-func mergeBuildFiles(output string, srcBuildFile string, generatedBuildFile string, verbose bool) error {
-
-	srcBuildFileContent, err := os.ReadFile(srcBuildFile)
-	if err != nil {
-		return err
-	}
-
-	generatedBuildFileContent, err := os.ReadFile(generatedBuildFile)
-	if err != nil {
-		return err
-	}
-
-	// There can't be a package() call in both the source and generated BUILD files.
-	// bp2build will generate a package() call for licensing information, but if
-	// there's no licensing information, it will still generate a package() call
-	// that just sets default_visibility=public. If the handcrafted build file
-	// also has a package() call, we'll allow it to override the bp2build
-	// generated one if it doesn't have any licensing information. If the bp2build
-	// one has licensing information and the handcrafted one exists, we'll leave
-	// them both in for bazel to throw an error.
-	packageRegex := regexp.MustCompile(`(?m)^package\s*\(`)
-	packageDefaultVisibilityRegex := regexp.MustCompile(`(?m)^package\s*\(\s*default_visibility\s*=\s*\[\s*"//visibility:public",?\s*]\s*\)`)
-	if packageRegex.Find(srcBuildFileContent) != nil {
-		if verbose && packageDefaultVisibilityRegex.Find(generatedBuildFileContent) != nil {
-			fmt.Fprintf(os.Stderr, "Both '%s' and '%s' have a package() target, removing the first one\n",
-				generatedBuildFile, srcBuildFile)
-		}
-		generatedBuildFileContent = packageDefaultVisibilityRegex.ReplaceAll(generatedBuildFileContent, []byte{})
-	}
-
-	newContents := generatedBuildFileContent
-	if newContents[len(newContents)-1] != '\n' {
-		newContents = append(newContents, '\n')
-	}
-	newContents = append(newContents, srcBuildFileContent...)
-
-	// Say you run bp2build 4 times:
-	// - The first time there's only an Android.bp file. bp2build will convert it to a build file
-	//   under out/soong/bp2build, then symlink from the forest to that generated file
-	// - Then you add a handcrafted BUILD file in the same directory. bp2build will merge this with
-	//   the generated one, and write the result to the output file in the forest. But the output
-	//   file was a symlink to out/soong/bp2build from the previous step! So we erroneously update
-	//   the file in out/soong/bp2build instead. So far this doesn't cause any problems...
-	// - You run a 3rd bp2build with no relevant changes. Everything continues to work.
-	// - You then add a comment to the handcrafted BUILD file. This causes a merge with the
-	//   generated file again. But since we wrote to the generated file in step 2, the generated
-	//   file has an old copy of the handcrafted file in it! This probably causes duplicate bazel
-	//   targets.
-	// To solve this, if we see that the output file is a symlink from a previous build, remove it.
-	stat, err := os.Lstat(output)
-	if err != nil && !os.IsNotExist(err) {
-		return err
-	} else if err == nil {
-		if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
-			if verbose {
-				fmt.Fprintf(os.Stderr, "Removing symlink so that we can replace it with a merged file: %s\n", output)
-			}
-			err = os.Remove(output)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	return pathtools.WriteFileIfChanged(output, newContents, 0666)
-}
-
-// Calls readdir() and returns it as a map from the basename of the files in dir
-// to os.FileInfo.
-func readdirToMap(dir string) map[string]os.FileInfo {
-	entryList, err := ioutil.ReadDir(dir)
-	result := make(map[string]os.FileInfo)
-
-	if err != nil {
-		if os.IsNotExist(err) {
-			// It's okay if a directory doesn't exist; it just means that one of the
-			// trees to be merged contains parts the other doesn't
-			return result
-		} else {
-			fmt.Fprintf(os.Stderr, "Cannot readdir '%s': %s\n", dir, err)
-			os.Exit(1)
-		}
-	}
-
-	for _, fi := range entryList {
-		result[fi.Name()] = fi
-	}
-
-	return result
-}
-
-// Creates a symbolic link at dst pointing to src
-func symlinkIntoForest(topdir, dst, src string) uint64 {
-	srcPath := shared.JoinPath(topdir, src)
-	dstPath := shared.JoinPath(topdir, dst)
-
-	// Check whether a symlink already exists.
-	if dstInfo, err := os.Lstat(dstPath); err != nil {
-		if !os.IsNotExist(err) {
-			fmt.Fprintf(os.Stderr, "Failed to lstat '%s': %s", dst, err)
-			os.Exit(1)
-		}
-	} else {
-		if dstInfo.Mode()&os.ModeSymlink != 0 {
-			// Assume that the link's target is correct, i.e. no manual tampering.
-			// E.g. OUT_DIR could have been previously used with a different source tree check-out!
-			return 0
-		} else {
-			if err := os.RemoveAll(dstPath); err != nil {
-				fmt.Fprintf(os.Stderr, "Failed to remove '%s': %s", dst, err)
-				os.Exit(1)
-			}
-		}
-	}
-
-	// Create symlink.
-	if err := os.Symlink(srcPath, dstPath); err != nil {
-		fmt.Fprintf(os.Stderr, "Cannot create symlink at '%s' pointing to '%s': %s", dst, src, err)
-		os.Exit(1)
-	}
-	return 1
-}
-
-func isDir(path string, fi os.FileInfo) bool {
-	if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
-		return fi.IsDir()
-	}
-
-	fi2, statErr := os.Stat(path)
-	if statErr == nil {
-		return fi2.IsDir()
-	}
-
-	// Check if this is a dangling symlink. If so, treat it like a file, not a dir.
-	_, lstatErr := os.Lstat(path)
-	if lstatErr != nil {
-		fmt.Fprintf(os.Stderr, "Cannot stat or lstat '%s': %s\n%s\n", path, statErr, lstatErr)
-		os.Exit(1)
-	}
-
-	return false
-}
-
-// Returns the mtime of the soong_build binary to determine whether we should
-// force symlink_forest to re-execute
-func getSoongBuildMTime() (int64, error) {
-	binaryPath, err := os.Executable()
-	if err != nil {
-		return 0, err
-	}
-
-	info, err := os.Stat(binaryPath)
-	if err != nil {
-		return 0, err
-	}
-
-	return info.ModTime().UnixMilli(), nil
-}
-
-// cleanSymlinkForest will remove the whole symlink forest directory
-func cleanSymlinkForest(topdir, forest string) error {
-	return os.RemoveAll(shared.JoinPath(topdir, forest))
-}
-
-// This returns whether symlink forest should clean and replant symlinks.
-// It compares the mtime of this executable with the mtime of the last-run
-// soong_build binary. If they differ, then we should clean and replant.
-func shouldCleanSymlinkForest(topdir string, forest string, soongBuildMTime int64) (bool, error) {
-	mtimeFilePath := shared.JoinPath(topdir, forest, "soong_build_mtime")
-	mtimeFileContents, err := os.ReadFile(mtimeFilePath)
-	if err != nil {
-		if os.IsNotExist(err) {
-			// This is likely the first time this has run with this functionality - clean away!
-			return true, nil
-		} else {
-			return false, err
-		}
-	}
-	return strconv.FormatInt(soongBuildMTime, 10) != string(mtimeFileContents), nil
-}
-
-func writeSoongBuildMTimeFile(topdir, forest string, mtime int64) error {
-	mtimeFilePath := shared.JoinPath(topdir, forest, "soong_build_mtime")
-	contents := []byte(strconv.FormatInt(mtime, 10))
-
-	return os.WriteFile(mtimeFilePath, contents, 0666)
-}
-
-// Recursively plants a symlink forest at forestDir. The symlink tree will
-// contain every file in buildFilesDir and srcDir excluding the files in
-// instructions. Collects every directory encountered during the traversal of
-// srcDir .
-func plantSymlinkForestRecursive(context *symlinkForestContext, instructions *instructionsNode, forestDir string, buildFilesDir string, srcDir string) {
-	defer context.wg.Done()
-
-	if instructions != nil && instructions.excluded {
-		// Excluded paths are skipped at the level of the non-excluded parent.
-		fmt.Fprintf(os.Stderr, "may not specify a root-level exclude directory '%s'", srcDir)
-		os.Exit(1)
-	}
-
-	// We don't add buildFilesDir here because the bp2build files marker files is
-	// already a dependency which covers it. If we ever wanted to turn this into
-	// a generic symlink forest creation tool, we'd need to add it, too.
-	context.depCh <- srcDir
-
-	srcDirMap := readdirToMap(shared.JoinPath(context.topdir, srcDir))
-	buildFilesMap := readdirToMap(shared.JoinPath(context.topdir, buildFilesDir))
-
-	renamingBuildFile := false
-	if _, ok := srcDirMap["BUILD"]; ok {
-		if _, ok := srcDirMap["BUILD.bazel"]; !ok {
-			if _, ok := buildFilesMap["BUILD.bazel"]; ok {
-				renamingBuildFile = true
-				srcDirMap["BUILD.bazel"] = srcDirMap["BUILD"]
-				delete(srcDirMap, "BUILD")
-				if instructions != nil {
-					if _, ok := instructions.children["BUILD"]; ok {
-						instructions.children["BUILD.bazel"] = instructions.children["BUILD"]
-						delete(instructions.children, "BUILD")
-					}
-				}
-			}
-		}
-	}
-
-	allEntries := make([]string, 0, len(srcDirMap)+len(buildFilesMap))
-	for n := range srcDirMap {
-		allEntries = append(allEntries, n)
-	}
-	for n := range buildFilesMap {
-		if _, ok := srcDirMap[n]; !ok {
-			allEntries = append(allEntries, n)
-		}
-	}
-	// Tests read the error messages generated, so ensure their order is deterministic
-	sort.Strings(allEntries)
-
-	fullForestPath := shared.JoinPath(context.topdir, forestDir)
-	createForestDir := false
-	if fi, err := os.Lstat(fullForestPath); err != nil {
-		if os.IsNotExist(err) {
-			createForestDir = true
-		} else {
-			fmt.Fprintf(os.Stderr, "Could not read info for '%s': %s\n", forestDir, err)
-		}
-	} else if fi.Mode()&os.ModeDir == 0 {
-		if err := os.RemoveAll(fullForestPath); err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to remove '%s': %s", forestDir, err)
-			os.Exit(1)
-		}
-		createForestDir = true
-	}
-	if createForestDir {
-		if err := os.MkdirAll(fullForestPath, 0777); err != nil {
-			fmt.Fprintf(os.Stderr, "Could not mkdir '%s': %s\n", forestDir, err)
-			os.Exit(1)
-		}
-		context.mkdirCount.Add(1)
-	}
-
-	// Start with a list of items that already exist in the forest, and remove
-	// each element as it is processed in allEntries. Any remaining items in
-	// forestMapForDeletion must be removed. (This handles files which were
-	// removed since the previous forest generation).
-	forestMapForDeletion := readdirToMap(shared.JoinPath(context.topdir, forestDir))
-
-	for _, f := range allEntries {
-		if f[0] == '.' {
-			continue // Ignore dotfiles
-		}
-		delete(forestMapForDeletion, f)
-		// todo add deletionCount metric
-
-		// The full paths of children in the input trees and in the output tree
-		forestChild := shared.JoinPath(forestDir, f)
-		srcChild := shared.JoinPath(srcDir, f)
-		if f == "BUILD.bazel" && renamingBuildFile {
-			srcChild = shared.JoinPath(srcDir, "BUILD")
-		}
-		buildFilesChild := shared.JoinPath(buildFilesDir, f)
-
-		// Descend in the instruction tree if it exists
-		var instructionsChild *instructionsNode
-		if instructions != nil {
-			instructionsChild = instructions.children[f]
-		}
-
-		srcChildEntry, sExists := srcDirMap[f]
-		buildFilesChildEntry, bExists := buildFilesMap[f]
-
-		if instructionsChild != nil && instructionsChild.excluded {
-			if bExists {
-				context.symlinkCount.Add(symlinkIntoForest(context.topdir, forestChild, buildFilesChild))
-			}
-			continue
-		}
-
-		sDir := sExists && isDir(shared.JoinPath(context.topdir, srcChild), srcChildEntry)
-		bDir := bExists && isDir(shared.JoinPath(context.topdir, buildFilesChild), buildFilesChildEntry)
-
-		if !sExists {
-			if bDir && instructionsChild != nil {
-				// Not in the source tree, but we have to exclude something from under
-				// this subtree, so descend
-				context.wg.Add(1)
-				go plantSymlinkForestRecursive(context, instructionsChild, forestChild, buildFilesChild, srcChild)
-			} else {
-				// Not in the source tree, symlink BUILD file
-				context.symlinkCount.Add(symlinkIntoForest(context.topdir, forestChild, buildFilesChild))
-			}
-		} else if !bExists {
-			if sDir && instructionsChild != nil {
-				// Not in the build file tree, but we have to exclude something from
-				// under this subtree, so descend
-				context.wg.Add(1)
-				go plantSymlinkForestRecursive(context, instructionsChild, forestChild, buildFilesChild, srcChild)
-			} else {
-				// Not in the build file tree, symlink source tree, carry on
-				context.symlinkCount.Add(symlinkIntoForest(context.topdir, forestChild, srcChild))
-			}
-		} else if sDir && bDir {
-			// Both are directories. Descend.
-			context.wg.Add(1)
-			go plantSymlinkForestRecursive(context, instructionsChild, forestChild, buildFilesChild, srcChild)
-		} else if !sDir && !bDir {
-			// Neither is a directory. Merge them.
-			srcBuildFile := shared.JoinPath(context.topdir, srcChild)
-			generatedBuildFile := shared.JoinPath(context.topdir, buildFilesChild)
-			// The Android.bp file that codegen used to produce `buildFilesChild` is
-			// already a dependency, we can ignore `buildFilesChild`.
-			context.depCh <- srcChild
-			if err := mergeBuildFiles(shared.JoinPath(context.topdir, forestChild), srcBuildFile, generatedBuildFile, context.verbose); err != nil {
-				fmt.Fprintf(os.Stderr, "Error merging %s and %s: %s",
-					srcBuildFile, generatedBuildFile, err)
-				os.Exit(1)
-			}
-		} else {
-			// Both exist and one is a file. This is an error.
-			fmt.Fprintf(os.Stderr,
-				"Conflict in workspace symlink tree creation: both '%s' and '%s' exist and exactly one is a directory\n",
-				srcChild, buildFilesChild)
-			os.Exit(1)
-		}
-	}
-
-	// Remove all files in the forest that exist in neither the source
-	// tree nor the build files tree. (This handles files which were removed
-	// since the previous forest generation).
-	for f := range forestMapForDeletion {
-		var instructionsChild *instructionsNode
-		if instructions != nil {
-			instructionsChild = instructions.children[f]
-		}
-
-		if instructionsChild != nil && instructionsChild.excluded {
-			// This directory may be excluded because bazel writes to it under the
-			// forest root. Thus this path is intentionally left alone.
-			continue
-		}
-		forestChild := shared.JoinPath(context.topdir, forestDir, f)
-		if err := os.RemoveAll(forestChild); err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to remove '%s/%s': %s", forestDir, f, err)
-			os.Exit(1)
-		}
-	}
-}
-
-// PlantSymlinkForest Creates a symlink forest by merging the directory tree at "buildFiles" and
-// "srcDir" while excluding paths listed in "exclude". Returns the set of paths
-// under srcDir on which readdir() had to be called to produce the symlink
-// forest.
-func PlantSymlinkForest(verbose bool, topdir string, forest string, buildFiles string, exclude []string) (deps []string, mkdirCount, symlinkCount uint64) {
-	context := &symlinkForestContext{
-		verbose:      verbose,
-		topdir:       topdir,
-		depCh:        make(chan string),
-		mkdirCount:   atomic.Uint64{},
-		symlinkCount: atomic.Uint64{},
-	}
-
-	// Check whether soong_build has been modified since the last run
-	soongBuildMTime, err := getSoongBuildMTime()
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-
-	shouldClean, err := shouldCleanSymlinkForest(topdir, forest, soongBuildMTime)
-
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	} else if shouldClean {
-		err = cleanSymlinkForest(topdir, forest)
-		if err != nil {
-			fmt.Fprintln(os.Stderr, err)
-			os.Exit(1)
-		}
-	}
-
-	instructions := instructionsFromExcludePathList(exclude)
-	go func() {
-		context.wg.Add(1)
-		plantSymlinkForestRecursive(context, instructions, forest, buildFiles, ".")
-		context.wg.Wait()
-		close(context.depCh)
-	}()
-
-	for dep := range context.depCh {
-		deps = append(deps, dep)
-	}
-
-	err = writeSoongBuildMTimeFile(topdir, forest, soongBuildMTime)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	return deps, context.mkdirCount.Load(), context.symlinkCount.Load()
-}
diff --git a/bp2build/testing.go b/bp2build/testing.go
deleted file mode 100644
index c978164..0000000
--- a/bp2build/testing.go
+++ /dev/null
@@ -1,785 +0,0 @@
-// Copyright 2021 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-/*
-For shareable/common bp2build testing functionality and dumping ground for
-specific-but-shared functionality among tests in package
-*/
-
-import (
-	"fmt"
-	"path/filepath"
-	"regexp"
-	"sort"
-	"strings"
-	"testing"
-
-	"android/soong/ui/metrics/bp2build_metrics_proto"
-
-	"github.com/google/blueprint/proptools"
-
-	"android/soong/android"
-	"android/soong/android/allowlists"
-	"android/soong/bazel"
-)
-
-var (
-	buildDir string
-)
-
-var labelRegex = regexp.MustCompile(`^//([^: ]+):([^ ]+)$`)
-var simpleModuleNameRegex = regexp.MustCompile(`^[^: /]+$`)
-
-func checkError(t *testing.T, errs []error, expectedErr error) bool {
-	t.Helper()
-
-	if len(errs) != 1 {
-		return false
-	}
-	if strings.Contains(errs[0].Error(), expectedErr.Error()) {
-		return true
-	}
-
-	return false
-}
-
-func errored(t *testing.T, tc Bp2buildTestCase, errs []error) bool {
-	t.Helper()
-	if tc.ExpectedErr != nil {
-		// Rely on checkErrors, as this test case is expected to have an error.
-		return false
-	}
-
-	if len(errs) > 0 {
-		for _, err := range errs {
-			t.Errorf("%s: %s", tc.Description, err)
-		}
-		return true
-	}
-
-	// All good, continue execution.
-	return false
-}
-
-func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
-	t.Helper()
-	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
-}
-
-type Bp2buildTestCase struct {
-	Description                string
-	ModuleTypeUnderTest        string
-	ModuleTypeUnderTestFactory android.ModuleFactory
-	// Text to add to the toplevel, root Android.bp file. If Dir is not set, all
-	// ExpectedBazelTargets are assumed to be generated by this file.
-	Blueprint string
-	// ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty).
-	// Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory.
-	ExpectedBazelTargets []string
-	// ExpectedConvertedModules asserts that modules in this list are labeled as "converted
-	// by bp2build" in the metrics reported by bp2build.
-	ExpectedConvertedModules []string
-	// ExpectedHandcraftedModules asserts that modules in this list are labeled as "handcrafted
-	// in build files" in the metrics reported by bp2build. Such modules are either explicitly
-	// defined in a BUILD file (by name), or registered as "otherwise implicitly handled"
-	// by bp2build (for example, by macros owned by other modules).
-	ExpectedHandcraftedModules []string
-
-	// AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file
-	// in the directory under test. The BUILD file has the given contents. This BUILD file
-	// will also be treated as "BUILD file to keep" by the simulated bp2build environment.
-	AlreadyExistingBuildContents string
-
-	// StubbedBuildDefinitions, if non-empty, adds stub definitions to already-present source
-	// BUILD files for each bazel label given. The BUILD files with these stub definitions
-	// are added to the BUILD file given in AlreadyExistingBuildContents.
-	// Labels may be of the form //pkg/to:target_name (which would be defined in pkg/to/BUILD.bazel)
-	// or `target_name` (which would be defined in ./BUILD.bazel).
-	StubbedBuildDefinitions []string
-
-	Filesystem map[string]string
-	// Dir sets the directory which will be compared against the targets in ExpectedBazelTargets.
-	// This should used in conjunction with the Filesystem property to check for targets
-	// generated from a directory that is not the root.
-	// If not set, all ExpectedBazelTargets are assumed to be generated by the text in the
-	// Blueprint property.
-	Dir string
-	// An error with a string contained within the string of the expected error
-	ExpectedErr         error
-	UnconvertedDepsMode unconvertedDepsMode
-
-	// For every directory listed here, the BUILD file for that directory will
-	// be merged with the generated BUILD file. This allows custom BUILD targets
-	// to be used in tests, or use BUILD files to draw package boundaries.
-	KeepBuildFileForDirs []string
-
-	// An extra FixturePreparer to use when running the test. If you need multiple extra
-	// FixturePreparers, use android.GroupFixturePreparers()
-	ExtraFixturePreparer android.FixturePreparer
-
-	// If bp2build_product_config.go should run as part of the test.
-	RunBp2buildProductConfig bool
-}
-
-func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
-	t.Helper()
-	preparers := []android.FixturePreparer{
-		android.FixtureRegisterWithContext(registerModuleTypes),
-	}
-	if tc.ExtraFixturePreparer != nil {
-		preparers = append(preparers, tc.ExtraFixturePreparer)
-	}
-	preparers = append(preparers, android.FixtureSetTestRunner(&bazelTestRunner{generateProductConfigTargets: tc.RunBp2buildProductConfig}))
-	bp2buildSetup := android.GroupFixturePreparers(
-		preparers...,
-	)
-	runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
-}
-
-func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
-	t.Helper()
-	if tc.Filesystem == nil {
-		tc.Filesystem = map[string]string{}
-	}
-	checkDir := "."
-	if tc.Dir != "" {
-		checkDir = tc.Dir
-	}
-	keepExistingBuildDirs := tc.KeepBuildFileForDirs
-	buildFilesToParse := []string{}
-
-	if len(tc.StubbedBuildDefinitions) > 0 {
-		for _, buildDef := range tc.StubbedBuildDefinitions {
-			globalLabelMatch := labelRegex.FindStringSubmatch(buildDef)
-			var dir, targetName string
-			if len(globalLabelMatch) > 0 {
-				dir = globalLabelMatch[1]
-				targetName = globalLabelMatch[2]
-			} else {
-				if !simpleModuleNameRegex.MatchString(buildDef) {
-					t.Errorf("Stubbed build definition '%s' must be either a simple module name or of global target syntax (//foo/bar:baz).", buildDef)
-					return
-				}
-				dir = "."
-				targetName = buildDef
-			}
-			buildFilePath := filepath.Join(dir, "BUILD")
-			tc.Filesystem[buildFilePath] +=
-				MakeBazelTarget(
-					"bp2build_test_stub",
-					targetName,
-					AttrNameToString{})
-			keepExistingBuildDirs = append(keepExistingBuildDirs, dir)
-			buildFilesToParse = append(buildFilesToParse, buildFilePath)
-		}
-	}
-	if len(tc.AlreadyExistingBuildContents) > 0 {
-		buildFilePath := filepath.Join(checkDir, "BUILD")
-		tc.Filesystem[buildFilePath] += tc.AlreadyExistingBuildContents
-		keepExistingBuildDirs = append(keepExistingBuildDirs, checkDir)
-		buildFilesToParse = append(buildFilesToParse, buildFilePath)
-	}
-	filesystem := make(map[string][]byte)
-	for f, content := range tc.Filesystem {
-		filesystem[f] = []byte(content)
-	}
-	preparers := []android.FixturePreparer{
-		extraPreparer,
-		android.FixtureMergeMockFs(filesystem),
-		android.FixtureWithRootAndroidBp(tc.Blueprint),
-		android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-			ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
-		}),
-		android.FixtureModifyContextWithMockFs(func(ctx *android.TestContext) {
-			// A default configuration for tests to not have to specify bp2build_available on top level
-			// targets.
-			bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
-				allowlists.Bp2BuildConfig{
-					android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
-				},
-			)
-			for _, f := range keepExistingBuildDirs {
-				bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
-					f: /*recursive=*/ false,
-				})
-			}
-			ctx.RegisterBp2BuildConfig(bp2buildConfig)
-			// This setting is added to bp2build invocations. It prevents bp2build
-			// from cloning modules to their original state after mutators run. This
-			// would lose some data intentionally set by these mutators.
-			ctx.SkipCloneModulesAfterMutators = true
-			err := ctx.RegisterExistingBazelTargets(".", buildFilesToParse)
-			if err != nil {
-				t.Errorf("error parsing build files in test setup: %s", err)
-			}
-		}),
-		android.FixtureModifyEnv(func(env map[string]string) {
-			if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
-				env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
-			}
-		}),
-	}
-
-	preparer := android.GroupFixturePreparers(preparers...)
-	if tc.ExpectedErr != nil {
-		pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E"
-		preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern))
-	}
-	result := preparer.RunTestWithCustomResult(t).(*BazelTestResult)
-	if len(result.Errs) > 0 {
-		return
-	}
-
-	expectedTargets := map[string][]string{
-		checkDir: tc.ExpectedBazelTargets,
-	}
-
-	result.CompareAllBazelTargets(t, tc, expectedTargets, true)
-}
-
-// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode.
-type bazelTestRunner struct {
-	generateProductConfigTargets bool
-}
-
-func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
-	ctx := result.TestContext
-	ctx.RegisterForBazelConversion()
-
-	return &BazelTestResult{TestResult: result}
-}
-
-func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
-	bazelResult := result.(*BazelTestResult)
-	ctx := bazelResult.TestContext
-	config := bazelResult.Config
-	_, errs := ctx.ResolveDependencies(config)
-	if bazelResult.CollateErrs(errs) {
-		return
-	}
-
-	codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "")
-	res, errs := GenerateBazelTargets(codegenCtx, false)
-	if bazelResult.CollateErrs(errs) {
-		return
-	}
-	if b.generateProductConfigTargets {
-		productConfig, err := createProductConfigFiles(codegenCtx, res.moduleNameToPartition, res.metrics.convertedModulePathMap)
-		if err != nil {
-			bazelResult.CollateErrs([]error{err})
-			return
-		}
-		for k, v := range productConfig.bp2buildTargets {
-			res.buildFileToTargets[k] = append(res.buildFileToTargets[k], v...)
-		}
-	}
-
-	// Store additional data for access by tests.
-	bazelResult.conversionResults = res
-}
-
-// BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel
-// specific data stored by the bazelTestRunner.
-type BazelTestResult struct {
-	*android.TestResult
-
-	// The result returned by the GenerateBazelTargets function.
-	conversionResults
-}
-
-// CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories
-// with the supplied set of expected targets.
-//
-// If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must
-// have a corresponding expected BazelTarget.
-//
-// If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
-func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, tc Bp2buildTestCase, expectedTargets map[string][]string, ignoreUnexpected bool) {
-	t.Helper()
-	actualTargets := b.buildFileToTargets
-
-	// Generate the sorted set of directories to check.
-	dirsToCheck := android.SortedKeys(expectedTargets)
-	if !ignoreUnexpected {
-		// This needs to perform an exact match so add the directories in which targets were
-		// produced to the list of directories to check.
-		dirsToCheck = append(dirsToCheck, android.SortedKeys(actualTargets)...)
-		dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
-	}
-
-	for _, dir := range dirsToCheck {
-		expected := expectedTargets[dir]
-		actual := actualTargets[dir]
-
-		if expected == nil {
-			if actual != nil {
-				t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual))
-			}
-		} else if actual == nil {
-			expectedCount := len(expected)
-			if expectedCount > 0 {
-				t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
-			}
-		} else {
-			b.CompareBazelTargets(t, tc.Description, expected, actual)
-		}
-	}
-
-	for _, module := range tc.ExpectedConvertedModules {
-		if _, found := b.metrics.convertedModulePathMap[module]; !found {
-			t.Errorf("expected %s to be generated by bp2build, but was not. Map of converted modules: %s", module, b.metrics.convertedModulePathMap)
-		}
-	}
-
-	for _, module := range tc.ExpectedHandcraftedModules {
-		if reason, found := b.metrics.serialized.UnconvertedModules[module]; !found {
-			t.Errorf("expected %s to be marked 'unconverted' by bp2build, but was not found. Full list: %s",
-				module, b.metrics.serialized.UnconvertedModules)
-		} else {
-			if reason.Type != bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE {
-				t.Errorf("expected %s to be marked 'handcrafted' by bp2build, but was disabled for another reason: %s", module, reason)
-			}
-		}
-	}
-}
-
-func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) {
-	t.Helper()
-	if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount {
-		t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
-			description, expectedCount, expectedContents, actualCount, actualTargets)
-	} else {
-		sort.SliceStable(actualTargets, func(i, j int) bool {
-			return actualTargets[i].name < actualTargets[j].name
-		})
-		sort.SliceStable(expectedContents, func(i, j int) bool {
-			return getTargetName(expectedContents[i]) < getTargetName(expectedContents[j])
-		})
-		for i, actualTarget := range actualTargets {
-			if w, g := expectedContents[i], actualTarget.content; w != g {
-				t.Errorf(
-					"%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
-					description, i, w, g)
-			}
-		}
-	}
-}
-
-type nestedProps struct {
-	Nested_prop *string
-}
-
-type EmbeddedProps struct {
-	Embedded_prop *string
-}
-
-type OtherEmbeddedProps struct {
-	Other_embedded_prop *string
-}
-
-type customProps struct {
-	EmbeddedProps
-	*OtherEmbeddedProps
-
-	Bool_prop     bool
-	Bool_ptr_prop *bool
-	// Ensure that properties tagged `blueprint:mutated` are omitted
-	Int_prop            int `blueprint:"mutated"`
-	Int64_ptr_prop      *int64
-	String_prop         string
-	String_literal_prop *string `android:"arch_variant"`
-	String_ptr_prop     *string
-	String_list_prop    []string
-
-	Nested_props     nestedProps
-	Nested_props_ptr *nestedProps
-
-	Arch_paths         []string `android:"path,arch_variant"`
-	Arch_paths_exclude []string `android:"path,arch_variant"`
-
-	// Prop used to indicate this conversion should be 1 module -> multiple targets
-	One_to_many_prop *bool
-
-	// Prop used to simulate an unsupported property in bp2build conversion. If this
-	// is true, this module should be treated as "unconvertible" via bp2build.
-	Does_not_convert_to_bazel *bool
-
-	Api *string // File describing the APIs of this module
-
-	Test_config_setting *bool // Used to test generation of config_setting targets
-
-	Dir *string // Dir in which the Bazel Target will be created
-}
-
-type customModule struct {
-	android.ModuleBase
-	android.BazelModuleBase
-
-	props customProps
-}
-
-// OutputFiles is needed because some instances of this module use dist with a
-// tag property which requires the module implements OutputFileProducer.
-func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
-	return android.PathsForTesting("path" + tag), nil
-}
-
-func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// nothing for now.
-}
-
-func customModuleFactoryBase() android.Module {
-	module := &customModule{}
-	module.AddProperties(&module.props)
-	android.InitBazelModule(module)
-	return module
-}
-
-func customModuleFactoryHostAndDevice() android.Module {
-	m := customModuleFactoryBase()
-	android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
-	return m
-}
-
-func customModuleFactoryDeviceSupported() android.Module {
-	m := customModuleFactoryBase()
-	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
-	return m
-}
-
-func customModuleFactoryHostSupported() android.Module {
-	m := customModuleFactoryBase()
-	android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth)
-	return m
-}
-
-func customModuleFactoryHostAndDeviceDefault() android.Module {
-	m := customModuleFactoryBase()
-	android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth)
-	return m
-}
-
-func customModuleFactoryNeitherHostNorDeviceSupported() android.Module {
-	m := customModuleFactoryBase()
-	android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth)
-	return m
-}
-
-type testProps struct {
-	Test_prop struct {
-		Test_string_prop string
-	}
-}
-
-type customTestModule struct {
-	android.ModuleBase
-
-	props      customProps
-	test_props testProps
-}
-
-func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// nothing for now.
-}
-
-func customTestModuleFactoryBase() android.Module {
-	m := &customTestModule{}
-	m.AddProperties(&m.props)
-	m.AddProperties(&m.test_props)
-	return m
-}
-
-func customTestModuleFactory() android.Module {
-	m := customTestModuleFactoryBase()
-	android.InitAndroidModule(m)
-	return m
-}
-
-type customDefaultsModule struct {
-	android.ModuleBase
-	android.DefaultsModuleBase
-}
-
-func customDefaultsModuleFactoryBase() android.DefaultsModule {
-	module := &customDefaultsModule{}
-	module.AddProperties(&customProps{})
-	return module
-}
-
-func customDefaultsModuleFactoryBasic() android.Module {
-	return customDefaultsModuleFactoryBase()
-}
-
-func customDefaultsModuleFactory() android.Module {
-	m := customDefaultsModuleFactoryBase()
-	android.InitDefaultsModule(m)
-	return m
-}
-
-type EmbeddedAttr struct {
-	Embedded_attr *string
-}
-
-type OtherEmbeddedAttr struct {
-	Other_embedded_attr *string
-}
-
-type customBazelModuleAttributes struct {
-	EmbeddedAttr
-	*OtherEmbeddedAttr
-	String_literal_prop bazel.StringAttribute
-	String_ptr_prop     *string
-	String_list_prop    []string
-	Arch_paths          bazel.LabelListAttribute
-	Api                 bazel.LabelAttribute
-}
-
-func (m *customModule) dir() *string {
-	return m.props.Dir
-}
-
-func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
-	if p := m.props.Does_not_convert_to_bazel; p != nil && *p {
-		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "")
-		return
-	}
-	if p := m.props.One_to_many_prop; p != nil && *p {
-		customBp2buildOneToMany(ctx, m)
-		return
-	}
-
-	paths := bazel.LabelListAttribute{}
-	strAttr := bazel.StringAttribute{}
-	for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
-		for config, props := range configToProps {
-			if custProps, ok := props.(*customProps); ok {
-				if custProps.Arch_paths != nil {
-					paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
-				}
-				if custProps.String_literal_prop != nil {
-					strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
-				}
-			}
-		}
-	}
-	productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module())
-	for _, err := range errs {
-		ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
-	}
-	if props, ok := productVariableProps["String_literal_prop"]; ok {
-		for c, p := range props {
-			if val, ok := p.(*string); ok {
-				strAttr.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
-			}
-		}
-	}
-
-	paths.ResolveExcludes()
-
-	attrs := &customBazelModuleAttributes{
-		String_literal_prop: strAttr,
-		String_ptr_prop:     m.props.String_ptr_prop,
-		String_list_prop:    m.props.String_list_prop,
-		Arch_paths:          paths,
-	}
-
-	attrs.Embedded_attr = m.props.Embedded_prop
-	if m.props.OtherEmbeddedProps != nil {
-		attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
-	}
-
-	props := bazel.BazelTargetModuleProperties{
-		Rule_class: "custom",
-	}
-
-	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name(), Dir: m.dir()}, attrs)
-
-	if proptools.Bool(m.props.Test_config_setting) {
-		m.createConfigSetting(ctx)
-	}
-
-}
-
-func (m *customModule) createConfigSetting(ctx android.Bp2buildMutatorContext) {
-	csa := bazel.ConfigSettingAttributes{
-		Flag_values: bazel.StringMapAttribute{
-			"//build/bazel/rules/my_string_setting": m.Name(),
-		},
-	}
-	ca := android.CommonAttributes{
-		Name: m.Name() + "_config_setting",
-	}
-	ctx.CreateBazelConfigSetting(
-		csa,
-		ca,
-		ctx.ModuleDir(),
-	)
-}
-
-// A bp2build mutator that uses load statements and creates a 1:M mapping from
-// module to target.
-func customBp2buildOneToMany(ctx android.Bp2buildMutatorContext, m *customModule) {
-
-	baseName := m.Name()
-	attrs := &customBazelModuleAttributes{}
-
-	myLibraryProps := bazel.BazelTargetModuleProperties{
-		Rule_class:        "my_library",
-		Bzl_load_location: "//build/bazel/rules:rules.bzl",
-	}
-	ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs)
-
-	protoLibraryProps := bazel.BazelTargetModuleProperties{
-		Rule_class:        "proto_library",
-		Bzl_load_location: "//build/bazel/rules:proto.bzl",
-	}
-	ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs)
-
-	myProtoLibraryProps := bazel.BazelTargetModuleProperties{
-		Rule_class:        "my_proto_library",
-		Bzl_load_location: "//build/bazel/rules:proto.bzl",
-	}
-	ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs)
-}
-
-// Helper method for tests to easily access the targets in a dir.
-func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
-	// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
-	res, err := GenerateBazelTargets(codegenCtx, false)
-	if err != nil {
-		return BazelTargets{}, err
-	}
-	return res.buildFileToTargets[dir], err
-}
-
-func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
-	ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
-	ctx.RegisterForBazelConversion()
-}
-
-func simpleModule(typ, name string) string {
-	return fmt.Sprintf(`
-%s {
-		name: "%s",
-}`, typ, name)
-}
-
-type AttrNameToString map[string]string
-
-func (a AttrNameToString) clone() AttrNameToString {
-	newAttrs := make(AttrNameToString, len(a))
-	for k, v := range a {
-		newAttrs[k] = v
-	}
-	return newAttrs
-}
-
-// makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or
-// device specific, or independent of host/device.
-func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod android.HostOrDeviceSupported) string {
-	if _, ok := attrs["target_compatible_with"]; !ok {
-		switch hod {
-		case android.HostSupported:
-			attrs["target_compatible_with"] = `select({
-        "//build/bazel_common_rules/platforms/os:android": ["@platforms//:incompatible"],
-        "//conditions:default": [],
-    })`
-		case android.DeviceSupported:
-			attrs["target_compatible_with"] = `["//build/bazel_common_rules/platforms/os:android"]`
-		}
-	}
-
-	attrStrings := make([]string, 0, len(attrs)+1)
-	if name != "" {
-		attrStrings = append(attrStrings, fmt.Sprintf(`    name = "%s",`, name))
-	}
-	for _, k := range android.SortedKeys(attrs) {
-		attrStrings = append(attrStrings, fmt.Sprintf("    %s = %s,", k, attrs[k]))
-	}
-	return fmt.Sprintf(`%s(
-%s
-)`, typ, strings.Join(attrStrings, "\n"))
-}
-
-// MakeBazelTargetNoRestrictions returns bazel target build file definition that does not add a
-// target_compatible_with.  This is useful for module types like filegroup and genrule that arch not
-// arch variant
-func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) string {
-	return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault)
-}
-
-// makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific
-// as this is the most common default in Soong.
-func MakeBazelTarget(typ, name string, attrs AttrNameToString) string {
-	return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported)
-}
-
-type ExpectedRuleTarget struct {
-	Rule  string
-	Name  string
-	Attrs AttrNameToString
-	Hod   android.HostOrDeviceSupported
-}
-
-func (ebr ExpectedRuleTarget) String() string {
-	return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod)
-}
-
-func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string {
-	if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs {
-		return ""
-	}
-	STUB_SUITE_ATTRS := map[string]string{
-		"api_surface":          "api_surface",
-		"stubs_symbol_file":    "symbol_file",
-		"stubs_versions":       "versions",
-		"soname":               "soname",
-		"source_library_label": "source_library_label",
-	}
-
-	stubSuiteAttrs := AttrNameToString{}
-	for key, _ := range attrs {
-		if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr {
-			stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
-		} else {
-			panic(fmt.Sprintf("unused cc_stub_suite attr %q\n", key))
-		}
-	}
-	return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
-}
-
-func MakeNeverlinkDuplicateTarget(moduleType string, name string) string {
-	return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{
-		"sdk_version": `"current"`, // use as default
-	})
-}
-
-func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string {
-	attrs := extraAttrs
-	attrs["neverlink"] = `True`
-	attrs["exports"] = `[":` + name + `"]`
-	return MakeBazelTarget(moduleType, name+"-neverlink", attrs)
-}
-
-func getTargetName(targetContent string) string {
-	data := strings.Split(targetContent, "name = \"")
-	if len(data) < 2 {
-		return ""
-	} else {
-		endIndex := strings.Index(data[1], "\"")
-		return data[1][:endIndex]
-	}
-}