// 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"
	"reflect"
	"slices"
	"strconv"
	"strings"

	"github.com/google/blueprint"
	"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"`

	// java class names to rename with jarjar when a reverse dependency has a jarjar_prefix
	// property.
	Jarjar_rename []string

	// if not blank, used as prefix to generate repackage rule
	Jarjar_prefix *string

	// 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"`

	// intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule
	Aconfig_Cache_files []android.Path `android:"mutated"`

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

	// A list of files or dependencies to make available to the build sandbox. This is
	// useful if source files are symlinks, the targets of the symlinks must be listed here.
	// Note that currently not all actions implemented by android_apps are sandboxed, so you
	// may only see this being necessary in lint builds.
	Compile_data []string `android:"path"`

	// Property signifying whether the module compiles stubs or not.
	// Should be set to true when srcs of this module are stub files.
	// This property does not need to be set to true when the module depends on
	// the stubs via libs, but should be set to true when the module depends on
	// the stubs via static libs.
	Is_stubs_module *bool

	// If true, enable the "Ravenizer" tool on the output jar.
	// "Ravenizer" is a tool for Ravenwood tests, but it can also be enabled on other kinds
	// of java targets.
	Ravenizer struct {
		Enabled *bool
	}

	// Contributing api surface of the stub module. Is not visible to bp modules, and should
	// only be set for stub submodules generated by the java_sdk_library
	Stub_contributing_api *string `blueprint:"mutated"`

	// If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject
	// bytecode to log API calls.
	ApiMapper bool `blueprint:"mutated"`
}

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

// Properties that can be overridden by overriding module (e.g. override_android_app)
type OverridableProperties 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

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

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

	// Functionality common to Module and Import.
	embeddableInModuleAndImport

	properties       CommonProperties
	protoProperties  android.ProtoProperties
	deviceProperties DeviceProperties

	overridableProperties OverridableProperties
	sourceProperties      android.SourceProperties

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

	repackagedHeaderJarFile 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

	// jarjar rule for inherited jarjar rules
	repackageJarjarRules 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

	// Values that will be set in the JarJarProvider data for jarjar repackaging,
	// and merged with our dependencies' rules.
	jarjarRenameRules map[string]string

	stubsLinkType StubsLinkType

	// Paths to the aconfig intermediate cache files that are provided by the
	// java_aconfig_library or java_library modules that are statically linked
	// to this module. Does not contain cache files from all transitive dependencies.
	aconfigCacheFiles android.Paths

	// List of soong module dependencies required to compile the current module.
	// This information is printed out to `Dependencies` field in module_bp_java_deps.json
	compileDepNames []string

	ravenizer struct {
		enabled bool
	}
}

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

// To satisfy the InstallableModule interface
func (j *Module) StaticDependencyTags() []blueprint.DependencyTag {
	return []blueprint.DependencyTag{staticLibTag}
}

// To satisfy the InstallableModule interface
func (j *Module) DynamicDependencyTags() []blueprint.DependencyTag {
	return []blueprint.DependencyTag{libTag, sdkLibTag, bootClasspathTag, systemModulesTag,
		instrumentationForTag, java9LibTag}
}

// Overrides android.ModuleBase.InstallInProduct()
func (j *Module) InstallInProduct() bool {
	return j.ProductSpecific()
}

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

// To safisfy the StubsAvailableModule interface
func (j *Module) IsStubsModule() bool {
	return proptools.Bool(j.properties.Is_stubs_module)
}

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.overridableProperties,
		&j.protoProperties,
		&j.usesLibraryProperties,
	)
}

func (j *Module) addHostAndDeviceProperties() {
	j.addHostProperties()
	j.AddProperties(
		&j.deviceProperties,
		&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)

	android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
}

