// 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 java

import (
	"fmt"
	"path/filepath"
	"strconv"
	"strings"

	"android/soong/ui/metrics/bp2build_metrics_proto"

	"github.com/google/blueprint/pathtools"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/dexpreopt"
	"android/soong/java/config"
)

// This file contains the definition and the implementation of the base module that most
// source-based Java module structs embed.

// TODO:
// Autogenerated files:
//  Renderscript
// Post-jar passes:
//  Proguard
// Rmtypedefs
// DroidDoc
// Findbugs

// Properties that are common to most Java modules, i.e. whether it's a host or device module.
type CommonProperties struct {
	// list of source files used to compile the Java module.  May be .java, .kt, .logtags, .proto,
	// or .aidl files.
	Srcs []string `android:"path,arch_variant"`

	// list Kotlin of source files containing Kotlin code that should be treated as common code in
	// a codebase that supports Kotlin multiplatform.  See
	// https://kotlinlang.org/docs/reference/multiplatform.html.  May be only be .kt files.
	Common_srcs []string `android:"path,arch_variant"`

	// list of source files that should not be used to build the Java module.
	// This is most useful in the arch/multilib variants to remove non-common files
	Exclude_srcs []string `android:"path,arch_variant"`

	// list of directories containing Java resources
	Java_resource_dirs []string `android:"arch_variant"`

	// list of directories that should be excluded from java_resource_dirs
	Exclude_java_resource_dirs []string `android:"arch_variant"`

	// list of files to use as Java resources
	Java_resources []string `android:"path,arch_variant"`

	// list of files that should be excluded from java_resources and java_resource_dirs
	Exclude_java_resources []string `android:"path,arch_variant"`

	// list of module-specific flags that will be used for javac compiles
	Javacflags []string `android:"arch_variant"`

	// list of module-specific flags that will be used for kotlinc compiles
	Kotlincflags []string `android:"arch_variant"`

	// list of java libraries that will be in the classpath
	Libs []string `android:"arch_variant"`

	// list of java libraries that will be compiled into the resulting jar
	Static_libs []string `android:"arch_variant"`

	// list of java libraries that should not be used to build this module
	Exclude_static_libs []string `android:"arch_variant"`

	// manifest file to be included in resulting jar
	Manifest *string `android:"path"`

	// if not blank, run jarjar using the specified rules file
	Jarjar_rules *string `android:"path,arch_variant"`

	// If not blank, set the java version passed to javac as -source and -target
	Java_version *string

	// If set to true, allow this module to be dexed and installed on devices.  Has no
	// effect on host modules, which are always considered installable.
	Installable *bool

	// If set to true, include sources used to compile the module in to the final jar
	Include_srcs *bool

	// If not empty, classes are restricted to the specified packages and their sub-packages.
	// This restriction is checked after applying jarjar rules and including static libs.
	Permitted_packages []string

	// List of modules to use as annotation processors
	Plugins []string

	// List of modules to export to libraries that directly depend on this library as annotation
	// processors.  Note that if the plugins set generates_api: true this will disable the turbine
	// optimization on modules that depend on this module, which will reduce parallelism and cause
	// more recompilation.
	Exported_plugins []string

	// The number of Java source entries each Javac instance can process
	Javac_shard_size *int64

	// Add host jdk tools.jar to bootclasspath
	Use_tools_jar *bool

	Openjdk9 struct {
		// List of source files that should only be used when passing -source 1.9 or higher
		Srcs []string `android:"path"`

		// List of javac flags that should only be used when passing -source 1.9 or higher
		Javacflags []string
	}

	// When compiling language level 9+ .java code in packages that are part of
	// a system module, patch_module names the module that your sources and
	// dependencies should be patched into. The Android runtime currently
	// doesn't implement the JEP 261 module system so this option is only
	// supported at compile time. It should only be needed to compile tests in
	// packages that exist in libcore and which are inconvenient to move
	// elsewhere.
	Patch_module *string

	Jacoco struct {
		// List of classes to include for instrumentation with jacoco to collect coverage
		// information at runtime when building with coverage enabled.  If unset defaults to all
		// classes.
		// Supports '*' as the last character of an entry in the list as a wildcard match.
		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
		// it matches classes in the package that have the class name as a prefix.
		Include_filter []string

		// List of classes to exclude from instrumentation with jacoco to collect coverage
		// information at runtime when building with coverage enabled.  Overrides classes selected
		// by the include_filter property.
		// Supports '*' as the last character of an entry in the list as a wildcard match.
		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
		// it matches classes in the package that have the class name as a prefix.
		Exclude_filter []string
	}

	Errorprone struct {
		// List of javac flags that should only be used when running errorprone.
		Javacflags []string

		// List of java_plugin modules that provide extra errorprone checks.
		Extra_check_modules []string

		// This property can be in 3 states. When set to true, errorprone will
		// be run during the regular build. When set to false, errorprone will
		// never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE
		// environment variable is true. Setting this to false will improve build
		// performance more than adding -XepDisableAllChecks in javacflags.
		Enabled *bool
	}

	Proto struct {
		// List of extra options that will be passed to the proto generator.
		Output_params []string
	}

	// If true, then jacocoagent is automatically added as a libs dependency so that
	// r8 will not strip instrumentation classes out of dexed libraries.
	Instrument bool `blueprint:"mutated"`
	// If true, then the module supports statically including the jacocoagent
	// into the library.
	Supports_static_instrumentation bool `blueprint:"mutated"`

	// List of files to include in the META-INF/services folder of the resulting jar.
	Services []string `android:"path,arch_variant"`

	// If true, package the kotlin stdlib into the jar.  Defaults to true.
	Static_kotlin_stdlib *bool `android:"arch_variant"`

	// A list of java_library instances that provide additional hiddenapi annotations for the library.
	Hiddenapi_additional_annotations []string

	// Additional srcJars tacked in by GeneratedJavaLibraryModule
	Generated_srcjars []android.Path `android:"mutated"`

	// If true, then only the headers are built and not the implementation jar.
	Headers_only *bool
}

// Properties that are specific to device modules. Host module factories should not add these when
// constructing a new module.
type DeviceProperties struct {
	// If not blank, set to the version of the sdk to compile against.
	// Defaults to an empty string, which compiles the module against the private platform APIs.
	// Values are of one of the following forms:
	// 1) numerical API level, "current", "none", or "core_platform"
	// 2) An SDK kind with an API level: "<sdk kind>_<API level>"
	// See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
	// If the SDK kind is empty, it will be set to public.
	Sdk_version *string

	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
	// Defaults to sdk_version if not set. See sdk_version for possible values.
	Min_sdk_version *string

	// if not blank, set the maximum version of the sdk that the compiled artifacts will run against.
	// Defaults to empty string "". See sdk_version for possible values.
	Max_sdk_version *string

	// if not blank, set the maxSdkVersion properties of permission and uses-permission tags.
	// Defaults to empty string "". See sdk_version for possible values.
	Replace_max_sdk_version_placeholder *string

	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
	// Defaults to sdk_version if not set. See sdk_version for possible values.
	Target_sdk_version *string

	// Whether to compile against the platform APIs instead of an SDK.
	// If true, then sdk_version must be empty. The value of this field
	// is ignored when module's type isn't android_app, android_test, or android_test_helper_app.
	Platform_apis *bool

	Aidl struct {
		// Top level directories to pass to aidl tool
		Include_dirs []string

		// Directories rooted at the Android.bp file to pass to aidl tool
		Local_include_dirs []string

		// directories that should be added as include directories for any aidl sources of modules
		// that depend on this module, as well as to aidl for this module.
		Export_include_dirs []string

		// whether to generate traces (for systrace) for this interface
		Generate_traces *bool

		// whether to generate Binder#GetTransaction name method.
		Generate_get_transaction_name *bool

		// whether all interfaces should be annotated with required permissions.
		Enforce_permissions *bool

		// allowlist for interfaces that (temporarily) do not require annotation for permissions.
		Enforce_permissions_exceptions []string `android:"path"`

		// list of flags that will be passed to the AIDL compiler
		Flags []string
	}

	// If true, export a copy of the module as a -hostdex module for host testing.
	Hostdex *bool

	Target struct {
		Hostdex struct {
			// Additional required dependencies to add to -hostdex modules.
			Required []string
		}
	}

	// When targeting 1.9 and above, override the modules to use with --system,
	// otherwise provides defaults libraries to add to the bootclasspath.
	System_modules *string

	IsSDKLibrary bool `blueprint:"mutated"`

	// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
	// Defaults to false.
	V4_signature *bool

	// Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the
	// public stubs library.
	SyspropPublicStub string `blueprint:"mutated"`

	HiddenAPIPackageProperties
	HiddenAPIFlagFileProperties
}

