// Copyright 2021 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package java

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	IsSDKLibrary bool `blueprint:"mutated"`

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

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

	HiddenAPIPackageProperties
	HiddenAPIFlagFileProperties
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Functionality common to Module and Import.
	embeddableInModuleAndImport

	properties       CommonProperties
	protoProperties  android.ProtoProperties
	deviceProperties DeviceProperties

	overridableProperties OverridableProperties
	sourceProperties      android.SourceProperties

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

	repackagedHeaderJarFile android.Path

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

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

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

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

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

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

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

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

	exportAidlIncludeDirs     android.Paths
	ignoredAidlPermissionList android.Paths

	logtagsSrcs android.Paths

	// installed file for binary dependency
	installFile android.Path

	// installed file for hostdex copy
	hostdexInstallFile android.InstallPath

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

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

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

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

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

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

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

	// expanded Jarjar_rules
	expandJarjarRules android.Path

	// jarjar rule for inherited jarjar rules
	repackageJarjarRules android.Path

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

	hiddenAPI
	dexer
	dexpreopter
	usesLibrary
	linter

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

	hideApexVariantFromMake bool

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

	sourceExtensions []string

	annoSrcJars android.Paths

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

	// Single aconfig "cache file" merged from this module and all dependencies.
	mergedAconfigFiles map[string]android.Paths

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

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

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

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

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

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

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

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

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

func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
	// Force enable the instrumentation for java code that is built for APEXes ...
	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
	apexInfo, _ := 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) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
	return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return false
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	var flags javaBuilderFlags

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

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

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

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

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

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

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

	// systemModules
	flags.systemModules = deps.systemModules

	return flags
}

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

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

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

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

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

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

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

	return flags
}

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

}

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

func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {

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

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

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

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

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

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

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

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

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

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

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

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

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

	var uniqueSrcFiles android.Paths
	uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
	uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
	j.uniqueSrcFiles = uniqueSrcFiles
	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: uniqueSrcFiles.Strings()})

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

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

	var kotlinJars android.Paths
	var kotlinHeaderJars android.Paths

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

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

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

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

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

		j.outputFile = j.headerJarFile
		return
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	jars := slices.Clone(kotlinJars)

	j.compiledSrcJars = srcJars

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

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

			extraJarDeps = append(extraJarDeps, errorprone)
		}

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

	jars = append(jars, extraCombinedJars...)

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

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

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

	var resArgs []string
	var resDeps android.Paths

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		if ctx.Failed() {
			return
		}
	}

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

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

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

		if ctx.Failed() {
			return
		}
	}

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

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

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

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

	j.implementationAndResourcesJar = implementationAndResourcesJar

	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
	compileDex := j.dexProperties.Compile_dex
	apexInfo, _ := 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.OutputPath
			params := &compileDexParams{
				flags:         flags,
				sdkVersion:    j.SdkVersion(ctx),
				minSdkVersion: j.MinSdkVersion(ctx),
				classesJar:    implementationAndResourcesJar,
				jarName:       jarName,
			}
			dexOutputFile = j.dexer.compileDex(ctx, params)
			if ctx.Failed() {
				return
			}

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

			// Initialize the hiddenapi structure.

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

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

			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)

			// Dexpreopting
			j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile)

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

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

	if ctx.Device() {
		lintSDKVersion := func(apiLevel android.ApiLevel) android.ApiLevel {
			if !apiLevel.IsPreview() {
				return apiLevel
			} else {
				return ctx.Config().DefaultAppTargetSdk(ctx)
			}
		}

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

	j.collectTransitiveSrcFiles(ctx, srcFiles)

	ctx.CheckbuildFile(outputFile)

	android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)

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

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

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