// helper method for java modules to set OutputFilesProvider
func setOutputFiles(ctx android.ModuleContext, m Module) {
	ctx.SetOutputFiles(append(android.Paths{m.outputFile}, m.extraOutputFiles...), "")
	ctx.SetOutputFiles(android.Paths{m.outputFile}, android.DefaultDistTag)
	ctx.SetOutputFiles(android.Paths{m.implementationAndResourcesJar}, ".jar")
	ctx.SetOutputFiles(android.Paths{m.headerJarFile}, ".hjar")
	if m.dexer.proguardDictionary.Valid() {
		ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map")
	}
	ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars")
	if m.linter.outputs.xml != nil {
		ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint")
	}
}

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) shouldApiMapper() bool {
	return j.properties.ApiMapper
}

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, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	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) setApiMapper(value bool) {
	j.properties.ApiMapper = 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.overridableProperties.Min_sdk_version != nil {
		return android.ApiLevelFrom(ctx, *j.overridableProperties.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.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 or it's
					// explicitly listed in the optional_uses_libs property.
					tag := usesLibReqTag
					if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
						android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs) {
						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
		tag := staticLibTag
		if !BoolDefault(j.properties.Static_kotlin_stdlib, true) {
			tag = libTag
		}
		ctx.AddVariationDependencies(nil, tag,
			"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "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()}

			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) {
	// Auto-propagating jarjar rules
	jarjarProviderData := j.collectJarJarRules(ctx)
	if jarjarProviderData != nil {
		android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
		text := getJarJarRuleText(jarjarProviderData)
		if text != "" {
			ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
			android.WriteFileRule(ctx, ruleTextFile, text)
			j.repackageJarjarRules = ruleTextFile
		}
	}

	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)

	if re := proptools.Bool(j.properties.Ravenizer.Enabled); re {
		j.ravenizer.enabled = re
	}

	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
	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: uniqueSrcFiles.Strings()})

	// 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...)

	j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)

	// 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.")
		}

		_, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
			extraCombinedJars)

		combinedHeaderJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
		combinedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
		if ctx.Failed() {
			return
		}
		j.headerJarFile = combinedHeaderJarFile

		android.SetProvider(ctx, 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,
			StubsLinkType:                       j.stubsLinkType,
			AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
		})

		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.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
		}

		kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")

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

		kotlinJars = append(kotlinJars, kotlinJarPath)
		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
	}

	jars := slices.Clone(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 := slices.Clone(kotlinHeaderJars)
		extraJars = append(extraJars, extraCombinedJars...)
		var combinedHeaderJarFile android.Path
		headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile =
			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)

		j.headerJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
		j.repackagedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
	}
	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)
					classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
					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)
					classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
					jars = append(jars, classes)
				}
			}
		} else {
			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
			classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
			jars = append(jars, classes)
		}
		if ctx.Failed() {
			return
		}
	}

	jars = append(jars, extraCombinedJars...)

	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)
	}

	// 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.Path

	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(j)

		if stub {
			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  jars[0],
				Output: combinedJar,
			})
			outputFile = combinedJar
		} else {
			outputFile = jars[0]
		}
	} else {
		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
			false, nil, nil)
		outputFile = combinedJar
	}

	// jarjar implementation jar if necessary
	jarjarFile := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
	outputFile = jarjarFile

	// jarjar resource jar if necessary
	if j.resourceJar != nil {
		resourceJarJarFile := j.jarjarIfNecessary(ctx, j.resourceJar, jarName, "resource")
		j.resourceJar = resourceJarJarFile
	}

	if ctx.Failed() {
		return
	}

	if j.ravenizer.enabled {
		ravenizerInput := outputFile
		ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", jarName)
		ctx.Build(pctx, android.BuildParams{
			Rule:        ravenizer,
			Description: "ravenizer",
			Input:       ravenizerInput,
			Output:      ravenizerOutput,
		})
		outputFile = ravenizerOutput
	}

	if j.shouldApiMapper() {
		inputFile := outputFile
		apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName)
		ctx.Build(pctx, android.BuildParams{
			Rule:        apimapper,
			Description: "apimapper",
			Input:       inputFile,
			Output:      apiMapperFile,
		})
		outputFile = apiMapperFile
	}

	// 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
		packageCheckOutputFile := android.PathForModuleOut(ctx, "package-check", jarName)
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Cp,
			Input:  inputFile,
			Output: packageCheckOutputFile,
			// Make sure that any dependency on the output file will cause ninja to run the package check
			// rule.
			Validation: pkgckFile,
		})
		outputFile = packageCheckOutputFile

		// 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)
		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, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	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.extraProguardFlagsFiles = append(j.dexer.extraProguardFlagsFiles,
					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
			}
			// Dex compilation
			var dexOutputFile android.Path
			params := &compileDexParams{
				flags:         flags,
				sdkVersion:    j.SdkVersion(ctx),
				minSdkVersion: j.MinSdkVersion(ctx),
				classesJar:    implementationAndResourcesJar,
				jarName:       jarName,
			}
			if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() {
				ctx.PropertyErrorf("enable_profile_rewriting",
					"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.",
				)
			}
			if j.EnableProfileRewriting() {
				profile := j.GetProfile()
				if profile == "" || !j.GetProfileGuided() {
					ctx.PropertyErrorf("enable_profile_rewriting", "Profile and Profile_guided must be set when enable_profile_rewriting is true")
				}
				params.artProfileInput = &profile
			}
			dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
			if ctx.Failed() {
				return
			}

			// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
			if dexArtProfileOutput != nil {
				j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput)
			}

			// merge dex jar with resources if necessary
			if j.resourceJar != nil {
				jars := android.Paths{dexOutputFile, j.resourceJar}
				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
				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)
					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
			libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
			if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
				libName = strings.TrimSuffix(libName, ".impl")
			}
			j.dexpreopt(ctx, libName, 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) android.ApiLevel {
			if !apiLevel.IsPreview() {
				return apiLevel
			} else {
				return ctx.Config().DefaultAppTargetSdk(ctx)
			}
		}

		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"
		j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data)
		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
			j.linter.buildModuleReportZip = true
		}
		j.linter.lint(ctx)
	}

	j.collectTransitiveSrcFiles(ctx, srcFiles)

	ctx.CheckbuildFile(outputFile)

	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
		HeaderJars:                          android.PathsIfNonNil(j.headerJarFile),
		RepackagedHeaderJars:                android.PathsIfNonNil(j.repackagedHeaderJarFile),
		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,
		StubsLinkType:                       j.stubsLinkType,
		AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
	})

	// 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 collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []*android.DepSet[android.Path]) {
	ctx.VisitDirectDeps(func(m android.Module) {
		depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
		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)
		}
	})

	return transitiveProguardFlags, transitiveUnconditionalExportedFlags
}