// Device properties that can be overridden by overriding module (e.g. override_android_app)
type OverridableDeviceProperties struct {
	// set the name of the output. If not set, `name` is used.
	// To override a module with this property set, overriding module might need to set this as well.
	// Otherwise, both the overridden and the overriding modules will have the same output name, which
	// can cause the duplicate output error.
	Stem *string
}

// Functionality common to Module and Import
//
// It is embedded in Module so its functionality can be used by methods in Module
// but it is currently only initialized by Import and Library.
type embeddableInModuleAndImport struct {

	// Functionality related to this being used as a component of a java_sdk_library.
	EmbeddableSdkLibraryComponent
}

func (e *embeddableInModuleAndImport) initModuleAndImport(module android.Module) {
	e.initSdkLibraryComponent(module)
}

// Module/Import's DepIsInSameApex(...) delegates to this method.
//
// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
// the one provided by ApexModuleBase.
func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
	// dependencies other than the static linkage are all considered crossing APEX boundary
	if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
		return true
	}
	return false
}

// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file,
// or an invalid path describing the reason it is invalid.
//
// It is unset if a dex jar isn't applicable, i.e. no build rule has been
// requested to create one.
//
// If a dex jar has been requested to be built then it is set, and it may be
// either a valid android.Path, or invalid with a reason message. The latter
// happens if the source that should produce the dex file isn't able to.
//
// E.g. it is invalid with a reason message if there is a prebuilt APEX that
// could produce the dex jar through a deapexer module, but the APEX isn't
// installable so doing so wouldn't be safe.
type OptionalDexJarPath struct {
	isSet bool
	path  android.OptionalPath
}

// IsSet returns true if a path has been set, either invalid or valid.
func (o OptionalDexJarPath) IsSet() bool {
	return o.isSet
}

// Valid returns true if there is a path that is valid.
func (o OptionalDexJarPath) Valid() bool {
	return o.isSet && o.path.Valid()
}

// Path returns the valid path, or panics if it's either not set or is invalid.
func (o OptionalDexJarPath) Path() android.Path {
	if !o.isSet {
		panic("path isn't set")
	}
	return o.path.Path()
}

// PathOrNil returns the path if it's set and valid, or else nil.
func (o OptionalDexJarPath) PathOrNil() android.Path {
	if o.Valid() {
		return o.Path()
	}
	return nil
}

// InvalidReason returns the reason for an invalid path, which is never "". It
// returns "" for an unset or valid path.
func (o OptionalDexJarPath) InvalidReason() string {
	if !o.isSet {
		return ""
	}
	return o.path.InvalidReason()
}

func (o OptionalDexJarPath) String() string {
	if !o.isSet {
		return "<unset>"
	}
	return o.path.String()
}

// makeUnsetDexJarPath returns an unset OptionalDexJarPath.
func makeUnsetDexJarPath() OptionalDexJarPath {
	return OptionalDexJarPath{isSet: false}
}

// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with
// the given OptionalPath, which may be valid or invalid.
func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath {
	return OptionalDexJarPath{isSet: true, path: path}
}

// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the
// valid given path. It returns an unset OptionalDexJarPath if the given path is
// nil.
func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath {
	if path == nil {
		return makeUnsetDexJarPath()
	}
	return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path))
}

// Module contains the properties and members used by all java module types
type Module struct {
	android.ModuleBase
	android.DefaultableModuleBase
	android.ApexModuleBase
	android.BazelModuleBase

	// Functionality common to Module and Import.
	embeddableInModuleAndImport

	properties       CommonProperties
	protoProperties  android.ProtoProperties
	deviceProperties DeviceProperties

	overridableDeviceProperties OverridableDeviceProperties

	// jar file containing header classes including static library dependencies, suitable for
	// inserting into the bootclasspath/classpath of another compile
	headerJarFile android.Path

	// jar file containing implementation classes including static library dependencies but no
	// resources
	implementationJarFile android.Path

	// jar file containing only resources including from static library dependencies
	resourceJar android.Path

	// args and dependencies to package source files into a srcjar
	srcJarArgs []string
	srcJarDeps android.Paths

	// the source files of this module and all its static dependencies
	transitiveSrcFiles *android.DepSet[android.Path]

	// jar file containing implementation classes and resources including static library
	// dependencies
	implementationAndResourcesJar android.Path

	// output file containing classes.dex and resources
	dexJarFile OptionalDexJarPath

	// output file containing uninstrumented classes that will be instrumented by jacoco
	jacocoReportClassesFile android.Path

	// output file of the module, which may be a classes jar or a dex jar
	outputFile       android.Path
	extraOutputFiles android.Paths

	exportAidlIncludeDirs     android.Paths
	ignoredAidlPermissionList android.Paths

	logtagsSrcs android.Paths

	// installed file for binary dependency
	installFile android.Path

	// installed file for hostdex copy
	hostdexInstallFile android.InstallPath

	// list of unique .java and .kt source files
	uniqueSrcFiles android.Paths

	// list of srcjars that was passed to javac
	compiledSrcJars android.Paths

	// manifest file to use instead of properties.Manifest
	overrideManifest android.OptionalPath

	// list of plugins that this java module is exporting
	exportedPluginJars android.Paths

	// list of plugins that this java module is exporting
	exportedPluginClasses []string

	// if true, the exported plugins generate API and require disabling turbine.
	exportedDisableTurbine bool

	// list of source files, collected from srcFiles with unique java and all kt files,
	// will be used by android.IDEInfo struct
	expandIDEInfoCompiledSrcs []string

	// expanded Jarjar_rules
	expandJarjarRules android.Path

	// Extra files generated by the module type to be added as java resources.
	extraResources android.Paths

	hiddenAPI
	dexer
	dexpreopter
	usesLibrary
	linter

	// list of the xref extraction files
	kytheFiles android.Paths

	hideApexVariantFromMake bool

	sdkVersion    android.SdkSpec
	minSdkVersion android.ApiLevel
	maxSdkVersion android.ApiLevel

	sourceExtensions []string

	annoSrcJars android.Paths

	// output file name based on Stem property.
	// This should be set in every ModuleWithStem's GenerateAndroidBuildActions
	// or the module should override Stem().
	stem string

	// Aconfig "cache files" that went directly into this module.  Transitive ones are
	// tracked via JavaInfo.TransitiveAconfigFiles
	// TODO: Extract to something standalone to propagate tags via GeneratedJavaLibraryModule
	aconfigIntermediates android.Paths

	// Aconfig files for all transitive deps.  Also exposed via JavaInfo
	transitiveAconfigFiles *android.DepSet[android.Path]
}

func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
	sdkVersion := j.SdkVersion(ctx)
	if sdkVersion.Stable() {
		return nil
	}
	if sdkVersion.Kind == android.SdkCorePlatform {
		if useLegacyCorePlatformApi(ctx, j.BaseModuleName()) {
			return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion)
		} else {
			// Treat stable core platform as stable.
			return nil
		}
	} else {
		return fmt.Errorf("non stable SDK %v", sdkVersion)
	}
}

// checkSdkVersions enforces restrictions around SDK dependencies.
func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
	if j.RequiresStableAPIs(ctx) {
		if sc, ok := ctx.Module().(android.SdkContext); ok {
			if !sc.SdkVersion(ctx).Specified() {
				ctx.PropertyErrorf("sdk_version",
					"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
			}
		}
	}

	// Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
	// See rank() for details.
	ctx.VisitDirectDeps(func(module android.Module) {
		tag := ctx.OtherModuleDependencyTag(module)
		switch module.(type) {
		// TODO(satayev): cover other types as well, e.g. imports
		case *Library, *AndroidLibrary:
			switch tag {
			case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
				j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
			}
		}
	})
}

func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
	if sc, ok := ctx.Module().(android.SdkContext); ok {
		usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
		sdkVersionSpecified := sc.SdkVersion(ctx).Specified()
		if usePlatformAPI && sdkVersionSpecified {
			ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.")
		} else if !usePlatformAPI && !sdkVersionSpecified {
			ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true")
		}

	}
}

func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
	if _, ok := ctx.Module().(android.SdkContext); ok {
		headersOnly := proptools.Bool(j.properties.Headers_only)
		installable := proptools.Bool(j.properties.Installable)

		if headersOnly && installable {
			ctx.PropertyErrorf("headers_only", "This module has conflicting settings. headers_only is true which, which means this module doesn't generate an implementation jar. However installable is set to true.")
		}
	}
}