func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []*android.DepSet[android.Path]) {
	ctx.VisitDirectDeps(func(m android.Module) {
		depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
		depTag := ctx.OtherModuleDependencyTag(m)

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

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

	return transitiveProguardFlags, transitiveUnconditionalExportedFlags
}

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

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

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

}

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

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

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

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

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

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

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

	return classes
}

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

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

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

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

	jars = append(jars, extraJars...)

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

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

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

	if j.repackageJarjarRules != nil {
		repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-turbine-jarjar", jarName)
		TransformJarJar(ctx, repackagedJarjarFile, jarjarAndDepsHeaderJar, j.repackageJarjarRules)
		jarjarAndDepsRepackagedHeaderJar = repackagedJarjarFile
		if ctx.Failed() {
			return nil, nil, nil
		}
	} else {
		jarjarAndDepsRepackagedHeaderJar = jarjarAndDepsHeaderJar
	}

	return headerJar, jarjarAndDepsHeaderJar, jarjarAndDepsRepackagedHeaderJar
}

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

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

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

	j.jacocoReportClassesFile = jacocoReportClassesFile

	return instrumentedJar
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
	var fromDeps []*android.DepSet[android.Path]
	ctx.VisitDirectDeps(func(module android.Module) {
		tag := ctx.OtherModuleDependencyTag(module)
		if tag == staticLibTag {
			depInfo, _ := android.OtherModuleProvider(ctx, module, JavaInfoProvider)
			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 (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
	switch name {
	case android.SdkCore.DefaultJavaLibraryName(),
		"legacy.core.platform.api.stubs",
		"stable.core.platform.api.stubs",
		"stub-annotations", "private-stub-annotations-jar",
		"core-lambda-stubs",
		"core-generated-annotation-stubs":
		return javaCore, true
	case android.SdkPublic.DefaultJavaLibraryName():
		return javaSdk, true
	case android.SdkSystem.DefaultJavaLibraryName():
		return javaSystem, true
	case android.SdkModule.DefaultJavaLibraryName():
		return javaModule, true
	case android.SdkSystemServer.DefaultJavaLibraryName():
		return javaSystemServer, true
	case android.SdkTest.DefaultJavaLibraryName():
		return javaSystem, true
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return deps
}

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

const (
	RenameUseInvalid DependencyUse = iota
	RenameUseInclude
	RenameUseExclude
)

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

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

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

var JarJarProvider = blueprint.NewProvider[JarJarProviderData]()

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

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

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

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

var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]()

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

}

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

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

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

	ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
		tag := ctx.OtherModuleDependencyTag(m)
		// This logic mirrors that in (*Module).collectDeps above.  There are several places
		// where we explicitly return RenameUseExclude, even though it is the default, to
		// indicate that it has been verified to be the case.
		//
		// Note well: there are probably cases that are getting to the unconditional return
		// and are therefore wrong.
		shouldIncludeRenames := func() (DependencyUse, string) {
			if moduleName == m.Name() {
				return RenameUseInclude, "name" // If we have the same module name, include the renames.
			}
			if sc, ok := module.(android.SdkContext); ok {
				if ctx.Device() {
					sdkDep := decodeSdkDep(ctx, sc)
					if !sdkDep.invalidVersion && sdkDep.useFiles {
						return RenameUseExclude, "useFiles"
					}
				}
			}
			if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
				return RenameUseExclude, "tags"
			}
			if _, ok := m.(SdkLibraryDependency); ok {
				switch tag {
				case sdkLibTag, libTag:
					return RenameUseExclude, "sdklibdep" // matches collectDeps()
				}
				return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
			} else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
				switch ji.StubsLinkType {
				case Stubs:
					return RenameUseExclude, "info"
				case Implementation:
					return RenameUseInclude, "info"
				default:
					//fmt.Printf("LJ: %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 kotlinStdlibTag, kotlinAnnotationsTag:
					return RenameUseExclude, "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)

	// Update that with entries we've stored for ourself
	for orig, renamed := range module.jarjarRenameRules {
		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)
				continue
			}
		}
		(*result).Rename[orig] = renamed
	}

	// 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.WritablePath, jarName, info string) android.WritablePath {
	if j.repackageJarjarRules == nil {
		return infile
	}
	repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info+jarName)
	TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
	return repackagedJarjarFile
}

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)