func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
	transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)

	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.Path {

	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)
	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)

	if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() {
		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 android.Path, combinedHeaderJar 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)
		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
	combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName)
	TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
		false, nil, []string{"META-INF/TRANSITIVE"})

	return headerJar, combinedHeaderJarOutputPath
}

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

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

	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
		}

		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
			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(ctx android.ModuleErrorfContext) 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(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
	// jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the
	// repackaged jar instead of the input sources.
	if j.expandJarjarRules != nil {
		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
		dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
	} else {
		dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
		dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
		dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...)
	}
	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
	dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...)
	dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
}

func (j *Module) CompilerDeps() []string {
	return j.compileDepNames
}

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 {
			if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
				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)
}

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 sdkLinkTypeFromSdkKind(k android.SdkKind) sdkLinkType {
	switch k {
	case android.SdkCore:
		return javaCore
	case android.SdkSystem:
		return javaSystem
	case android.SdkPublic:
		return javaSdk
	case android.SdkModule:
		return javaModule
	case android.SdkSystemServer:
		return javaSystemServer
	case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
		return javaPlatform
	default:
		return javaSdk
	}
}

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(m); stub {
		return linkType, true
	}

	ver := m.SdkVersion(ctx)
	if !ver.Valid() {
		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw))
	}

	return sdkLinkTypeFromSdkKind(ver.Kind), 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
			// Add the sdk module dependency to `compileDepNames`.
			// This ensures that the dependency is reported in `module_bp_java_deps.json`
			// TODO (b/358608607): Move this to decodeSdkDep
			sdkSpec := android.SdkContext(j).SdkVersion(ctx)
			j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
		} 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 dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
			if sdkLinkType != javaPlatform {
				if syspropDep, ok := android.OtherModuleProvider(ctx, module, SyspropPublicStubInfoProvider); ok {
					// 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.
					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...)
				if len(dep.RepackagedHeaderJars) == 1 && !slices.Contains(dep.HeaderJars, dep.RepackagedHeaderJars[0]) {
					deps.classpath = append(deps.classpath, dep.RepackagedHeaderJars...)
					deps.dexClasspath = append(deps.dexClasspath, dep.RepackagedHeaderJars...)
				}
				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
				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
			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 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.
				android.SetProvider(ctx, 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 if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
			switch tag {
			case staticLibTag:
				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
			}
		} else {
			switch tag {
			case bootClasspathTag:
				// If a system modules dependency has been added to the bootclasspath
				// then add its libs to the bootclasspath.
				if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
					depHeaderJars := sm.HeaderJars
					deps.bootClasspath = append(deps.bootClasspath, depHeaderJars...)
				} else {
					ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
						ctx.OtherModuleName(module))
				}

			case systemModulesTag:
				if deps.systemModules != nil {
					panic("Found two system module dependencies")
				}
				if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
					deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps}
				} else {
					ctx.PropertyErrorf("system modules dependency %q does not provide SystemModulesProvider",
						ctx.OtherModuleName(module))
				}

			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))
			}
		}

		if android.InList(tag, compileDependencyTags) {
			// Add the dependency name to compileDepNames so that it can be recorded in module_bp_java_deps.json
			j.compileDepNames = append(j.compileDepNames, otherName)
		}

		addCLCFromDep(ctx, module, j.classLoaderContexts)
		addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
	})

	return deps
}