func (j *Module) addHostProperties() {
	j.AddProperties(
		&j.properties,
		&j.protoProperties,
		&j.usesLibraryProperties,
	)
}

func (j *Module) addHostAndDeviceProperties() {
	j.addHostProperties()
	j.AddProperties(
		&j.deviceProperties,
		&j.overridableDeviceProperties,
		&j.dexer.dexProperties,
		&j.dexpreoptProperties,
		&j.linter.properties,
	)
}

// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and
// makes it available through the hiddenAPIPropertyInfoProvider.
func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) {
	hiddenAPIInfo := newHiddenAPIPropertyInfo()

	// Populate with flag file paths from the properties.
	hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties)

	// Populate with package rules from the properties.
	hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties)

	ctx.SetProvider(hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
}

func (j *Module) OutputFiles(tag string) (android.Paths, error) {
	switch tag {
	case "":
		return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
	case android.DefaultDistTag:
		return android.Paths{j.outputFile}, nil
	case ".jar":
		return android.Paths{j.implementationAndResourcesJar}, nil
	case ".hjar":
		return android.Paths{j.headerJarFile}, nil
	case ".proguard_map":
		if j.dexer.proguardDictionary.Valid() {
			return android.Paths{j.dexer.proguardDictionary.Path()}, nil
		}
		return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
	case ".generated_srcjars":
		return j.properties.Generated_srcjars, nil
	case ".lint":
		if j.linter.outputs.xml != nil {
			return android.Paths{j.linter.outputs.xml}, nil
		}
		return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
	default:
		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
	}
}

var _ android.OutputFileProducer = (*Module)(nil)

func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
	initJavaModule(module, hod, false)
}

func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
	initJavaModule(module, hod, true)
}

func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
	multilib := android.MultilibCommon
	if multiTargets {
		android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
	} else {
		android.InitAndroidArchModule(module, hod, multilib)
	}
	android.InitDefaultableModule(module)
}

func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
	return j.properties.Instrument &&
		ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
		ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
}

func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
	return j.properties.Supports_static_instrumentation &&
		j.shouldInstrument(ctx) &&
		(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
			ctx.Config().UnbundledBuild())
}

func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
	// Force enable the instrumentation for java code that is built for APEXes ...
	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
	if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
			return true
		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
			return true
		}
	}
	return false
}

func (j *Module) setInstrument(value bool) {
	j.properties.Instrument = value
}

func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
	return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
}

func (j *Module) SystemModules() string {
	return proptools.String(j.deviceProperties.System_modules)
}

func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	if j.deviceProperties.Min_sdk_version != nil {
		return android.ApiLevelFrom(ctx, *j.deviceProperties.Min_sdk_version)
	}
	return j.SdkVersion(ctx).ApiLevel
}

func (j *Module) GetDeviceProperties() *DeviceProperties {
	return &j.deviceProperties
}

func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	if j.deviceProperties.Max_sdk_version != nil {
		return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version)
	}
	// Default is PrivateApiLevel
	return android.SdkSpecPrivate.ApiLevel
}

func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
	if j.deviceProperties.Replace_max_sdk_version_placeholder != nil {
		return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder)
	}
	// Default is PrivateApiLevel
	return android.SdkSpecPrivate.ApiLevel
}

func (j *Module) MinSdkVersionString() string {
	return j.minSdkVersion.String()
}

func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	if j.deviceProperties.Target_sdk_version != nil {
		return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version)
	}
	return j.SdkVersion(ctx).ApiLevel
}

func (j *Module) AvailableFor(what string) bool {
	if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
		// Exception: for hostdex: true libraries, the platform variant is created
		// even if it's not marked as available to platform. In that case, the platform
		// variant is used only for the hostdex and not installed to the device.
		return true
	}
	return j.ApexModuleBase.AvailableFor(what)
}

func (j *Module) deps(ctx android.BottomUpMutatorContext) {
	if ctx.Device() {
		j.linter.deps(ctx)

		sdkDeps(ctx, android.SdkContext(j), j.dexer)

		if j.deviceProperties.SyspropPublicStub != "" {
			// This is a sysprop implementation library that has a corresponding sysprop public
			// stubs library, and a dependency on it so that dependencies on the implementation can
			// be forwarded to the public stubs library when necessary.
			ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub)
		}
	}

	libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)

	j.properties.Static_libs = android.RemoveListFromList(j.properties.Static_libs, j.properties.Exclude_static_libs)
	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)

	// Add dependency on libraries that provide additional hidden api annotations.
	ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)

	if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
		// Require java_sdk_library at inter-partition java dependency to ensure stable
		// interface between partitions. If inter-partition java_library dependency is detected,
		// raise build error because java_library doesn't have a stable interface.
		//
		// Inputs:
		//    PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY
		//      if true, enable enforcement
		//    PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST
		//      exception list of java_library names to allow inter-partition dependency
		for idx := range j.properties.Libs {
			if libDeps[idx] == nil {
				continue
			}

			if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok {
				// java_sdk_library is always allowed at inter-partition dependency.
				// So, skip check.
				if _, ok := javaDep.(*SdkLibrary); ok {
					continue
				}

				j.checkPartitionsForJavaDependency(ctx, "libs", javaDep)
			}
		}
	}

	// For library dependencies that are component libraries (like stubs), add the implementation
	// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
	for _, dep := range libDeps {
		if dep != nil {
			if component, ok := dep.(SdkLibraryComponentDependency); ok {
				if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
					// Add library as optional if it's one of the optional compatibility libs.
					tag := usesLibReqTag
					if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) {
						tag = usesLibOptTag
					}
					ctx.AddVariationDependencies(nil, tag, *lib)
				}
			}
		}
	}

	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)

	android.ProtoDeps(ctx, &j.protoProperties)
	if j.hasSrcExt(".proto") {
		protoDeps(ctx, &j.protoProperties)
	}

	if j.hasSrcExt(".kt") {
		// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
		// Kotlin files
		ctx.AddVariationDependencies(nil, kotlinStdlibTag,
			"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8")
		ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
	}

	// Framework libraries need special handling in static coverage builds: they should not have
	// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
	// the same jacoco classes coming from different bootclasspath jars.
	if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
			j.properties.Instrument = true
		}
	} else if j.shouldInstrumentStatic(ctx) {
		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
	}

	if j.useCompose() {
		ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
			"androidx.compose.compiler_compiler-hosted")
	}
}

func hasSrcExt(srcs []string, ext string) bool {
	for _, src := range srcs {
		if filepath.Ext(src) == ext {
			return true
		}
	}

	return false
}

func (j *Module) hasSrcExt(ext string) bool {
	return hasSrcExt(j.properties.Srcs, ext)
}

func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string {
	var flags string

	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
		if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) {
			flags = "-Wmissing-permission-annotation -Werror"
		}
	}
	return flags
}

func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
	aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) {

	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
	aidlIncludes = append(aidlIncludes,
		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
	aidlIncludes = append(aidlIncludes,
		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)

	var flags []string
	var deps android.Paths
	var includeDirs android.Paths

	flags = append(flags, j.deviceProperties.Aidl.Flags...)

	if aidlPreprocess.Valid() {
		flags = append(flags, "-p"+aidlPreprocess.String())
		deps = append(deps, aidlPreprocess.Path())
	} else if len(aidlIncludeDirs) > 0 {
		includeDirs = append(includeDirs, aidlIncludeDirs...)
	}

	if len(j.exportAidlIncludeDirs) > 0 {
		includeDirs = append(includeDirs, j.exportAidlIncludeDirs...)
	}

	if len(aidlIncludes) > 0 {
		includeDirs = append(includeDirs, aidlIncludes...)
	}

	includeDirs = append(includeDirs, android.PathForModuleSrc(ctx))
	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
		includeDirs = append(includeDirs, src.Path())
	}
	flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I"))
	// add flags for dirs containing AIDL srcs that haven't been specified yet
	flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))

	sdkVersion := (j.SdkVersion(ctx)).Kind
	defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem))
	if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
		flags = append(flags, "-t")
	}

	if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
		flags = append(flags, "--transaction_names")
	}

	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
		exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions
		j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil)
	}

	aidlMinSdkVersion := j.MinSdkVersion(ctx).String()
	flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion)

	return strings.Join(flags, " "), deps
}

