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

	Instrument 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 compiling against the current platform.
	// Values are of one of the following forms:
	// 1) numerical API level or "current"
	// 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 value 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 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.
	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"`
}

// 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.SdkBase
	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 .java files and srcjars that was passed to javac
	compiledJavaSrcs android.Paths
	compiledSrcJars  android.Paths

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

	// map of SDK version to class loader context
	classLoaderContexts dexpreopt.ClassLoaderContextMap

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

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 ".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.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) 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) 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.
					optional := android.InList(*lib, dexpreopt.OptionalCompatUsesLibs)
					tag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, optional, true)
					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")
		if len(j.properties.Plugins) > 0 {
			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) (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

	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 {
		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
	}

	if len(j.exportAidlIncludeDirs) > 0 {
		flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
	}

	if len(aidlIncludes) > 0 {
		flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
	}

	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
		flags = append(flags, "-I"+src.String())
	}

	if Bool(j.deviceProperties.Aidl.Generate_traces) {
		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().TestProductVariables == nil {
			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

	// aidl flags.
	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)

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

	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"

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

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

	var kotlinJars android.Paths

	if srcFiles.HasExt(".kt") {
		// 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"
		}

		var kotlinSrcFiles android.Paths
		kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
		kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)

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

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

		flags.dexClasspath = append(flags.dexClasspath, 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, kotlinSrcFiles, 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)
		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
		if ctx.Failed() {
			return
		}

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

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

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

	// Store the list of .java files that was passed to javac
	j.compiledJavaSrcs = uniqueSrcFiles
	j.compiledSrcJars = srcJars

	enableSharding := false
	var headerJarFileWithoutDepsOrJarjar android.Path
	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.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, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
		if ctx.Failed() {
			return
		}
	}
	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
		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 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, uniqueSrcFiles, 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(uniqueSrcFiles) > 0 {
				shardSrcs = android.ShardPaths(uniqueSrcFiles, 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, uniqueSrcFiles, 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
	}

	if j.shouldInstrumentInApex(ctx) {
		j.properties.Instrument = true
	}

	// 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
	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
	if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() {
		if j.dexProperties.Compile_dex == nil {
			j.dexProperties.Compile_dex = proptools.BoolPtr(true)
		}
		if j.deviceProperties.Hostdex == nil {
			j.deviceProperties.Hostdex = proptools.BoolPtr(true)
		}
	}

	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) {
		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() {
		lintSDKVersionString := func(sdkSpec android.SdkSpec) string {
			if v := sdkSpec.ApiLevel; !v.IsPreview() {
				return v.String()
			} else {
				return ctx.Config().DefaultAppTargetSdk(ctx).String()
			}
		}

		j.linter.name = ctx.ModuleName()
		j.linter.srcs = srcFiles
		j.linter.srcJars = srcJars
		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
		j.linter.classes = j.implementationJarFile
		j.linter.minSdkVersion = lintSDKVersionString(j.MinSdkVersion(ctx))
		j.linter.targetSdkVersion = lintSDKVersionString(j.TargetSdkVersion(ctx))
		j.linter.compileSdkVersion = lintSDKVersionString(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),
		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
}

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

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

	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 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 libTag, instrumentationForTag:
				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:
				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 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)
		}
	}
}