// Provider for jarjar renaming rules.
//
// Modules can set their jarjar renaming rules with addJarJarRenameRule, and those renamings will be
// passed to all rdeps.  The typical way that these renamings will NOT be inherited is when a module
// links against stubs -- these are not passed through stubs. The classes will remain unrenamed on
// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
// be renamed from that module.
// TODO: Add another property to suppress the forwarding of
type DependencyUse int

const (
	RenameUseInvalid DependencyUse = iota
	RenameUseInclude
	RenameUseExclude
)

type RenameUseElement struct {
	DepName   string
	RenameUse DependencyUse
	Why       string // token for determining where in the logic the decision was made.
}

type JarJarProviderData struct {
	// Mapping of class names: original --> renamed.  If the value is "", the class will be
	// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
	// attribute). Rdeps of that module will inherit the renaming.
	Rename    map[string]string
	RenameUse []RenameUseElement
}

func (this JarJarProviderData) GetDebugString() string {
	result := ""
	for _, k := range android.SortedKeys(this.Rename) {
		v := this.Rename[k]
		if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") {
			result += k + "--&gt;" + v + ";"
		}
	}
	return result
}

var JarJarProvider = blueprint.NewProvider[JarJarProviderData]()

var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath"

func init() {
	android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
}

// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
// whether they are java modules or not.
type BaseJarJarProviderData struct {
	JarJarProviderData JarJarProviderData
}

func (this BaseJarJarProviderData) GetDebugString() string {
	return this.JarJarProviderData.GetDebugString()
}

var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]()