func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {

	var flags javaBuilderFlags

	// javaVersion flag.
	flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))

	epEnabled := j.properties.Errorprone.Enabled
	if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) {
		if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() {
			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
		}

		errorProneFlags := []string{
			"-Xplugin:ErrorProne",
			"${config.ErrorProneChecks}",
		}
		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)

		flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " +
			"'" + strings.Join(errorProneFlags, " ") + "'"
		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
	}

	// classpath
	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
	flags.classpath = append(flags.classpath, deps.classpath...)
	flags.dexClasspath = append(flags.dexClasspath, deps.dexClasspath...)
	flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
	flags.processorPath = append(flags.processorPath, deps.processorPath...)
	flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...)

	flags.processors = append(flags.processors, deps.processorClasses...)
	flags.processors = android.FirstUniqueStrings(flags.processors)

	if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
		decodeSdkDep(ctx, android.SdkContext(j)).hasStandardLibs() {
		// Give host-side tools a version of OpenJDK's standard libraries
		// close to what they're targeting. As of Dec 2017, AOSP is only
		// bundling OpenJDK 8 and 9, so nothing < 8 is available.
		//
		// When building with OpenJDK 8, the following should have no
		// effect since those jars would be available by default.
		//
		// When building with OpenJDK 9 but targeting a version < 1.8,
		// putting them on the bootclasspath means that:
		// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
		// b) references to existing APIs are not reinterpreted in an
		//    OpenJDK 9-specific way, eg. calls to subclasses of
		//    java.nio.Buffer as in http://b/70862583
		java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
		flags.bootClasspath = append(flags.bootClasspath,
			android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
			android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
		if Bool(j.properties.Use_tools_jar) {
			flags.bootClasspath = append(flags.bootClasspath,
				android.PathForSource(ctx, java8Home, "lib/tools.jar"))
		}
	}

	// systemModules
	flags.systemModules = deps.systemModules

	return flags
}

