// 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 (
	"encoding/gob"
	"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 proptools.Configurable[[]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

	// jar file containing implementation classes including static library dependencies but no
	// resources
	implementationJarFile 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
	kytheKotlinFiles 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")
}

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) staticLibs(ctx android.BaseModuleContext) []string {
	return android.RemoveListFromList(j.properties.Static_libs.GetOrDefault(ctx, nil), j.properties.Exclude_static_libs)
}

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

	ctx.AddVariationDependencies(nil, staticLibTag, j.staticLibs(ctx)...)

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

	// 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) {
		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, extraDepCombinedJars 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 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...)

	var localImplementationJars android.Paths

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

		transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars

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

		combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
		if jarjared {
			localHeaderJars = android.Paths{combinedHeaderJarFile}
			transitiveStaticLibsHeaderJars = nil
		}
		combinedHeaderJarFile, repackaged := j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
		if repackaged {
			localHeaderJars = android.Paths{combinedHeaderJarFile}
			transitiveStaticLibsHeaderJars = nil
		}
		if ctx.Failed() {
			return
		}
		j.headerJarFile = combinedHeaderJarFile

		if ctx.Config().UseTransitiveJarsInClasspath() {
			if len(localHeaderJars) > 0 {
				ctx.CheckbuildFile(localHeaderJars...)
			} else {
				// There are no local sources or resources in this module, so there is nothing to checkbuild.
				ctx.UncheckedModule()
			}
		} else {
			ctx.CheckbuildFile(j.headerJarFile)
		}

		android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
			HeaderJars:                          android.PathsIfNonNil(j.headerJarFile),
			LocalHeaderJars:                     localHeaderJars,
			TransitiveStaticLibsHeaderJars:      android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
			TransitiveLibsHeaderJarsForR8:       j.transitiveLibsHeaderJarsForR8,
			TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
			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)
			localImplementationJars = append(localImplementationJars, 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)
		j.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...)

		localImplementationJars = append(localImplementationJars, kotlinJarPath)

		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
	}

	j.compiledSrcJars = srcJars

	transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars

	enableSharding := false
	var localHeaderJars android.Paths
	var shardingHeaderJars android.Paths
	var repackagedHeaderJarFile 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
		localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
		shardingHeaderJars = localHeaderJars

		var jarjared bool
		j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
		if jarjared {
			// jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive
			// static libs header jars.
			localHeaderJars = android.Paths{j.headerJarFile}
			transitiveStaticLibsHeaderJars = nil
		}
		var repackaged bool
		repackagedHeaderJarFile, repackaged = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
		if repackaged {
			// repackage modifies transitive static dependencies, use the combined header jar and drop the transitive
			// static libs header jars.
			// TODO(b/356688296): this shouldn't export both the unmodified and repackaged header jars
			localHeaderJars = android.Paths{j.headerJarFile, repackagedHeaderJarFile}
			transitiveStaticLibsHeaderJars = nil
		}
	}
	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 len(shardingHeaderJars) > 0 {
				flags.classpath = append(classpath(slices.Clone(shardingHeaderJars)), 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))
					localImplementationJars = append(localImplementationJars, 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))
					localImplementationJars = append(localImplementationJars, classes)
				}
			}
		} else {
			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
			classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
			localImplementationJars = append(localImplementationJars, classes)
		}
		if ctx.Failed() {
			return
		}
	}

	localImplementationJars = append(localImplementationJars, 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...)

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

	if Bool(j.properties.Include_srcs) {
		localResourceJars = append(localResourceJars, includeSrcJar)
	}

	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,
		})
		localResourceJars = append(localResourceJars, servicesJar)
	}

	completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars)

	var combinedResourceJar android.Path
	var resourceJars android.Paths
	if ctx.Config().UseTransitiveJarsInClasspath() {
		resourceJars = completeStaticLibsResourceJars.ToList()
	} else {
		resourceJars = append(slices.Clone(localResourceJars), deps.staticResourceJars...)
	}
	if len(resourceJars) == 1 {
		combinedResourceJar = resourceJars[0]
	} else if len(resourceJars) > 0 {
		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
			false, nil, nil)
		combinedResourceJar = combinedJar
	}

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

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

	completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars)

	var jars android.Paths
	if ctx.Config().UseTransitiveJarsInClasspath() {
		jars = completeStaticLibsImplementationJars.ToList()
	} else {
		jars = append(slices.Clone(localImplementationJars), deps.staticJars...)
	}

	jars = append(jars, extraDepCombinedJars...)

	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(extraJars) == 0.

		// 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 copy the single input static lib in order to prevent the static lib from being exposed
		// to the copy rules.
		if stub, _ := moduleStubLinkType(j); stub {
			copiedJar := android.PathForModuleOut(ctx, "combined", jarName)
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  jars[0],
				Output: copiedJar,
			})
			completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, android.Paths{copiedJar}, nil)
			outputFile = copiedJar
		} 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, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
	if jarjarred {
		localImplementationJars = android.Paths{jarjarFile}
		completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil)
	}
	outputFile = jarjarFile

	// jarjar resource jar if necessary
	if combinedResourceJar != nil {
		resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource")
		combinedResourceJar = resourceJarJarFile
		if jarjarred {
			localResourceJars = android.Paths{resourceJarJarFile}
			completeStaticLibsResourceJars = android.NewDepSet(android.PREORDER, localResourceJars, nil)
		}
	}

	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
		localImplementationJars = android.Paths{ravenizerOutput}
		completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil)
	}

	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
		localImplementationJars = android.Paths{apiMapperFile}
		completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil)
	}

	// 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
		localImplementationJars = android.Paths{packageCheckOutputFile}
		completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil)

		// 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
		if len(localImplementationJars) == 1 && ctx.Config().UseTransitiveJarsInClasspath() {
			localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName)
			convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile)
			localHeaderJars = append(localHeaderJars, localHeaderJarFile)
		} else {
			localHeaderJars = append(localHeaderJars, headerJarFile)
		}
	}

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

	completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars

	if j.shouldInstrument(ctx) {
		instrumentedOutputFile := j.instrument(ctx, flags, outputFile, jarName, specs)
		completeStaticLibsImplementationJarsToCombine = android.NewDepSet(android.PREORDER, android.Paths{instrumentedOutputFile}, nil)
		outputFile = instrumentedOutputFile
	}

	// merge implementation jar with resources if necessary
	var implementationAndResourcesJarsToCombine android.Paths
	if ctx.Config().UseTransitiveJarsInClasspath() {
		resourceJars := completeStaticLibsResourceJars.ToList()
		if len(resourceJars) > 0 {
			implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...)
			implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
		}
	} else {
		if combinedResourceJar != nil {
			implementationAndResourcesJarsToCombine = android.Paths{combinedResourceJar, outputFile}
		}
	}

	if len(implementationAndResourcesJarsToCombine) > 0 {
		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
		TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJarsToCombine, manifest,
			false, nil, nil)
		outputFile = combinedJar
	}

	j.implementationAndResourcesJar = outputFile

	// 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:    outputFile,
				jarName:       jarName,
			}
			if j.GetProfileGuided(ctx) && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting(ctx) {
				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(ctx) {
				profile := j.GetProfile(ctx)
				if profile == "" || !j.GetProfileGuided(ctx) {
					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
			var dexAndResourceJarsToCombine android.Paths
			if ctx.Config().UseTransitiveJarsInClasspath() {
				resourceJars := completeStaticLibsResourceJars.ToList()
				if len(resourceJars) > 0 {
					dexAndResourceJarsToCombine = append(android.Paths{dexOutputFile}, resourceJars...)
				}
			} else {
				if combinedResourceJar != nil {
					dexAndResourceJarsToCombine = android.Paths{dexOutputFile, combinedResourceJar}
				}
			}
			if len(dexAndResourceJarsToCombine) > 0 {
				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
				TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, 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

			ctx.CheckbuildFile(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.
			j.dexJarFile = makeDexJarPathFromPath(combinedResourceJar)
		}

		if ctx.Failed() {
			return
		}
	}

	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)

	if ctx.Config().UseTransitiveJarsInClasspath() {
		if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
			ctx.CheckbuildFile(localImplementationJars...)
			ctx.CheckbuildFile(localResourceJars...)
			ctx.CheckbuildFile(localHeaderJars...)
		} else {
			// There are no local sources or resources in this module, so there is nothing to checkbuild.
			ctx.UncheckedModule()
		}
	} else {
		ctx.CheckbuildFile(j.implementationJarFile)
		ctx.CheckbuildFile(j.headerJarFile)
	}

	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
		HeaderJars:           android.PathsIfNonNil(j.headerJarFile),
		RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),

		LocalHeaderJars:                        localHeaderJars,
		TransitiveStaticLibsHeaderJars:         android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
		TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
		TransitiveStaticLibsResourceJars:       completeStaticLibsResourceJars,

		TransitiveLibsHeaderJarsForR8:       j.transitiveLibsHeaderJarsForR8,
		TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
		ImplementationAndResourcesJars:      android.PathsIfNonNil(j.implementationAndResourcesJar),
		ImplementationJars:                  android.PathsIfNonNil(j.implementationJarFile),
		ResourceJars:                        android.PathsIfNonNil(combinedResourceJar),
		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(ctx android.BaseModuleContext) bool {
	return android.InList("androidx.compose.runtime_runtime", j.staticLibs(ctx))
}

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) (localHeaderJars android.Paths, combinedHeaderJar android.Path) {

	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)
		localHeaderJars = append(localHeaderJars, turbineJar)
	}

	localHeaderJars = append(localHeaderJars, extraJars...)

	// Combine any static header libraries into classes-header.jar. If there is only
	// one input jar this step will be skipped.
	var jars android.Paths
	if ctx.Config().UseTransitiveJarsInClasspath() {
		depSet := android.NewDepSet(android.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
		jars = depSet.ToList()
	} else {
		jars = append(slices.Clone(localHeaderJars), 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 localHeaderJars, 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 providesTransitiveHeaderJarsForR8 struct {
	// set of header jars for all transitive libs deps
	transitiveLibsHeaderJarsForR8 *android.DepSet[android.Path]
	// set of header jars for all transitive static libs deps
	transitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path]
}

// collectTransitiveHeaderJarsForR8 visits direct dependencies and collects all transitive libs and static_libs
// header jars.  The semantics of the collected jars are odd (it collects combined jars that contain the static
// libs, but also the static libs, and it collects transitive libs dependencies of static_libs), so these
// are only used to expand the --lib arguments to R8.
func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(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.TransitiveLibsHeaderJarsForR8 != nil {
				transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJarsForR8)
			}
			if dep.TransitiveStaticLibsHeaderJarsForR8 != nil {
				transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
			}

		}
	})
	j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
	j.transitiveStaticLibsHeaderJarsForR8 = 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.staticLibs(ctx)...)
	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

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

	j.collectTransitiveHeaderJarsForR8(ctx)

	var transitiveBootClasspathHeaderJars []*android.DepSet[android.Path]
	var transitiveClasspathHeaderJars []*android.DepSet[android.Path]
	var transitiveJava9ClasspathHeaderJars []*android.DepSet[android.Path]
	var transitiveStaticJarsHeaderLibs []*android.DepSet[android.Path]
	var transitiveStaticJarsImplementationLibs []*android.DepSet[android.Path]
	var transitiveStaticJarsResourceLibs []*android.DepSet[android.Path]

	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 sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
			switch tag {
			case sdkLibTag, libTag, staticLibTag:
				generatingLibsString := android.PrettyConcat(
					getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
				ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
			}
		} 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...)
				if dep.TransitiveStaticLibsHeaderJars != nil {
					transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
				}
			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

				if dep.TransitiveStaticLibsHeaderJars != nil {
					transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
				}
			case java9LibTag:
				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
				if dep.TransitiveStaticLibsHeaderJars != nil {
					transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
				}
			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...)

				if dep.TransitiveStaticLibsHeaderJars != nil {
					transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
					transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, dep.TransitiveStaticLibsHeaderJars)
				}
				if dep.TransitiveStaticLibsImplementationJars != nil {
					transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars)
				}
				if dep.TransitiveStaticLibsResourceJars != nil {
					transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars)
				}
			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()...)
				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
					android.NewDepSet(android.PREORDER, dep.Srcs(), nil))
			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()...)

				depHeaderJars := android.NewDepSet(android.PREORDER, dep.Srcs(), nil)
				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars)
				transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars)
				transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars)
			}
		} 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 {
					deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
					if sm.TransitiveStaticLibsHeaderJars != nil {
						transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars,
							sm.TransitiveStaticLibsHeaderJars)
					}
				} 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)
	})

	deps.transitiveStaticLibsHeaderJars = transitiveStaticJarsHeaderLibs
	deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs
	deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs

	if ctx.Config().UseTransitiveJarsInClasspath() {
		depSet := android.NewDepSet(android.PREORDER, nil, transitiveClasspathHeaderJars)
		deps.classpath = depSet.ToList()
		depSet = android.NewDepSet(android.PREORDER, nil, transitiveBootClasspathHeaderJars)
		deps.bootClasspath = depSet.ToList()
		depSet = android.NewDepSet(android.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
		deps.java9Classpath = depSet.ToList()
	}

	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(slices.Clone(classpath(sdkDep.jars)), deps.classpath...)
			deps.dexClasspath = append(slices.Clone(classpath(sdkDep.jars)), deps.dexClasspath...)
			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
		}
	}

	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)

	gob.Register(BaseJarJarProviderData{})
}

// 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.VisitDirectDeps(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 := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); 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, bool) {
	if j.repackageJarjarRules == nil {
		return infile, false
	}
	repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
	TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
	return repackagedJarjarFile, true
}

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

}

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)