// mergeJarJarPrefixes is called immediately before module.GenerateAndroidBuildActions is called.
// Since there won't be a JarJarProvider, we create the BaseJarJarProvider if any of our deps have
// either JarJarProvider or BaseJarJarProvider.
func mergeJarJarPrefixes(ctx android.ModuleContext) {
	mod := ctx.Module()
	// Explicitly avoid propagating into some module types.
	switch reflect.TypeOf(mod).String() {
	case "*java.Droidstubs":
		return
	}
	jarJarData := collectDirectDepsProviders(ctx)
	if jarJarData != nil {
		providerData := BaseJarJarProviderData{
			JarJarProviderData: *jarJarData,
		}
		android.SetProvider(ctx, BaseJarJarProvider, providerData)
	}

}

// Add a jarjar renaming rule to this module, to be inherited to all dependent modules.
func (module *Module) addJarJarRenameRule(original string, renamed string) {
	if module.jarjarRenameRules == nil {
		module.jarjarRenameRules = make(map[string]string)
	}
	module.jarjarRenameRules[original] = renamed
}

func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
	// Gather repackage information from deps
	// If the dep jas a JarJarProvider, it is used.  Otherwise, any BaseJarJarProvider is used.

	module := ctx.Module()
	moduleName := module.Name()

	ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
		tag := ctx.OtherModuleDependencyTag(m)
		// This logic mirrors that in (*Module).collectDeps above.  There are several places
		// where we explicitly return RenameUseExclude, even though it is the default, to
		// indicate that it has been verified to be the case.
		//
		// Note well: there are probably cases that are getting to the unconditional return
		// and are therefore wrong.
		shouldIncludeRenames := func() (DependencyUse, string) {
			if moduleName == m.Name() {
				return RenameUseInclude, "name" // If we have the same module name, include the renames.
			}
			if sc, ok := module.(android.SdkContext); ok {
				if ctx.Device() {
					sdkDep := decodeSdkDep(ctx, sc)
					if !sdkDep.invalidVersion && sdkDep.useFiles {
						return RenameUseExclude, "useFiles"
					}
				}
			}
			if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
				return RenameUseExclude, "tags"
			}
			if _, ok := m.(SdkLibraryDependency); ok {
				switch tag {
				case sdkLibTag, libTag:
					return RenameUseExclude, "sdklibdep" // matches collectDeps()
				}
				return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
			} else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
				switch ji.StubsLinkType {
				case Stubs:
					return RenameUseExclude, "info"
				case Implementation:
					return RenameUseInclude, "info"
				default:
					//fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m)
					// Fall through to the heuristic logic.
				}
				switch reflect.TypeOf(m).String() {
				case "*java.GeneratedJavaLibraryModule":
					// Probably a java_aconfig_library module.
					// TODO: make this check better.
					return RenameUseInclude, "reflect"
				}
				switch tag {
				case bootClasspathTag:
					return RenameUseExclude, "tagswitch"
				case sdkLibTag, libTag, instrumentationForTag:
					return RenameUseInclude, "tagswitch"
				case java9LibTag:
					return RenameUseExclude, "tagswitch"
				case staticLibTag:
					return RenameUseInclude, "tagswitch"
				case pluginTag:
					return RenameUseInclude, "tagswitch"
				case errorpronePluginTag:
					return RenameUseInclude, "tagswitch"
				case exportedPluginTag:
					return RenameUseInclude, "tagswitch"
				case kotlinPluginTag:
					return RenameUseInclude, "tagswitch"
				default:
					return RenameUseExclude, "tagswitch"
				}
			} else if _, ok := m.(android.SourceFileProducer); ok {
				switch tag {
				case sdkLibTag, libTag, staticLibTag:
					return RenameUseInclude, "srcfile"
				default:
					return RenameUseExclude, "srcfile"
				}
			} else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
				return RenameUseInclude, "aconfig_declarations_group"
			} else {
				switch tag {
				case bootClasspathTag:
					return RenameUseExclude, "else"
				case systemModulesTag:
					return RenameUseInclude, "else"
				}
			}
			// If we got here, choose the safer option, which may lead to a build failure, rather
			// than runtime failures on the device.
			return RenameUseExclude, "end"
		}

		if result == nil {
			result = &JarJarProviderData{
				Rename:    make(map[string]string),
				RenameUse: make([]RenameUseElement, 0),
			}
		}
		how, why := shouldIncludeRenames()
		result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
		if how != RenameUseInclude {
			// Nothing to merge.
			return
		}

		merge := func(theirs *JarJarProviderData) {
			for orig, renamed := range theirs.Rename {
				if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
					result.Rename[orig] = renamed
				} else if preexisting != "" && renamed != "" && preexisting != renamed {
					if strings.HasPrefix(preexisting, overridableJarJarPrefix) {
						result.Rename[orig] = renamed
					} else if !strings.HasPrefix(renamed, overridableJarJarPrefix) {
						ctx.ModuleErrorf("1. Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting, ctx.ModuleName(), m.Name())
						continue
					}
				}
			}
		}
		if theirs, ok := android.OtherModuleProvider(ctx, m, JarJarProvider); ok {
			merge(&theirs)
		} else if theirs, ok := android.OtherModuleProvider(ctx, m, BaseJarJarProvider); ok {
			// TODO: if every java.Module should have a JarJarProvider, and we find only the
			// BaseJarJarProvider, then there is a bug.  Consider seeing if m can be cast
			// to java.Module.
			merge(&theirs.JarJarProviderData)
		}
	})
	return
}