func (j *Module) collectJavacFlags(
	ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags {
	// javac flags.
	javacFlags := j.properties.Javacflags
	var needsDebugInfo bool

	needsDebugInfo = false
	for _, flag := range javacFlags {
		if strings.HasPrefix(flag, "-g") {
			needsDebugInfo = true
		}
	}

	if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() && !needsDebugInfo {
		// For non-host binaries, override the -g flag passed globally to remove
		// local variable debug info to reduce disk and memory usage.
		javacFlags = append(javacFlags, "-g:source,lines")
	}
	javacFlags = append(javacFlags, "-Xlint:-dep-ann")

	if flags.javaVersion.usesJavaModules() {
		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
	} else if len(j.properties.Openjdk9.Javacflags) > 0 {
		// java version defaults higher than openjdk 9, these conditionals should no longer be necessary
		ctx.PropertyErrorf("openjdk9.javacflags", "JDK version defaults to higher than 9")
	}

	if flags.javaVersion.usesJavaModules() {
		if j.properties.Patch_module != nil {
			// Manually specify build directory in case it is not under the repo root.
			// (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so
			// just adding a symlink under the root doesn't help.)
			patchPaths := []string{".", ctx.Config().SoongOutDir()}

			// b/150878007
			//
			// Workaround to support *Bazel-executed* JDK9 javac in Bazel's
			// execution root for --patch-module. If this javac command line is
			// invoked within Bazel's execution root working directory, the top
			// level directories (e.g. libcore/, tools/, frameworks/) are all
			// symlinks. JDK9 javac does not traverse into symlinks, which causes
			// --patch-module to fail source file lookups when invoked in the
			// execution root.
			//
			// Short of patching javac or enumerating *all* directories as possible
			// input dirs, manually add the top level dir of the source files to be
			// compiled.
			topLevelDirs := map[string]bool{}
			for _, srcFilePath := range srcFiles {
				srcFileParts := strings.Split(srcFilePath.String(), "/")
				// Ignore source files that are already in the top level directory
				// as well as generated files in the out directory. The out
				// directory may be an absolute path, which means srcFileParts[0] is the
				// empty string, so check that as well. Note that "out" in Bazel's execution
				// root is *not* a symlink, which doesn't cause problems for --patch-modules
				// anyway, so it's fine to not apply this workaround for generated
				// source files.
				if len(srcFileParts) > 1 &&
					srcFileParts[0] != "" &&
					srcFileParts[0] != "out" {
					topLevelDirs[srcFileParts[0]] = true
				}
			}
			patchPaths = append(patchPaths, android.SortedKeys(topLevelDirs)...)

			classPath := flags.classpath.FormJavaClassPath("")
			if classPath != "" {
				patchPaths = append(patchPaths, classPath)
			}
			javacFlags = append(
				javacFlags,
				"--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":"))
		}
	}

	if len(javacFlags) > 0 {
		// optimization.
		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
		flags.javacFlags = "$javacFlags"
	}

	return flags
}

func (j *Module) AddJSONData(d *map[string]interface{}) {
	(&j.ModuleBase).AddJSONData(d)
	(*d)["Java"] = map[string]interface{}{
		"SourceExtensions": j.sourceExtensions,
	}

}

func (j *Module) addGeneratedSrcJars(path android.Path) {
	j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
}

func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {
	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)

	deps := j.collectDeps(ctx)
	flags := j.collectBuilderFlags(ctx, deps)

	if flags.javaVersion.usesJavaModules() {
		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
	} else if len(j.properties.Openjdk9.Javacflags) > 0 {
		// java version defaults higher than openjdk 9, these conditionals should no longer be necessary
		ctx.PropertyErrorf("openjdk9.srcs", "JDK version defaults to higher than 9")
	}

	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
	j.sourceExtensions = []string{}
	for _, ext := range []string{".kt", ".proto", ".aidl", ".java", ".logtags"} {
		if hasSrcExt(srcFiles.Strings(), ext) {
			j.sourceExtensions = append(j.sourceExtensions, ext)
		}
	}
	if hasSrcExt(srcFiles.Strings(), ".proto") {
		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
	}

	kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
	if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
		ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
	}

	aidlSrcs := srcFiles.FilterByExt(".aidl")
	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs)

	nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar")
	srcFiles = j.genSources(ctx, srcFiles, flags)

	// Collect javac flags only after computing the full set of srcFiles to
	// ensure that the --patch-module lookup paths are complete.
	flags = j.collectJavacFlags(ctx, flags, srcFiles)

	srcJars := srcFiles.FilterByExt(".srcjar")
	srcJars = append(srcJars, deps.srcJars...)
	srcJars = append(srcJars, extraSrcJars...)
	srcJars = append(srcJars, j.properties.Generated_srcjars...)
	srcFiles = srcFiles.FilterOutByExt(".srcjar")

	if j.properties.Jarjar_rules != nil {
		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
	}

	jarName := j.Stem() + ".jar"

	var uniqueJavaFiles android.Paths
	set := make(map[string]bool)
	for _, v := range srcFiles.FilterByExt(".java") {
		if _, found := set[v.String()]; !found {
			set[v.String()] = true
			uniqueJavaFiles = append(uniqueJavaFiles, v)
		}
	}
	var uniqueKtFiles android.Paths
	for _, v := range srcFiles.FilterByExt(".kt") {
		if _, found := set[v.String()]; !found {
			set[v.String()] = true
			uniqueKtFiles = append(uniqueKtFiles, v)
		}
	}

	var uniqueSrcFiles android.Paths
	uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
	uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
	j.uniqueSrcFiles = uniqueSrcFiles

	// We don't currently run annotation processors in turbine, which means we can't use turbine
	// generated header jars when an annotation processor that generates API is enabled.  One
	// exception (handled further below) is when kotlin sources are enabled, in which case turbine
	//  is used to run all of the annotation processors.
	disableTurbine := deps.disableTurbine

	// Collect .java and .kt files for AIDEGen
	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)

	var kotlinJars android.Paths
	var kotlinHeaderJars android.Paths

	// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
	// any dependencies so that it can override any non-final R classes from dependencies with the
	// final R classes from the app.
	flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)

	// If compiling headers then compile them and skip the rest
	if proptools.Bool(j.properties.Headers_only) {
		if srcFiles.HasExt(".kt") {
			ctx.ModuleErrorf("Compiling headers_only with .kt not supported")
		}
		if ctx.Config().IsEnvFalse("TURBINE_ENABLED") || disableTurbine {
			ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
		}

		_, j.headerJarFile =
			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
				extraCombinedJars)
		if ctx.Failed() {
			return
		}

		ctx.SetProvider(JavaInfoProvider, JavaInfo{
			HeaderJars:                     android.PathsIfNonNil(j.headerJarFile),
			TransitiveLibsHeaderJars:       j.transitiveLibsHeaderJars,
			TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
			AidlIncludeDirs:                j.exportAidlIncludeDirs,
			ExportedPlugins:                j.exportedPluginJars,
			ExportedPluginClasses:          j.exportedPluginClasses,
			ExportedPluginDisableTurbine:   j.exportedDisableTurbine,
		})

		j.outputFile = j.headerJarFile
		return
	}

	if srcFiles.HasExt(".kt") {
		// When using kotlin sources turbine is used to generate annotation processor sources,
		// including for annotation processors that generate API, so we can use turbine for
		// java sources too.
		disableTurbine = false

		// user defined kotlin flags.
		kotlincFlags := j.properties.Kotlincflags
		CheckKotlincFlags(ctx, kotlincFlags)

		// Workaround for KT-46512
		kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")

		// If there are kotlin files, compile them first but pass all the kotlin and java files
		// kotlinc will use the java files to resolve types referenced by the kotlin files, but
		// won't emit any classes for them.
		kotlincFlags = append(kotlincFlags, "-no-stdlib")
		if ctx.Device() {
			kotlincFlags = append(kotlincFlags, "-no-jdk")
		}

		for _, plugin := range deps.kotlinPlugins {
			kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String())
		}
		flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...)

		if len(kotlincFlags) > 0 {
			// optimization.
			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
			flags.kotlincFlags += "$kotlincFlags"
		}

		// Collect common .kt files for AIDEGen
		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)

		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
		flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)

		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)

		if len(flags.processorPath) > 0 {
			// Use kapt for annotation processing
			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
			kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
			srcJars = append(srcJars, kaptSrcJar)
			kotlinJars = append(kotlinJars, kaptResJar)
			// Disable annotation processing in javac, it's already been handled by kapt
			flags.processorPath = nil
			flags.processors = nil
		}

		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
		kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
		kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
		if ctx.Failed() {
			return
		}

		// Make javac rule depend on the kotlinc rule
		flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)

		kotlinJars = append(kotlinJars, kotlinJar)
		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)

		// Jar kotlin classes into the final jar after javac
		if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
			kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
			kotlinJars = append(kotlinJars, deps.kotlinAnnotations...)
			kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinStdlib...)
			kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinAnnotations...)
		} else {
			flags.dexClasspath = append(flags.dexClasspath, deps.kotlinStdlib...)
			flags.dexClasspath = append(flags.dexClasspath, deps.kotlinAnnotations...)
		}
	}

	jars := append(android.Paths(nil), kotlinJars...)

	j.compiledSrcJars = srcJars

	enableSharding := false
	var headerJarFileWithoutDepsOrJarjar android.Path
	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
			enableSharding = true
			// Formerly, there was a check here that prevented annotation processors
			// from being used when sharding was enabled, as some annotation processors
			// do not function correctly in sharded environments. It was removed to
			// allow for the use of annotation processors that do function correctly
			// with sharding enabled. See: b/77284273.
		}
		extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...)
		headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
		if ctx.Failed() {
			return
		}
	}
	if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
		hasErrorproneableFiles := false
		for _, ext := range j.sourceExtensions {
			if ext != ".proto" && ext != ".aidl" {
				// Skip running errorprone on pure proto or pure aidl modules. Some modules take a long time to
				// compile, and it's not useful to have warnings on these generated sources.
				hasErrorproneableFiles = true
				break
			}
		}
		var extraJarDeps android.Paths
		if Bool(j.properties.Errorprone.Enabled) {
			// If error-prone is enabled, enable errorprone flags on the regular
			// build.
			flags = enableErrorproneFlags(flags)
		} else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
			// Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
			// a new jar file just for compiling with the errorprone compiler to.
			// This is because we don't want to cause the java files to get completely
			// rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
			// We also don't want to run this if errorprone is enabled by default for
			// this module, or else we could have duplicated errorprone messages.
			errorproneFlags := enableErrorproneFlags(flags)
			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
			errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")

			transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
				"errorprone", "errorprone")

			extraJarDeps = append(extraJarDeps, errorprone)
		}

		if enableSharding {
			if headerJarFileWithoutDepsOrJarjar != nil {
				flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...)
			}
			shardSize := int(*(j.properties.Javac_shard_size))
			var shardSrcs []android.Paths
			if len(uniqueJavaFiles) > 0 {
				shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
				for idx, shardSrc := range shardSrcs {
					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
						nil, flags, extraJarDeps)
					jars = append(jars, classes)
				}
			}
			// Assume approximately 5 sources per srcjar.
			// For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean
			// of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files.
			if len(srcJars) > 0 {
				startIdx := len(shardSrcs)
				shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5)
				for idx, shardSrcJars := range shardSrcJarsList {
					classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
						nil, shardSrcJars, flags, extraJarDeps)
					jars = append(jars, classes)
				}
			}
		} else {
			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
			jars = append(jars, classes)
		}
		if ctx.Failed() {
			return
		}
	}

	j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles

	var includeSrcJar android.WritablePath
	if Bool(j.properties.Include_srcs) {
		includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
		TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
	}

	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
	extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources

	var resArgs []string
	var resDeps android.Paths

	resArgs = append(resArgs, dirArgs...)
	resDeps = append(resDeps, dirDeps...)

	resArgs = append(resArgs, fileArgs...)
	resDeps = append(resDeps, fileDeps...)

	resArgs = append(resArgs, extraArgs...)
	resDeps = append(resDeps, extraDeps...)

	if len(resArgs) > 0 {
		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
		j.resourceJar = resourceJar
		if ctx.Failed() {
			return
		}
	}

	var resourceJars android.Paths
	if j.resourceJar != nil {
		resourceJars = append(resourceJars, j.resourceJar)
	}
	if Bool(j.properties.Include_srcs) {
		resourceJars = append(resourceJars, includeSrcJar)
	}
	resourceJars = append(resourceJars, deps.staticResourceJars...)

	if len(resourceJars) > 1 {
		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
			false, nil, nil)
		j.resourceJar = combinedJar
	} else if len(resourceJars) == 1 {
		j.resourceJar = resourceJars[0]
	}

	if len(deps.staticJars) > 0 {
		jars = append(jars, deps.staticJars...)
	}

	manifest := j.overrideManifest
	if !manifest.Valid() && j.properties.Manifest != nil {
		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
	}

	services := android.PathsForModuleSrc(ctx, j.properties.Services)
	if len(services) > 0 {
		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
		var zipargs []string
		for _, file := range services {
			serviceFile := file.String()
			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
		}
		rule := zip
		args := map[string]string{
			"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
		}
		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
			rule = zipRE
			args["implicits"] = strings.Join(services.Strings(), ",")
		}
		ctx.Build(pctx, android.BuildParams{
			Rule:      rule,
			Output:    servicesJar,
			Implicits: services,
			Args:      args,
		})
		jars = append(jars, servicesJar)
	}

	jars = append(android.CopyOf(extraCombinedJars), jars...)

	// Combine the classes built from sources, any manifests, and any static libraries into
	// classes.jar. If there is only one input jar this step will be skipped.
	var outputFile android.OutputPath

	if len(jars) == 1 && !manifest.Valid() {
		// Optimization: skip the combine step as there is nothing to do
		// TODO(ccross): this leaves any module-info.class files, but those should only come from
		// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
		// any if len(jars) == 1.

		// moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
		// from sdk_library. The TopLevelStubLibrary contains only one static lib,
		// either with .from-source or .from-text suffix.
		// outputFile should be agnostic to the build configuration,
		// thus "combine" the single static lib in order to prevent the static lib from being exposed
		// to the copy rules.
		stub, _ := moduleStubLinkType(ctx.ModuleName())

		// Transform the single path to the jar into an OutputPath as that is required by the following
		// code.
		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok && !stub {
			// The path contains an embedded OutputPath so reuse that.
			outputFile = moduleOutPath.OutputPath
		} else if outputPath, ok := jars[0].(android.OutputPath); ok && !stub {
			// The path is an OutputPath so reuse it directly.
			outputFile = outputPath
		} else {
			// The file is not in the out directory so create an OutputPath into which it can be copied
			// and which the following code can use to refer to it.
			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  jars[0],
				Output: combinedJar,
			})
			outputFile = combinedJar.OutputPath
		}
	} else {
		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
			false, nil, nil)
		outputFile = combinedJar.OutputPath
	}

	// jarjar implementation jar if necessary
	if j.expandJarjarRules != nil {
		// Transform classes.jar into classes-jarjar.jar
		jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName).OutputPath
		TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules)
		outputFile = jarjarFile

		// jarjar resource jar if necessary
		if j.resourceJar != nil {
			resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
			TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules)
			j.resourceJar = resourceJarJarFile
		}

		if ctx.Failed() {
			return
		}
	}

	// Check package restrictions if necessary.
	if len(j.properties.Permitted_packages) > 0 {
		// Time stamp file created by the package check rule.
		pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")

		// Create a rule to copy the output jar to another path and add a validate dependency that
		// will check that the jar only contains the permitted packages. The new location will become
		// the output file of this module.
		inputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "package-check", jarName).OutputPath
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Cp,
			Input:  inputFile,
			Output: outputFile,
			// Make sure that any dependency on the output file will cause ninja to run the package check
			// rule.
			Validation: pkgckFile,
		})

		// Check packages and create a timestamp file when complete.
		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)

		if ctx.Failed() {
			return
		}
	}

	j.implementationJarFile = outputFile
	if j.headerJarFile == nil {
		// If this module couldn't generate a header jar (for example due to api generating annotation processors)
		// then use the implementation jar.  Run it through zip2zip first to remove any files in META-INF/services
		// so that javac on modules that depend on this module don't pick up annotation processors (which may be
		// missing their implementations) from META-INF/services/javax.annotation.processing.Processor.
		headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
		convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
		j.headerJarFile = headerJarFile
	}

	// enforce syntax check to jacoco filters for any build (http://b/183622051)
	specs := j.jacocoModuleToZipCommand(ctx)
	if ctx.Failed() {
		return
	}

	if j.shouldInstrument(ctx) {
		outputFile = j.instrument(ctx, flags, outputFile, jarName, specs)
	}

	// merge implementation jar with resources if necessary
	implementationAndResourcesJar := outputFile
	if j.resourceJar != nil {
		jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
		combinedJar := android.PathForModuleOut(ctx, "withres", jarName).OutputPath
		TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
			false, nil, nil)
		implementationAndResourcesJar = combinedJar
	}

	j.implementationAndResourcesJar = implementationAndResourcesJar

	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
	compileDex := j.dexProperties.Compile_dex
	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
	if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() {
		if compileDex == nil {
			compileDex = proptools.BoolPtr(true)
		}
		if j.deviceProperties.Hostdex == nil {
			j.deviceProperties.Hostdex = proptools.BoolPtr(true)
		}
	}

	if ctx.Device() && (Bool(j.properties.Installable) || Bool(compileDex)) {
		if j.hasCode(ctx) {
			if j.shouldInstrumentStatic(ctx) {
				j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
			}
			// Dex compilation
			var dexOutputFile android.OutputPath
			params := &compileDexParams{
				flags:         flags,
				sdkVersion:    j.SdkVersion(ctx),
				minSdkVersion: j.MinSdkVersion(ctx),
				classesJar:    implementationAndResourcesJar,
				jarName:       jarName,
			}
			dexOutputFile = j.dexer.compileDex(ctx, params)
			if ctx.Failed() {
				return
			}

			// merge dex jar with resources if necessary
			if j.resourceJar != nil {
				jars := android.Paths{dexOutputFile, j.resourceJar}
				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName).OutputPath
				TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
					false, nil, nil)
				if *j.dexProperties.Uncompress_dex {
					combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath
					TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil)
					dexOutputFile = combinedAlignedJar
				} else {
					dexOutputFile = combinedJar
				}
			}

			// Initialize the hiddenapi structure.

			j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex)

			// Encode hidden API flags in dex file, if needed.
			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)

			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)

			// Dexpreopting
			j.dexpreopt(ctx, dexOutputFile)

			outputFile = dexOutputFile
		} else {
			// There is no code to compile into a dex jar, make sure the resources are propagated
			// to the APK if this is an app.
			outputFile = implementationAndResourcesJar
			j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
		}

		if ctx.Failed() {
			return
		}
	} else {
		outputFile = implementationAndResourcesJar
	}

	if ctx.Device() {
		lintSDKVersion := func(apiLevel android.ApiLevel) int {
			if !apiLevel.IsPreview() {
				return apiLevel.FinalInt()
			} else {
				// When running metalava, we pass --version-codename. When that value
				// is not REL, metalava will add 1 to the --current-version argument.
				// On old branches, PLATFORM_SDK_VERSION is the latest version (for that
				// branch) and the codename is REL, except potentially on the most
				// recent non-master branch. On that branch, it goes through two other
				// phases before it gets to the phase previously described:
				//  - PLATFORM_SDK_VERSION has not been updated yet, and the codename
				//    is not rel. This happens for most of the internal branch's life
				//    while the branch has been cut but is still under active development.
				//  - PLATFORM_SDK_VERSION has been set, but the codename is still not
				//    REL. This happens briefly during the release process. During this
				//    state the code to add --current-version is commented out, and then
				//    that commenting out is reverted after the codename is set to REL.
				// On the master branch, the PLATFORM_SDK_VERSION always represents a
				// prior version and the codename is always non-REL.
				//
				// We need to add one here to match metalava adding 1. Technically
				// this means that in the state described in the second bullet point
				// above, this number is 1 higher than it should be.
				return ctx.Config().PlatformSdkVersion().FinalInt() + 1
			}
		}

		j.linter.name = ctx.ModuleName()
		j.linter.srcs = append(srcFiles, nonGeneratedSrcJars...)
		j.linter.srcJars, _ = android.FilterPathList(srcJars, nonGeneratedSrcJars)
		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
		j.linter.classes = j.implementationJarFile
		j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx))
		j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx))
		j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel)
		j.linter.compileSdkKind = j.SdkVersion(ctx).Kind
		j.linter.javaLanguageLevel = flags.javaVersion.String()
		j.linter.kotlinLanguageLevel = "1.3"
		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
			j.linter.buildModuleReportZip = true
		}
		j.linter.lint(ctx)
	}

	j.collectTransitiveSrcFiles(ctx, srcFiles)

	ctx.CheckbuildFile(outputFile)

	j.collectTransitiveAconfigFiles(ctx)

	ctx.SetProvider(JavaInfoProvider, JavaInfo{
		HeaderJars:                     android.PathsIfNonNil(j.headerJarFile),
		TransitiveLibsHeaderJars:       j.transitiveLibsHeaderJars,
		TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
		ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
		ImplementationJars:             android.PathsIfNonNil(j.implementationJarFile),
		ResourceJars:                   android.PathsIfNonNil(j.resourceJar),
		AidlIncludeDirs:                j.exportAidlIncludeDirs,
		SrcJarArgs:                     j.srcJarArgs,
		SrcJarDeps:                     j.srcJarDeps,
		TransitiveSrcFiles:             j.transitiveSrcFiles,
		ExportedPlugins:                j.exportedPluginJars,
		ExportedPluginClasses:          j.exportedPluginClasses,
		ExportedPluginDisableTurbine:   j.exportedDisableTurbine,
		JacocoReportClassesFile:        j.jacocoReportClassesFile,
		TransitiveAconfigFiles:         j.transitiveAconfigFiles,
	})

	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
	j.outputFile = outputFile.WithoutRel()
}

