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

package java

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	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
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	IsSDKLibrary bool `blueprint:"mutated"`

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

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

	HiddenAPIPackageProperties
	HiddenAPIFlagFileProperties
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Functionality common to Module and Import.
	embeddableInModuleAndImport

	properties       CommonProperties
	protoProperties  android.ProtoProperties
	deviceProperties DeviceProperties

	overridableDeviceProperties OverridableDeviceProperties

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

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

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

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

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

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

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

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

	exportAidlIncludeDirs     android.Paths
	ignoredAidlPermissionList android.Paths

	logtagsSrcs android.Paths

	// installed file for binary dependency
	installFile android.Path

	// installed file for hostdex copy
	hostdexInstallFile android.InstallPath

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

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

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

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

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

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

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

	// expanded Jarjar_rules
	expandJarjarRules android.Path

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

	hiddenAPI
	dexer
	dexpreopter
	usesLibrary
	linter

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

	// Collect the module directory for IDE info in java/jdeps.go.
	modulePaths []string

	hideApexVariantFromMake bool

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

	sourceExtensions []string
}

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) addHostProperties() {
	j.AddProperties(
		&j.properties,
		&j.protoProperties,
		&j.usesLibraryProperties,
	)
}

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

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

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

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

	ctx.SetProvider(hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
}

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

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

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

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

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

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

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

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

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

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

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

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

func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
	maxSdkVersion := proptools.StringDefault(j.deviceProperties.Max_sdk_version, "")
	// SdkSpecFrom returns SdkSpecPrivate for this, which may be confusing.
	// TODO(b/208456999): ideally MaxSdkVersion should be an ApiLevel and not SdkSpec.
	return android.SdkSpecFrom(ctx, maxSdkVersion)
}

func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
	replaceMaxSdkVersionPlaceholder := proptools.StringDefault(j.deviceProperties.Replace_max_sdk_version_placeholder, "")
	return android.SdkSpecFrom(ctx, replaceMaxSdkVersionPlaceholder)
}

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

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

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...)
	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)

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

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

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

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

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

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

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

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

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

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

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

	return false
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	aidlMinSdkVersion := j.MinSdkVersion(ctx).ApiLevel.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

	if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
		// 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...)

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

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

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

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

	return flags
}

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

}

func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
	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...)
	}

	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...)
	if aaptSrcJar != nil {
		srcJars = append(srcJars, aaptSrcJar)
	}
	srcFiles = srcFiles.FilterOutByExt(".srcjar")

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

	jarName := ctx.ModuleName() + ".jar"

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

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

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

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

	var kotlinJars android.Paths
	var kotlinHeaderJars android.Paths

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	j.compiledSrcJars = srcJars

	enableSharding := false
	var headerJarFileWithoutDepsOrJarjar android.Path
	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
			enableSharding = true
			// Formerly, there was a check here that prevented annotation processors
			// from being used when sharding was enabled, as some annotation processors
			// do not function correctly in sharded environments. It was removed to
			// allow for the use of annotation processors that do function correctly
			// with sharding enabled. See: b/77284273.
		}
		headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
		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)

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

			extraJarDeps = append(extraJarDeps, errorprone)
		}

		if enableSharding {
			if headerJarFileWithoutDepsOrJarjar != nil {
				flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...)
			}
			shardSize := int(*(j.properties.Javac_shard_size))
			var shardSrcs []android.Paths
			if len(uniqueJavaFiles) > 0 {
				shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
				for idx, shardSrc := range shardSrcs {
					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
						nil, flags, extraJarDeps)
					jars = append(jars, classes)
				}
			}
			if len(srcJars) > 0 {
				classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
					nil, srcJars, flags, extraJarDeps)
				jars = append(jars, classes)
			}
		} else {
			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
			jars = append(jars, classes)
		}
		if ctx.Failed() {
			return
		}
	}

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

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

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

	var resArgs []string
	var resDeps android.Paths

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

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

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

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

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

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

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

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

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

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

		// 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 {
			// The path contains an embedded OutputPath so reuse that.
			outputFile = moduleOutPath.OutputPath
		} else if outputPath, ok := jars[0].(android.OutputPath); ok {
			// 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 {
		j.headerJarFile = j.implementationJarFile
	}

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

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

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

	j.implementationAndResourcesJar = implementationAndResourcesJar

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

	if ctx.Device() && (Bool(j.properties.Installable) || Bool(compileDex)) {
		if j.hasCode(ctx) {
			if j.shouldInstrumentStatic(ctx) {
				j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
			}
			// Dex compilation
			var dexOutputFile android.OutputPath
			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), implementationAndResourcesJar, jarName)
			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)
					dexOutputFile = combinedAlignedJar
				} else {
					dexOutputFile = combinedJar
				}
			}

			// Initialize the hiddenapi structure.

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

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

			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)

			// Dexpreopting
			j.dexpreopt(ctx, dexOutputFile)

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

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

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

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

	ctx.CheckbuildFile(outputFile)

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

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

// 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")
	if idx >= 0 {
		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
		jarName += strconv.Itoa(idx)
	}

	classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath
	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, 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)
	}

	return classes
}

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

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

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

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

	jars = append(jars, extraJars...)

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

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

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

	return headerJar, jarjarAndDepsHeaderJar
}

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

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

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

	j.jacocoReportClassesFile = jacocoReportClassesFile

	return instrumentedJar
}

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

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

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

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

		dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
		if dep.TransitiveLibsHeaderJars != nil {
			transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJars)
		}
		if dep.TransitiveStaticLibsHeaderJars != nil {
			transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJars)
		}

		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...)
		}
	})
	j.transitiveLibsHeaderJars = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
	j.transitiveStaticLibsHeaderJars = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs)
}

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

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

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

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

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

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

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

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

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 {
	sdkSpec := j.MinSdkVersion(ctx)
	if !sdkSpec.Specified() {
		return fmt.Errorf("min_sdk_version is not specified")
	}
	if sdkSpec.Kind == android.SdkCore {
		return nil
	}
	if sdkSpec.ApiLevel.GreaterThan(sdkVersion) {
		return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel)
	}
	return nil
}

func (j *Module) Stem() string {
	return proptools.StringDefault(j.overridableDeviceProperties.Stem, j.Name())
}

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

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 "core.current.stubs", "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_stubs_current":
		return javaSdk, true
	case "android_system_stubs_current":
		return javaSystem, true
	case "android_module_lib_stubs_current":
		return javaModule, true
	case "android_system_server_stubs_current":
		return javaSystemServer, true
	case "android_test_stubs_current":
		return javaSystem, true
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return deps
}

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

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

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

type ModuleWithStem interface {
	Stem() string
}

var _ ModuleWithStem = (*Module)(nil)

func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
	switch ctx.ModuleType() {
	case "java_library", "java_library_host", "java_library_static":
		if lib, ok := ctx.Module().(*Library); ok {
			javaLibraryBp2Build(ctx, lib)
		}
	case "java_binary_host":
		if binary, ok := ctx.Module().(*Binary); ok {
			javaBinaryHostBp2Build(ctx, binary)
		}
	}
}