func (this Module) GetDebugString() string {
	return "sdk_version=" + proptools.String(this.deviceProperties.Sdk_version)
}

// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to
// us, and if it's been set, apply the jarjar_prefix property to rename them.
func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData {
	// Gather repackage information from deps
	result := collectDirectDepsProviders(ctx)

	add := func(orig string, renamed string) {
		if result == nil {
			result = &JarJarProviderData{
				Rename: make(map[string]string),
			}
		}
		if renamed != "" {
			if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed {
				ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting)
				return
			}
		}
		(*result).Rename[orig] = renamed
	}

	// Update that with entries we've stored for ourself
	for orig, renamed := range module.jarjarRenameRules {
		add(orig, renamed)
	}

	// Update that with entries given in the jarjar_rename property.
	for _, orig := range module.properties.Jarjar_rename {
		add(orig, "")
	}

	// If there are no renamings, then jarjar_prefix does nothing, so skip the extra work.
	if result == nil {
		return nil
	}

	// If they've given us a jarjar_prefix property, then we will use that to rename any classes
	// that have not yet been renamed.
	prefix := proptools.String(module.properties.Jarjar_prefix)
	if prefix != "" {
		if prefix[0] == '.' {
			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not start with '.'")
			return nil
		}
		if prefix[len(prefix)-1] == '.' {
			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not end with '.'")
			return nil
		}

		var updated map[string]string
		for orig, renamed := range (*result).Rename {
			if renamed == "" {
				if updated == nil {
					updated = make(map[string]string)
				}
				updated[orig] = prefix + "." + orig
			}
		}
		for orig, renamed := range updated {
			(*result).Rename[orig] = renamed
		}
	}

	return result
}

// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
// to "" won't be in this list because they shouldn't be renamed yet.
func getJarJarRuleText(provider *JarJarProviderData) string {
	result := ""
	for _, orig := range android.SortedKeys(provider.Rename) {
		renamed := provider.Rename[orig]
		if renamed != "" {
			result += "rule " + orig + " " + renamed + "\n"
		}
	}
	return result
}

// Repackage the flags if the jarjar rule txt for the flags is generated
func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
	if j.repackageJarjarRules == nil {
		return infile
	}
	repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
	TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
	return repackagedJarjarFile
}

func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
	if j.expandJarjarRules == nil {
		return infile
	}
	jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
	TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules)
	return jarjarFile

}

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)

type ModuleWithUsesLibrary interface {
	UsesLibrary() *usesLibrary
}

func (j *Module) UsesLibrary() *usesLibrary {
	return &j.usesLibrary
}

var _ ModuleWithUsesLibrary = (*Module)(nil)