func (j *Module) useCompose() bool {
	return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs)
}

func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
	transitiveUnconditionalExportedFlags := []*android.DepSet[android.Path]{}
	transitiveProguardFlags := []*android.DepSet[android.Path]{}

	ctx.VisitDirectDeps(func(m android.Module) {
		depProguardInfo := ctx.OtherModuleProvider(m, ProguardSpecInfoProvider).(ProguardSpecInfo)
		depTag := ctx.OtherModuleDependencyTag(m)

		if depProguardInfo.UnconditionallyExportedProguardFlags != nil {
			transitiveUnconditionalExportedFlags = append(transitiveUnconditionalExportedFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
			transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
		}

		if depTag == staticLibTag && depProguardInfo.ProguardFlagsFiles != nil {
			transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.ProguardFlagsFiles)
		}
	})

	directUnconditionalExportedFlags := android.Paths{}
	proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
	exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
	if exportUnconditionally {
		// if we explicitly export, then our unconditional exports are the same as our transitive flags
		transitiveUnconditionalExportedFlags = transitiveProguardFlags
		directUnconditionalExportedFlags = proguardFlagsForThisModule
	}

	return ProguardSpecInfo{
		Export_proguard_flags_files: exportUnconditionally,
		ProguardFlagsFiles: android.NewDepSet[android.Path](
			android.POSTORDER,
			proguardFlagsForThisModule,
			transitiveProguardFlags,
		),
		UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
			android.POSTORDER,
			directUnconditionalExportedFlags,
			transitiveUnconditionalExportedFlags,
		),
	}

}

// Returns a copy of the supplied flags, but with all the errorprone-related
// fields copied to the regular build's fields.
func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
	flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)

	if len(flags.errorProneExtraJavacFlags) > 0 {
		if len(flags.javacFlags) > 0 {
			flags.javacFlags += " " + flags.errorProneExtraJavacFlags
		} else {
			flags.javacFlags = flags.errorProneExtraJavacFlags
		}
	}
	return flags
}

func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
	srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {

	kzipName := pathtools.ReplaceExtension(jarName, "kzip")
	annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar")
	if idx >= 0 {
		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
		annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar")
		jarName += strconv.Itoa(idx)
	}

	classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath
	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)

	if ctx.Config().EmitXrefRules() {
		extractionFile := android.PathForModuleOut(ctx, kzipName)
		emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
		j.kytheFiles = append(j.kytheFiles, extractionFile)
	}

	if len(flags.processorPath) > 0 {
		j.annoSrcJars = append(j.annoSrcJars, annoSrcJar)
	}

	return classes
}

// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
// since some of these flags may be used internally.
func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
	for _, flag := range flags {
		flag = strings.TrimSpace(flag)

		if !strings.HasPrefix(flag, "-") {
			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
			ctx.PropertyErrorf("kotlincflags",
				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
		} else if inList(flag, config.KotlincIllegalFlags) {
			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
		} else if flag == "-include-runtime" {
			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
		} else {
			args := strings.Split(flag, " ")
			if args[0] == "-kotlin-home" {
				ctx.PropertyErrorf("kotlincflags",
					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
			}
		}
	}
}

func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
	deps deps, flags javaBuilderFlags, jarName string,
	extraJars android.Paths) (headerJar, jarjarAndDepsHeaderJar android.Path) {

	var jars android.Paths
	if len(srcFiles) > 0 || len(srcJars) > 0 {
		// Compile java sources into turbine.jar.
		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
		if ctx.Failed() {
			return nil, nil
		}
		jars = append(jars, turbineJar)
		headerJar = turbineJar
	}

	jars = append(jars, extraJars...)

	// Combine any static header libraries into classes-header.jar. If there is only
	// one input jar this step will be skipped.
	jars = append(jars, deps.staticHeaderJars...)

	// we cannot skip the combine step for now if there is only one jar
	// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
	combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName)
	TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
		false, nil, []string{"META-INF/TRANSITIVE"})
	jarjarAndDepsHeaderJar = combinedJar

	if j.expandJarjarRules != nil {
		// Transform classes.jar into classes-jarjar.jar
		jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
		TransformJarJar(ctx, jarjarFile, jarjarAndDepsHeaderJar, j.expandJarjarRules)
		jarjarAndDepsHeaderJar = jarjarFile
		if ctx.Failed() {
			return nil, nil
		}
	}

	return headerJar, jarjarAndDepsHeaderJar
}

func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
	classesJar android.Path, jarName string, specs string) android.OutputPath {

	jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
	instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName).OutputPath

	jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)

	j.jacocoReportClassesFile = jacocoReportClassesFile

	return instrumentedJar
}

type providesTransitiveHeaderJars struct {
	// set of header jars for all transitive libs deps
	transitiveLibsHeaderJars *android.DepSet[android.Path]
	// set of header jars for all transitive static libs deps
	transitiveStaticLibsHeaderJars *android.DepSet[android.Path]
}

func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet[android.Path] {
	return j.transitiveLibsHeaderJars
}

func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet[android.Path] {
	return j.transitiveStaticLibsHeaderJars
}

func (j *providesTransitiveHeaderJars) collectTransitiveHeaderJars(ctx android.ModuleContext) {
	directLibs := android.Paths{}
	directStaticLibs := android.Paths{}
	transitiveLibs := []*android.DepSet[android.Path]{}
	transitiveStaticLibs := []*android.DepSet[android.Path]{}
	ctx.VisitDirectDeps(func(module android.Module) {
		// don't add deps of the prebuilt version of the same library
		if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
			return
		}

		dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
		tag := ctx.OtherModuleDependencyTag(module)
		_, isUsesLibDep := tag.(usesLibraryDependencyTag)
		if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep {
			directLibs = append(directLibs, dep.HeaderJars...)
		} else if tag == staticLibTag {
			directStaticLibs = append(directStaticLibs, dep.HeaderJars...)
		} else {
			// Don't propagate transitive libs for other kinds of dependencies.
			return
		}

		if dep.TransitiveLibsHeaderJars != nil {
			transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJars)
		}
		if dep.TransitiveStaticLibsHeaderJars != nil {
			transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJars)
		}
	})
	j.transitiveLibsHeaderJars = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
	j.transitiveStaticLibsHeaderJars = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs)
}

func (j *Module) HeaderJars() android.Paths {
	if j.headerJarFile == nil {
		return nil
	}
	return android.Paths{j.headerJarFile}
}

func (j *Module) ImplementationJars() android.Paths {
	if j.implementationJarFile == nil {
		return nil
	}
	return android.Paths{j.implementationJarFile}
}

func (j *Module) DexJarBuildPath() OptionalDexJarPath {
	return j.dexJarFile
}

func (j *Module) DexJarInstallPath() android.Path {
	return j.installFile
}

func (j *Module) ImplementationAndResourcesJars() android.Paths {
	if j.implementationAndResourcesJar == nil {
		return nil
	}
	return android.Paths{j.implementationAndResourcesJar}
}

func (j *Module) AidlIncludeDirs() android.Paths {
	// exportAidlIncludeDirs is type android.Paths already
	return j.exportAidlIncludeDirs
}

func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
	return j.classLoaderContexts
}

// Collect information for opening IDE project files in java/jdeps.go.
func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
	dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
	dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
	if j.expandJarjarRules != nil {
		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
	}
	dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...)
	dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
	dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...)
}

func (j *Module) CompilerDeps() []string {
	jdeps := []string{}
	jdeps = append(jdeps, j.properties.Libs...)
	jdeps = append(jdeps, j.properties.Static_libs...)
	return jdeps
}

func (j *Module) hasCode(ctx android.ModuleContext) bool {
	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
	return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
}

// Implements android.ApexModule
func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
	return j.depIsInSameApex(ctx, dep)
}

// Implements android.ApexModule
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
	sdkVersionSpec := j.SdkVersion(ctx)
	minSdkVersion := j.MinSdkVersion(ctx)
	if !minSdkVersion.Specified() {
		return fmt.Errorf("min_sdk_version is not specified")
	}
	// If the module is compiling against core (via sdk_version), skip comparison check.
	if sdkVersionSpec.Kind == android.SdkCore {
		return nil
	}
	if minSdkVersion.GreaterThan(sdkVersion) {
		return fmt.Errorf("newer SDK(%v)", minSdkVersion)
	}
	return nil
}

func (j *Module) Stem() string {
	if j.stem == "" {
		panic("Stem() called before stem property was set")
	}
	return j.stem
}

func (j *Module) JacocoReportClassesFile() android.Path {
	return j.jacocoReportClassesFile
}

func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
	var fromDeps []*android.DepSet[android.Path]
	ctx.VisitDirectDeps(func(module android.Module) {
		tag := ctx.OtherModuleDependencyTag(module)
		if tag == staticLibTag {
			depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
			if depInfo.TransitiveSrcFiles != nil {
				fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles)
			}
		}
	})

	j.transitiveSrcFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
}

func (j *Module) IsInstallable() bool {
	return Bool(j.properties.Installable)
}

func (j *Module) collectTransitiveAconfigFiles(ctx android.ModuleContext) {
	// Aconfig files from this module
	mine := j.aconfigIntermediates

	// Aconfig files from transitive dependencies
	fromDeps := []*android.DepSet[android.Path]{}
	ctx.VisitDirectDeps(func(module android.Module) {
		dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
		if dep.TransitiveAconfigFiles != nil {
			fromDeps = append(fromDeps, dep.TransitiveAconfigFiles)
		}
	})

	// DepSet containing aconfig files myself and from dependencies
	j.transitiveAconfigFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
}

func (j *Module) AddAconfigIntermediate(path android.Path) {
	j.aconfigIntermediates = append(j.aconfigIntermediates, path)
}

func (j *Module) getTransitiveAconfigFiles() *android.DepSet[android.Path] {
	if j.transitiveAconfigFiles == nil {
		panic(fmt.Errorf("java.Moduile: getTransitiveAconfigFiles called before collectTransitiveAconfigFiles module=%s", j.Name()))
	}
	return j.transitiveAconfigFiles
}

type sdkLinkType int

const (
	// TODO(jiyong) rename these for better readability. Make the allowed
	// and disallowed link types explicit
	// order is important here. See rank()
	javaCore sdkLinkType = iota
	javaSdk
	javaSystem
	javaModule
	javaSystemServer
	javaPlatform
)

func (lt sdkLinkType) String() string {
	switch lt {
	case javaCore:
		return "core Java API"
	case javaSdk:
		return "Android API"
	case javaSystem:
		return "system API"
	case javaModule:
		return "module API"
	case javaSystemServer:
		return "system server API"
	case javaPlatform:
		return "private API"
	default:
		panic(fmt.Errorf("unrecognized linktype: %d", lt))
	}
}

// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to
// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK
// can't statically depend on modules that use Platform API.
func (lt sdkLinkType) rank() int {
	return int(lt)
}

type moduleWithSdkDep interface {
	android.Module
	getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool)
}

func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
	switch name {
	case android.SdkCore.DefaultJavaLibraryName(),
		"legacy.core.platform.api.stubs",
		"stable.core.platform.api.stubs",
		"stub-annotations", "private-stub-annotations-jar",
		"core-lambda-stubs",
		"core-generated-annotation-stubs":
		return javaCore, true
	case android.SdkPublic.DefaultJavaLibraryName():
		return javaSdk, true
	case android.SdkSystem.DefaultJavaLibraryName():
		return javaSystem, true
	case android.SdkModule.DefaultJavaLibraryName():
		return javaModule, true
	case android.SdkSystemServer.DefaultJavaLibraryName():
		return javaSystemServer, true
	case android.SdkTest.DefaultJavaLibraryName():
		return javaSystem, true
	}

	if stub, linkType := moduleStubLinkType(name); stub {
		return linkType, true
	}

	ver := m.SdkVersion(ctx)
	switch ver.Kind {
	case android.SdkCore:
		return javaCore, false
	case android.SdkSystem:
		return javaSystem, false
	case android.SdkPublic:
		return javaSdk, false
	case android.SdkModule:
		return javaModule, false
	case android.SdkSystemServer:
		return javaSystemServer, false
	case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
		return javaPlatform, false
	}

	if !ver.Valid() {
		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw))
	}
	return javaSdk, false
}

// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
// this module's. See the comment on rank() for details and an example.
func (j *Module) checkSdkLinkType(
	ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) {
	if ctx.Host() {
		return
	}

	myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName())
	if stubs {
		return
	}
	depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep))

	if myLinkType.rank() < depLinkType.rank() {
		ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
			"In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
			"property of the source or target module so that target module is built "+
			"with the same or smaller API set when compared to the source.",
			myLinkType, ctx.OtherModuleName(dep), depLinkType)
	}
}

func (j *Module) collectDeps(ctx android.ModuleContext) deps {
	var deps deps

	if ctx.Device() {
		sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
		if sdkDep.invalidVersion {
			ctx.AddMissingDependencies(sdkDep.bootclasspath)
			ctx.AddMissingDependencies(sdkDep.java9Classpath)
		} else if sdkDep.useFiles {
			// sdkDep.jar is actually equivalent to turbine header.jar.
			deps.classpath = append(deps.classpath, sdkDep.jars...)
			deps.dexClasspath = append(deps.dexClasspath, sdkDep.jars...)
			deps.aidlPreprocess = sdkDep.aidl
		} else {
			deps.aidlPreprocess = sdkDep.aidl
		}
	}

	sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())

	j.collectTransitiveHeaderJars(ctx)
	ctx.VisitDirectDeps(func(module android.Module) {
		otherName := ctx.OtherModuleName(module)
		tag := ctx.OtherModuleDependencyTag(module)

		if IsJniDepTag(tag) {
			// Handled by AndroidApp.collectAppDeps
			return
		}
		if tag == certificateTag {
			// Handled by AndroidApp.collectAppDeps
			return
		}

		if dep, ok := module.(SdkLibraryDependency); ok {
			switch tag {
			case sdkLibTag, libTag:
				depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
				deps.classpath = append(deps.classpath, depHeaderJars...)
				deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...)
			case staticLibTag:
				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
			}
		} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
			if sdkLinkType != javaPlatform &&
				ctx.OtherModuleHasProvider(module, SyspropPublicStubInfoProvider) {
				// dep is a sysprop implementation library, but this module is not linking against
				// the platform, so it gets the sysprop public stubs library instead.  Replace
				// dep with the JavaInfo from the SyspropPublicStubInfoProvider.
				syspropDep := ctx.OtherModuleProvider(module, SyspropPublicStubInfoProvider).(SyspropPublicStubInfo)
				dep = syspropDep.JavaInfo
			}
			switch tag {
			case bootClasspathTag:
				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
			case sdkLibTag, libTag, instrumentationForTag:
				if _, ok := module.(*Plugin); ok {
					ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
				}
				deps.classpath = append(deps.classpath, dep.HeaderJars...)
				deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...)
				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
			case java9LibTag:
				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
			case staticLibTag:
				if _, ok := module.(*Plugin); ok {
					ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
				}
				deps.classpath = append(deps.classpath, dep.HeaderJars...)
				deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
				// Turbine doesn't run annotation processors, so any module that uses an
				// annotation processor that generates API is incompatible with the turbine
				// optimization.
				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
			case pluginTag:
				if plugin, ok := module.(*Plugin); ok {
					if plugin.pluginProperties.Processor_class != nil {
						addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
					} else {
						addPlugins(&deps, dep.ImplementationAndResourcesJars)
					}
					// Turbine doesn't run annotation processors, so any module that uses an
					// annotation processor that generates API is incompatible with the turbine
					// optimization.
					deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
				} else {
					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
				}
			case errorpronePluginTag:
				if _, ok := module.(*Plugin); ok {
					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
				} else {
					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
				}
			case exportedPluginTag:
				if plugin, ok := module.(*Plugin); ok {
					j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
					if plugin.pluginProperties.Processor_class != nil {
						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
					}
					// Turbine doesn't run annotation processors, so any module that uses an
					// annotation processor that generates API is incompatible with the turbine
					// optimization.
					j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api)
				} else {
					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
				}
			case kotlinStdlibTag:
				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...)
			case kotlinAnnotationsTag:
				deps.kotlinAnnotations = dep.HeaderJars
			case kotlinPluginTag:
				deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
			case syspropPublicStubDepTag:
				// This is a sysprop implementation library, forward the JavaInfoProvider from
				// the corresponding sysprop public stub library as SyspropPublicStubInfoProvider.
				ctx.SetProvider(SyspropPublicStubInfoProvider, SyspropPublicStubInfo{
					JavaInfo: dep,
				})
			}
		} else if dep, ok := module.(android.SourceFileProducer); ok {
			switch tag {
			case sdkLibTag, libTag:
				checkProducesJars(ctx, dep)
				deps.classpath = append(deps.classpath, dep.Srcs()...)
				deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
			case staticLibTag:
				checkProducesJars(ctx, dep)
				deps.classpath = append(deps.classpath, dep.Srcs()...)
				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
			}
		} else {
			switch tag {
			case bootClasspathTag:
				// If a system modules dependency has been added to the bootclasspath
				// then add its libs to the bootclasspath.
				sm := module.(SystemModulesProvider)
				deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)

			case systemModulesTag:
				if deps.systemModules != nil {
					panic("Found two system module dependencies")
				}
				sm := module.(SystemModulesProvider)
				outputDir, outputDeps := sm.OutputDirAndDeps()
				deps.systemModules = &systemModules{outputDir, outputDeps}

			case instrumentationForTag:
				ctx.PropertyErrorf("instrumentation_for", "dependency %q of type %q does not provide JavaInfo so is unsuitable for use with this property", ctx.OtherModuleName(module), ctx.OtherModuleType(module))
			}
		}

		addCLCFromDep(ctx, module, j.classLoaderContexts)
	})

	return deps
}

func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
	deps.processorPath = append(deps.processorPath, pluginJars...)
	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
}

// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with
// this interface.
type ProvidesUsesLib interface {
	ProvidesUsesLib() *string
}

func (j *Module) ProvidesUsesLib() *string {
	return j.usesLibraryProperties.Provides_uses_lib
}

type ModuleWithStem interface {
	Stem() string
}

var _ ModuleWithStem = (*Module)(nil)

func (j *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
	switch ctx.ModuleType() {
	case "java_library", "java_library_host", "java_library_static", "tradefed_java_library_host":
		if lib, ok := ctx.Module().(*Library); ok {
			javaLibraryBp2Build(ctx, lib)
		}
	case "java_binary_host":
		if binary, ok := ctx.Module().(*Binary); ok {
			javaBinaryHostBp2Build(ctx, binary)
		}
	case "java_test_host":
		if testHost, ok := ctx.Module().(*TestHost); ok {
			javaTestHostBp2Build(ctx, testHost)
		}
	default:
		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
	}
}
