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

// This file contains the module types for compiling Java for Android, and converts the properties
// into the flags and filenames necessary to pass to the Module.  The final creation of the rules
// is handled in builder.go

import (
	"fmt"
	"path/filepath"
	"slices"
	"sort"
	"strings"

	"android/soong/remoteexec"

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

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

func init() {
	registerJavaBuildComponents(android.InitRegistrationContext)

	RegisterJavaSdkMemberTypes()
}

func registerJavaBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("java_defaults", DefaultsFactory)

	ctx.RegisterModuleType("java_library", LibraryFactory)
	ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
	ctx.RegisterModuleType("java_binary", BinaryFactory)
	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
	ctx.RegisterModuleType("java_test", TestFactory)
	ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
	ctx.RegisterModuleType("java_test_host", TestHostFactory)
	ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
	ctx.RegisterModuleType("java_import", ImportFactory)
	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
	ctx.RegisterModuleType("dex_import", DexImportFactory)
	ctx.RegisterModuleType("java_api_library", ApiLibraryFactory)
	ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory)
	ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory)
	ctx.RegisterModuleType("java_genrule_combiner", GenruleCombinerFactory)

	// This mutator registers dependencies on dex2oat for modules that should be
	// dexpreopted. This is done late when the final variants have been
	// established, to not get the dependencies split into the wrong variants and
	// to support the checks in dexpreoptDisabled().
	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
		ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator)
		// needs access to ApexInfoProvider which is available after variant creation
		ctx.BottomUp("jacoco_deps", jacocoDepsMutator)
	})

	ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}

func RegisterJavaSdkMemberTypes() {
	// Register sdk member types.
	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
	android.RegisterSdkMemberType(javaLibsSdkMemberType)
	android.RegisterSdkMemberType(JavaBootLibsSdkMemberType)
	android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType)
	android.RegisterSdkMemberType(javaTestSdkMemberType)
}

type StubsLinkType int

const (
	Unknown StubsLinkType = iota
	Stubs
	Implementation
)

var (
	// Supports adding java header libraries to module_exports and sdk.
	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
		android.SdkMemberTypeBase{
			PropertyName: "java_header_libs",
			SupportsSdk:  true,
		},
		func(_ android.SdkMemberContext, j *Library) android.Path {
			headerJars := j.HeaderJars()
			if len(headerJars) != 1 {
				panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
			}

			return headerJars[0]
		},
		sdkSnapshotFilePathForJar,
		copyEverythingToSnapshot,
	}

	// Export implementation classes jar as part of the sdk.
	exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path {
		implementationJars := j.ImplementationAndResourcesJars()
		if len(implementationJars) != 1 {
			panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
		}
		return implementationJars[0]
	}

	// Supports adding java implementation libraries to module_exports but not sdk.
	javaLibsSdkMemberType = &librarySdkMemberType{
		android.SdkMemberTypeBase{
			PropertyName: "java_libs",
		},
		exportImplementationClassesJar,
		sdkSnapshotFilePathForJar,
		copyEverythingToSnapshot,
	}

	snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
		// In the S build the build will break if updatable-media does not provide a full implementation
		// jar. That issue was fixed in Tiramisu by b/229932396.
		if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" {
			return true
		}

		return false
	}

	// Supports adding java boot libraries to module_exports and sdk.
	//
	// The build has some implicit dependencies (via the boot jars configuration) on a number of
	// modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are
	// provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise
	// used outside those mainline modules.
	//
	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
	// either java_libs, or java_header_libs would end up exporting more information than was strictly
	// necessary. The java_boot_libs property to allow those modules to be exported as part of the
	// sdk/module_exports without exposing any unnecessary information.
	JavaBootLibsSdkMemberType = &librarySdkMemberType{
		android.SdkMemberTypeBase{
			PropertyName: "java_boot_libs",
			SupportsSdk:  true,
		},
		func(ctx android.SdkMemberContext, j *Library) android.Path {
			if snapshotRequiresImplementationJar(ctx) {
				return exportImplementationClassesJar(ctx, j)
			}

			// Java boot libs are only provided in the SDK to provide access to their dex implementation
			// jar for use by dexpreopting and boot jars package check. They do not need to provide an
			// actual implementation jar but the java_import will need a file that exists so just copy an
			// empty file. Any attempt to use that file as a jar will cause a build error.
			return ctx.SnapshotBuilder().EmptyFile()
		},
		func(ctx android.SdkMemberContext, osPrefix, name string) string {
			if snapshotRequiresImplementationJar(ctx) {
				return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
			}

			// Create a special name for the implementation jar to try and provide some useful information
			// to a developer that attempts to compile against this.
			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
			return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
		},
		onlyCopyJarToSnapshot,
	}

	// Supports adding java systemserver libraries to module_exports and sdk.
	//
	// The build has some implicit dependencies (via the systemserver jars configuration) on a number
	// of modules that are part of the java systemserver classpath and which are provided by mainline
	// modules but which are not otherwise used outside those mainline modules.
	//
	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
	// either java_libs, or java_header_libs would end up exporting more information than was strictly
	// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
	// the sdk/module_exports without exposing any unnecessary information.
	JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{
		android.SdkMemberTypeBase{
			PropertyName: "java_systemserver_libs",
			SupportsSdk:  true,

			// This was only added in Tiramisu.
			SupportedBuildReleaseSpecification: "Tiramisu+",
		},
		func(ctx android.SdkMemberContext, j *Library) android.Path {
			// Java systemserver libs are only provided in the SDK to provide access to their dex
			// implementation jar for use by dexpreopting. They do not need to provide an actual
			// implementation jar but the java_import will need a file that exists so just copy an empty
			// file. Any attempt to use that file as a jar will cause a build error.
			return ctx.SnapshotBuilder().EmptyFile()
		},
		func(_ android.SdkMemberContext, osPrefix, name string) string {
			// Create a special name for the implementation jar to try and provide some useful information
			// to a developer that attempts to compile against this.
			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
			return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
		},
		onlyCopyJarToSnapshot,
	}

	// Supports adding java test libraries to module_exports but not sdk.
	javaTestSdkMemberType = &testSdkMemberType{
		SdkMemberTypeBase: android.SdkMemberTypeBase{
			PropertyName: "java_tests",
		},
	}

	// Rule for generating device binary default wrapper
	deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{
		Command: `printf '#!/system/bin/sh\n` +
			`export CLASSPATH=/system/framework/$jar_name\n` +
			`exec app_process /$partition/bin $main_class "$$@"\n'> ${out}`,
		Description: "Generating device binary wrapper ${jar_name}",
	}, "jar_name", "partition", "main_class")
)

type ProguardSpecInfo struct {
	// If true, proguard flags files will be exported to reverse dependencies across libs edges
	// If false, proguard flags files will only be exported to reverse dependencies across
	// static_libs edges.
	Export_proguard_flags_files bool

	// TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from
	// all transitive deps. This list includes all proguard flags files from transitive static dependencies,
	// and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`.
	ProguardFlagsFiles depset.DepSet[android.Path]

	// implementation detail to store transitive proguard flags files from exporting shared deps
	UnconditionallyExportedProguardFlags depset.DepSet[android.Path]
}

var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()

type AndroidLibraryDependencyInfo struct {
	ExportPackage       android.Path
	ResourcesNodeDepSet depset.DepSet[*resourcesNode]
	RRODirsDepSet       depset.DepSet[rroDir]
	ManifestsDepSet     depset.DepSet[android.Path]
}

type UsesLibraryDependencyInfo struct {
	DexJarInstallPath   android.Path
	ClassLoaderContexts dexpreopt.ClassLoaderContextMap
}

type SdkLibraryComponentDependencyInfo struct {
	// The name of the implementation library for the optional SDK library or nil, if there isn't one.
	OptionalSdkLibraryImplementation *string
}

type ProvidesUsesLibInfo struct {
	ProvidesUsesLib *string
}

type ModuleWithUsesLibraryInfo struct {
	UsesLibrary *usesLibrary
}

type ModuleWithSdkDepInfo struct {
	SdkLinkType sdkLinkType
	Stubs       bool
}

// JavaInfo contains information about a java module for use by modules that depend on it.
type JavaInfo struct {
	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
	// against this module.  If empty, ImplementationJars should be used instead.
	// Unlike LocalHeaderJars, HeaderJars includes classes from static dependencies.
	HeaderJars android.Paths

	RepackagedHeaderJars android.Paths

	// set of header jars for all transitive libs deps
	TransitiveLibsHeaderJarsForR8 depset.DepSet[android.Path]

	// set of header jars for all transitive static libs deps
	TransitiveStaticLibsHeaderJarsForR8 depset.DepSet[android.Path]

	// depset of header jars for this module and all transitive static dependencies
	TransitiveStaticLibsHeaderJars depset.DepSet[android.Path]

	// depset of implementation jars for this module and all transitive static dependencies
	TransitiveStaticLibsImplementationJars depset.DepSet[android.Path]

	// depset of resource jars for this module and all transitive static dependencies
	TransitiveStaticLibsResourceJars depset.DepSet[android.Path]

	// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
	// in the module as well as any resources included in the module.
	ImplementationAndResourcesJars android.Paths

	// ImplementationJars is a list of jars that contain the implementations of classes in the
	// module.
	ImplementationJars android.Paths

	// ResourceJars is a list of jars that contain the resources included in the module.
	ResourceJars android.Paths

	// LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies.
	LocalHeaderJars android.Paths

	// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
	// depending on this module.
	AidlIncludeDirs android.Paths

	// SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this
	// module.
	SrcJarArgs []string

	// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
	SrcJarDeps android.Paths

	// The source files of this module and all its transitive static dependencies.
	TransitiveSrcFiles depset.DepSet[android.Path]

	// ExportedPlugins is a list of paths that should be used as annotation processors for any
	// module that depends on this module.
	ExportedPlugins android.Paths

	// ExportedPluginClasses is a list of classes that should be run as annotation processors for
	// any module that depends on this module.
	ExportedPluginClasses []string

	// ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs,
	// requiring disbling turbine for any modules that depend on it.
	ExportedPluginDisableTurbine bool

	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
	// instrumented by jacoco.
	JacocoReportClassesFile android.Path

	// StubsLinkType provides information about whether the provided jars are stub jars or
	// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
	// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
	StubsLinkType StubsLinkType

	// AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the
	// java_aconfig_library modules that are statically linked to this module.
	AconfigIntermediateCacheOutputPaths android.Paths

	SdkVersion android.SdkSpec

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

	ExtraOutputFiles android.Paths

	AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo

	UsesLibraryDependencyInfo *UsesLibraryDependencyInfo

	SdkLibraryComponentDependencyInfo *SdkLibraryComponentDependencyInfo

	ProvidesUsesLibInfo *ProvidesUsesLibInfo

	MissingOptionalUsesLibs []string

	ModuleWithSdkDepInfo *ModuleWithSdkDepInfo

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

	// installed file for binary dependency
	InstallFile android.Path

	// The path to the dex jar that is in the boot class path. If this is unset then the associated
	// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
	// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
	// themselves.
	//
	// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
	// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
	BootDexJarPath OptionalDexJarPath

	// The compressed state of the dex file being encoded. This is used to ensure that the encoded
	// dex file has the same state.
	UncompressDexState *bool

	// True if the module containing this structure contributes to the hiddenapi information or has
	// that information encoded within it.
	Active bool

	BuiltInstalled string

	// The config is used for two purposes:
	// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
	//   a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
	//   Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
	// - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
	//   dexpreopt another partition).
	ConfigPath android.WritablePath

	LogtagsSrcs android.Paths

	ProguardDictionary android.OptionalPath

	ProguardUsageZip android.OptionalPath

	LinterReports android.Paths

	// installed file for hostdex copy
	HostdexInstallFile android.InstallPath

	// Additional srcJars tacked in by GeneratedJavaLibraryModule
	GeneratedSrcjars []android.Path

	// True if profile-guided optimization is actually enabled.
	ProfileGuided bool

	Stem string

	DexJarBuildPath OptionalDexJarPath

	DexpreopterInfo *DexpreopterInfo

	XrefJavaFiles   android.Paths
	XrefKotlinFiles android.Paths
}

var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()

type DexpreopterInfo struct {
	// The path to the profile on host that dexpreopter generates. This is used as the input for
	// dex2oat.
	OutputProfilePathOnHost android.Path
	// If the java module is to be installed into an APEX, this list contains information about the
	// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
	// outside of the APEX.
	ApexSystemServerDexpreoptInstalls []DexpreopterInstall

	// ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar.
	ApexSystemServerDexJars android.Paths
}

type JavaLibraryInfo struct {
	Prebuilt bool
}

var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]()

type JavaDexImportInfo struct{}

var JavaDexImportInfoProvider = blueprint.NewProvider[JavaDexImportInfo]()

// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to
// the sysprop implementation library.
type SyspropPublicStubInfo struct {
	// JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to
	// the sysprop implementation library.
	JavaInfo *JavaInfo
}

var SyspropPublicStubInfoProvider = blueprint.NewProvider[SyspropPublicStubInfo]()

// Methods that need to be implemented for a module that is added to apex java_libs property.
type ApexDependency interface {
	HeaderJars() android.Paths
	ImplementationAndResourcesJars() android.Paths
}

// Provides build path and install path to DEX jars.
type UsesLibraryDependency interface {
	DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
	DexJarInstallPath() android.Path
	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
}

// TODO(jungjw): Move this to kythe.go once it's created.
type xref interface {
	XrefJavaFiles() android.Paths
	XrefKotlinFiles() android.Paths
}

func (j *Module) XrefJavaFiles() android.Paths {
	return j.kytheFiles
}

func (j *Module) XrefKotlinFiles() android.Paths {
	return j.kytheKotlinFiles
}

func (d dependencyTag) PropagateAconfigValidation() bool {
	return d.static
}

var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string

	// True if the dependency is relinked at runtime.
	runtimeLinked bool

	// True if the dependency is a toolchain, for example an annotation processor.
	toolchain bool

	static bool

	installable bool
}

var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil)

func (d dependencyTag) InstallDepNeeded() bool {
	return d.installable
}

func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
	if d.runtimeLinked {
		return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
	} else if d.toolchain {
		return []android.LicenseAnnotation{android.LicenseAnnotationToolchain}
	}
	return nil
}

var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}

type usesLibraryDependencyTag struct {
	dependencyTag
	sdkVersion int  // SDK version in which the library appared as a standalone library.
	optional   bool // If the dependency is optional or required.
}

func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag {
	return usesLibraryDependencyTag{
		dependencyTag: dependencyTag{
			name:          fmt.Sprintf("uses-library-%d", sdkVersion),
			runtimeLinked: true,
		},
		sdkVersion: sdkVersion,
		optional:   optional,
	}
}

func IsJniDepTag(depTag blueprint.DependencyTag) bool {
	return depTag == jniLibTag || depTag == jniInstallTag
}

var (
	dataNativeBinsTag       = dependencyTag{name: "dataNativeBins"}
	dataDeviceBinsTag       = dependencyTag{name: "dataDeviceBins"}
	staticLibTag            = dependencyTag{name: "staticlib", static: true}
	libTag                  = dependencyTag{name: "javalib", runtimeLinked: true}
	sdkLibTag               = dependencyTag{name: "sdklib", runtimeLinked: true}
	java9LibTag             = dependencyTag{name: "java9lib", runtimeLinked: true}
	pluginTag               = dependencyTag{name: "plugin", toolchain: true}
	errorpronePluginTag     = dependencyTag{name: "errorprone-plugin", toolchain: true}
	exportedPluginTag       = dependencyTag{name: "exported-plugin", toolchain: true}
	bootClasspathTag        = dependencyTag{name: "bootclasspath", runtimeLinked: true}
	systemModulesTag        = dependencyTag{name: "system modules", runtimeLinked: true}
	frameworkResTag         = dependencyTag{name: "framework-res"}
	kotlinPluginTag         = dependencyTag{name: "kotlin-plugin", toolchain: true}
	proguardRaiseTag        = dependencyTag{name: "proguard-raise"}
	certificateTag          = dependencyTag{name: "certificate"}
	instrumentationForTag   = dependencyTag{name: "instrumentation_for"}
	extraLintCheckTag       = dependencyTag{name: "extra-lint-check", toolchain: true}
	jniLibTag               = dependencyTag{name: "jnilib", runtimeLinked: true}
	r8LibraryJarTag         = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
	traceReferencesTag      = dependencyTag{name: "trace-references"}
	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
	aconfigDeclarationTag   = dependencyTag{name: "aconfig-declaration"}
	jniInstallTag           = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
	usesLibReqTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
	usesLibOptTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
	usesLibCompat28OptTag   = makeUsesLibraryDependencyTag(28, true)
	usesLibCompat29ReqTag   = makeUsesLibraryDependencyTag(29, false)
	usesLibCompat30OptTag   = makeUsesLibraryDependencyTag(30, true)
)

// A list of tags for deps used for compiling a module.
// Any dependency tags that modifies the following properties of `deps` in `Module.collectDeps` should be
// added to this list:
// - bootClasspath
// - classpath
// - java9Classpath
// - systemModules
// - kotlin deps...
var (
	compileDependencyTags = []blueprint.DependencyTag{
		sdkLibTag,
		libTag,
		staticLibTag,
		bootClasspathTag,
		systemModulesTag,
		java9LibTag,
		kotlinPluginTag,
		syspropPublicStubDepTag,
		instrumentationForTag,
		traceReferencesTag,
	}
)

func IsLibDepTag(depTag blueprint.DependencyTag) bool {
	return depTag == libTag
}

func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
	return depTag == staticLibTag
}

type sdkDep struct {
	useModule, useFiles, invalidVersion bool

	// The modules that will be added to the bootclasspath when targeting 1.8 or lower
	bootclasspath []string

	// The default system modules to use. Will be an empty string if no system
	// modules are to be used.
	systemModules string

	// The modules that will be added to the classpath regardless of the Java language level targeted
	classpath []string

	// The modules that will be added ot the classpath when targeting 1.9 or higher
	// (normally these will be on the bootclasspath when targeting 1.8 or lower)
	java9Classpath []string

	frameworkResModule string

	jars android.Paths
	aidl android.OptionalPath

	noStandardLibs, noFrameworksLibs bool
}

func (s sdkDep) hasStandardLibs() bool {
	return !s.noStandardLibs
}

func (s sdkDep) hasFrameworkLibs() bool {
	return !s.noStandardLibs && !s.noFrameworksLibs
}

type jniLib struct {
	name           string
	path           android.Path
	target         android.Target
	coverageFile   android.OptionalPath
	unstrippedFile android.Path
	partition      string
	installPaths   android.InstallPaths
}

func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
	sdkDep := decodeSdkDep(ctx, sdkContext)
	if sdkDep.useModule {
		ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
		ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
		ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
		if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
			ctx.AddVariationDependencies(nil, proguardRaiseTag,
				config.LegacyCorePlatformBootclasspathLibraries...,
			)
		}
		if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
			ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
		}
	}
	if sdkDep.systemModules != "" {
		ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
	}
}

type deps struct {
	// bootClasspath is the list of jars that form the boot classpath (generally the java.* and
	// android.* classes) for tools that still use it.  javac targeting 1.9 or higher uses
	// systemModules and java9Classpath instead.
	bootClasspath classpath

	// classpath is the list of jars that form the classpath for javac and kotlinc rules.  It
	// contains header jars for all static and non-static dependencies.
	classpath classpath

	// dexClasspath is the list of jars that form the classpath for d8 and r8 rules.  It contains
	// header jars for all non-static dependencies.  Static dependencies have already been
	// combined into the program jar.
	dexClasspath classpath

	// java9Classpath is the list of jars that will be added to the classpath when targeting
	// 1.9 or higher.  It generally contains the android.* classes, while the java.* classes
	// are provided by systemModules.
	java9Classpath classpath

	processorPath           classpath ``
	errorProneProcessorPath classpath
	processorClasses        []string
	staticJars              android.Paths
	staticHeaderJars        android.Paths
	staticResourceJars      android.Paths
	aidlIncludeDirs         android.Paths
	srcs                    android.Paths
	srcJars                 android.Paths
	systemModules           *systemModules
	aidlPreprocess          android.OptionalPath
	kotlinPlugins           android.Paths
	aconfigProtoFiles       android.Paths

	disableTurbine bool

	transitiveStaticLibsHeaderJars         []depset.DepSet[android.Path]
	transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
	transitiveStaticLibsResourceJars       []depset.DepSet[android.Path]
}

func checkProducesJars(ctx android.ModuleContext, dep android.SourceFilesInfo, module android.ModuleProxy) {
	for _, f := range dep.Srcs {
		if f.Ext() != ".jar" {
			ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
				ctx.OtherModuleName(module))
		}
	}
}

func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion {
	if javaVersion != "" {
		return normalizeJavaVersion(ctx, javaVersion)
	} else if ctx.Device() {
		return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
	} else if ctx.Config().TargetsJava21() {
		// Build flag that controls whether Java 21 is used as the default
		// target version, or Java 17.
		return JAVA_VERSION_21
	} else {
		return JAVA_VERSION_17
	}
}

// Java version for stubs generation
func getStubsJavaVersion() javaVersion {
	return JAVA_VERSION_8
}

type javaVersion int

const (
	JAVA_VERSION_UNSUPPORTED = 0
	JAVA_VERSION_6           = 6
	JAVA_VERSION_7           = 7
	JAVA_VERSION_8           = 8
	JAVA_VERSION_9           = 9
	JAVA_VERSION_11          = 11
	JAVA_VERSION_17          = 17
	JAVA_VERSION_21          = 21
)

func (v javaVersion) String() string {
	switch v {
	case JAVA_VERSION_6:
		// Java version 1.6 no longer supported, bumping to 1.8
		return "1.8"
	case JAVA_VERSION_7:
		// Java version 1.7 no longer supported, bumping to 1.8
		return "1.8"
	case JAVA_VERSION_8:
		return "1.8"
	case JAVA_VERSION_9:
		return "1.9"
	case JAVA_VERSION_11:
		return "11"
	case JAVA_VERSION_17:
		return "17"
	case JAVA_VERSION_21:
		return "21"
	default:
		return "unsupported"
	}
}

func (v javaVersion) StringForKotlinc() string {
	// $ ./external/kotlinc/bin/kotlinc -jvm-target foo
	// error: unknown JVM target version: foo
	// Supported versions: 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17
	switch v {
	case JAVA_VERSION_6:
		return "1.8"
	case JAVA_VERSION_7:
		return "1.8"
	case JAVA_VERSION_9:
		return "9"
	default:
		return v.String()
	}
}

// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
func (v javaVersion) usesJavaModules() bool {
	return v >= 9
}

func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion {
	switch javaVersion {
	case "1.6", "6":
		// Java version 1.6 no longer supported, bumping to 1.8
		return JAVA_VERSION_8
	case "1.7", "7":
		// Java version 1.7 no longer supported, bumping to 1.8
		return JAVA_VERSION_8
	case "1.8", "8":
		return JAVA_VERSION_8
	case "1.9", "9":
		return JAVA_VERSION_9
	case "11":
		return JAVA_VERSION_11
	case "17":
		return JAVA_VERSION_17
	case "21":
		return JAVA_VERSION_21
	case "10", "12", "13", "14", "15", "16":
		ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion)
		return JAVA_VERSION_UNSUPPORTED
	default:
		ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
		return JAVA_VERSION_UNSUPPORTED
	}
}

//
// Java libraries (.jar file)
//

type Library struct {
	Module

	combinedExportedProguardFlagsFile android.Path

	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths)

	apiXmlFile android.WritablePath
}

var _ android.ApexModule = (*Library)(nil)

func (j *Library) CheckDepsMinSdkVersion(ctx android.ModuleContext) {
	CheckMinSdkVersion(ctx, j)
}

// Provides access to the list of permitted packages from apex boot jars.
type PermittedPackagesForUpdatableBootJars interface {
	PermittedPackagesForUpdatableBootJars() []string
}

var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)

func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
	return j.properties.Permitted_packages
}

func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool {
	// Store uncompressed (and aligned) any dex files from jars in APEXes.
	if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
		return true
	}

	// Store uncompressed (and do not strip) dex files from boot class path jars.
	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
		return true
	}

	// Store uncompressed dex files that are preopted on /system or /system_other.
	if !dexpreopter.dexpreoptDisabled(ctx, libName) {
		return true
	}

	if ctx.Config().UncompressPrivAppDex() &&
		inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
		return true
	}

	return false
}

// Sets `dexer.dexProperties.Uncompress_dex` to the proper value.
func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) {
	if dexer.dexProperties.Uncompress_dex == nil {
		// If the value was not force-set by the user, use reasonable default based on the module.
		dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter))
	}
}

// list of java_library modules that set platform_apis: true
// this property is a no-op for java_library
// TODO (b/215379393): Remove this allowlist
var (
	aospPlatformApiAllowlist = map[string]bool{
		"adservices-test-scenarios":                         true,
		"aidl-cpp-java-test-interface-java":                 true,
		"aidl-test-extras-java":                             true,
		"aidl-test-interface-java":                          true,
		"aidl-test-interface-permission-java":               true,
		"aidl_test_java_client_permission":                  true,
		"aidl_test_java_client_sdk1":                        true,
		"aidl_test_java_client_sdk29":                       true,
		"aidl_test_java_client":                             true,
		"aidl_test_java_service_permission":                 true,
		"aidl_test_java_service_sdk1":                       true,
		"aidl_test_java_service_sdk29":                      true,
		"aidl_test_java_service":                            true,
		"aidl_test_loggable_interface-java":                 true,
		"aidl_test_nonvintf_parcelable-V1-java":             true,
		"aidl_test_nonvintf_parcelable-V2-java":             true,
		"aidl_test_unstable_parcelable-java":                true,
		"aidl_test_vintf_parcelable-V1-java":                true,
		"aidl_test_vintf_parcelable-V2-java":                true,
		"android.aidl.test.trunk-V1-java":                   true,
		"android.aidl.test.trunk-V2-java":                   true,
		"android.frameworks.location.altitude-V1-java":      true,
		"android.frameworks.location.altitude-V2-java":      true,
		"android.frameworks.stats-V1-java":                  true,
		"android.frameworks.stats-V2-java":                  true,
		"android.frameworks.stats-V3-java":                  true,
		"android.hardware.authsecret-V1-java":               true,
		"android.hardware.authsecret-V2-java":               true,
		"android.hardware.biometrics.common-V1-java":        true,
		"android.hardware.biometrics.common-V2-java":        true,
		"android.hardware.biometrics.common-V3-java":        true,
		"android.hardware.biometrics.common-V4-java":        true,
		"android.hardware.biometrics.face-V1-java":          true,
		"android.hardware.biometrics.face-V2-java":          true,
		"android.hardware.biometrics.face-V3-java":          true,
		"android.hardware.biometrics.face-V4-java":          true,
		"android.hardware.biometrics.fingerprint-V1-java":   true,
		"android.hardware.biometrics.fingerprint-V2-java":   true,
		"android.hardware.biometrics.fingerprint-V3-java":   true,
		"android.hardware.biometrics.fingerprint-V4-java":   true,
		"android.hardware.bluetooth.lmp_event-V1-java":      true,
		"android.hardware.confirmationui-V1-java":           true,
		"android.hardware.confirmationui-V2-java":           true,
		"android.hardware.gatekeeper-V1-java":               true,
		"android.hardware.gatekeeper-V2-java":               true,
		"android.hardware.gnss-V1-java":                     true,
		"android.hardware.gnss-V2-java":                     true,
		"android.hardware.gnss-V3-java":                     true,
		"android.hardware.gnss-V4-java":                     true,
		"android.hardware.graphics.common-V1-java":          true,
		"android.hardware.graphics.common-V2-java":          true,
		"android.hardware.graphics.common-V3-java":          true,
		"android.hardware.graphics.common-V4-java":          true,
		"android.hardware.graphics.common-V5-java":          true,
		"android.hardware.identity-V1-java":                 true,
		"android.hardware.identity-V2-java":                 true,
		"android.hardware.identity-V3-java":                 true,
		"android.hardware.identity-V4-java":                 true,
		"android.hardware.identity-V5-java":                 true,
		"android.hardware.identity-V6-java":                 true,
		"android.hardware.keymaster-V1-java":                true,
		"android.hardware.keymaster-V2-java":                true,
		"android.hardware.keymaster-V3-java":                true,
		"android.hardware.keymaster-V4-java":                true,
		"android.hardware.keymaster-V5-java":                true,
		"android.hardware.oemlock-V1-java":                  true,
		"android.hardware.oemlock-V2-java":                  true,
		"android.hardware.power.stats-V1-java":              true,
		"android.hardware.power.stats-V2-java":              true,
		"android.hardware.power.stats-V3-java":              true,
		"android.hardware.power-V1-java":                    true,
		"android.hardware.power-V2-java":                    true,
		"android.hardware.power-V3-java":                    true,
		"android.hardware.power-V4-java":                    true,
		"android.hardware.power-V5-java":                    true,
		"android.hardware.rebootescrow-V1-java":             true,
		"android.hardware.rebootescrow-V2-java":             true,
		"android.hardware.security.authgraph-V1-java":       true,
		"android.hardware.security.keymint-V1-java":         true,
		"android.hardware.security.keymint-V2-java":         true,
		"android.hardware.security.keymint-V3-java":         true,
		"android.hardware.security.keymint-V4-java":         true,
		"android.hardware.security.secretkeeper-V1-java":    true,
		"android.hardware.security.secureclock-V1-java":     true,
		"android.hardware.security.secureclock-V2-java":     true,
		"android.hardware.thermal-V1-java":                  true,
		"android.hardware.thermal-V2-java":                  true,
		"android.hardware.threadnetwork-V1-java":            true,
		"android.hardware.weaver-V1-java":                   true,
		"android.hardware.weaver-V2-java":                   true,
		"android.hardware.weaver-V3-java":                   true,
		"android.security.attestationmanager-java":          true,
		"android.security.authorization-java":               true,
		"android.security.compat-java":                      true,
		"android.security.legacykeystore-java":              true,
		"android.security.maintenance-java":                 true,
		"android.security.metrics-java":                     true,
		"android.system.keystore2-V1-java":                  true,
		"android.system.keystore2-V2-java":                  true,
		"android.system.keystore2-V3-java":                  true,
		"android.system.keystore2-V4-java":                  true,
		"binderReadParcelIface-java":                        true,
		"binderRecordReplayTestIface-java":                  true,
		"car-experimental-api-static-lib":                   true,
		"collector-device-lib-platform":                     true,
		"com.android.car.oem":                               true,
		"com.google.hardware.pixel.display-V10-java":        true,
		"com.google.hardware.pixel.display-V1-java":         true,
		"com.google.hardware.pixel.display-V2-java":         true,
		"com.google.hardware.pixel.display-V3-java":         true,
		"com.google.hardware.pixel.display-V4-java":         true,
		"com.google.hardware.pixel.display-V5-java":         true,
		"com.google.hardware.pixel.display-V6-java":         true,
		"com.google.hardware.pixel.display-V7-java":         true,
		"com.google.hardware.pixel.display-V8-java":         true,
		"com.google.hardware.pixel.display-V9-java":         true,
		"conscrypt-support":                                 true,
		"cts-keystore-test-util":                            true,
		"cts-keystore-user-auth-helper-library":             true,
		"ctsmediautil":                                      true,
		"CtsNetTestsNonUpdatableLib":                        true,
		"DpmWrapper":                                        true,
		"flickerlib-apphelpers":                             true,
		"flickerlib-helpers":                                true,
		"flickerlib-parsers":                                true,
		"flickerlib":                                        true,
		"hardware.google.bluetooth.ccc-V1-java":             true,
		"hardware.google.bluetooth.sar-V1-java":             true,
		"monet":                                             true,
		"pixel-power-ext-V1-java":                           true,
		"pixel-power-ext-V2-java":                           true,
		"pixel_stateresidency_provider_aidl_interface-java": true,
		"pixel-thermal-ext-V1-java":                         true,
		"protolog-lib":                                      true,
		"RkpRegistrationCheck":                              true,
		"rotary-service-javastream-protos":                  true,
		"service_based_camera_extensions":                   true,
		"statsd-helper-test":                                true,
		"statsd-helper":                                     true,
		"test-piece-2-V1-java":                              true,
		"test-piece-2-V2-java":                              true,
		"test-piece-3-V1-java":                              true,
		"test-piece-3-V2-java":                              true,
		"test-piece-3-V3-java":                              true,
		"test-piece-4-V1-java":                              true,
		"test-piece-4-V2-java":                              true,
		"test-root-package-V1-java":                         true,
		"test-root-package-V2-java":                         true,
		"test-root-package-V3-java":                         true,
		"test-root-package-V4-java":                         true,
		"testServiceIface-java":                             true,
		"wm-flicker-common-app-helpers":                     true,
		"wm-flicker-common-assertions":                      true,
		"wm-shell-flicker-utils":                            true,
		"wycheproof-keystore":                               true,
	}

	// Union of aosp and internal allowlists
	PlatformApiAllowlist = map[string]bool{}
)

func init() {
	for k, v := range aospPlatformApiAllowlist {
		PlatformApiAllowlist[k] = v
	}
}

func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if disableSourceApexVariant(ctx) {
		// Prebuilts are active, do not create the installation rules for the source javalib.
		// Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
		// TODO (b/331665856): Implement a principled solution for this.
		j.HideFromMake()
		j.SkipInstall()
	}
	j.provideHiddenAPIPropertyInfo(ctx)

	j.sdkVersion = j.SdkVersion(ctx)
	j.minSdkVersion = j.MinSdkVersion(ctx)
	j.maxSdkVersion = j.MaxSdkVersion(ctx)

	// Check min_sdk_version of the transitive dependencies if this module is created from
	// java_sdk_library.
	if j.overridableProperties.Min_sdk_version != nil && j.SdkLibraryName() != nil {
		j.CheckDepsMinSdkVersion(ctx)
	}

	// SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
	// If the stubsLinkType has already been set to Unknown, the stubsLinkType should
	// not be overridden.
	if j.stubsLinkType != Unknown {
		if proptools.Bool(j.properties.Is_stubs_module) {
			j.stubsLinkType = Stubs
		} else {
			j.stubsLinkType = Implementation
		}
	}

	j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())

	proguardSpecInfo := j.collectProguardSpecInfo(ctx)
	android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
	exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList()
	j.extraProguardFlagsFiles = append(j.extraProguardFlagsFiles, exportedProguardFlagsFiles...)

	combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags")
	writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles)
	j.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile

	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	if !apexInfo.IsForPlatform() {
		j.hideApexVariantFromMake = true
	}

	j.checkSdkVersions(ctx)
	j.checkHeadersOnly(ctx)
	if ctx.Device() {
		libName := j.Name()
		if j.SdkLibraryName() != nil && strings.HasSuffix(libName, ".impl") {
			libName = proptools.String(j.SdkLibraryName())
		}
		j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
			ctx, libName, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
		j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
		setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
		j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
		j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
		if j.usesLibrary.shouldDisableDexpreopt {
			j.dexpreopter.disableDexpreopt()
		}
	}
	javaInfo := j.compile(ctx, nil, nil, nil, nil)

	j.setInstallRules(ctx)

	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
		TestOnly:       Bool(j.sourceProperties.Test_only),
		TopLevelTarget: j.sourceProperties.Top_level_test_target,
	})

	android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
		Prebuilt: false,
	})

	if javaInfo != nil {
		setExtraJavaInfo(ctx, j, javaInfo)
		javaInfo.ExtraOutputFiles = j.extraOutputFiles
		javaInfo.DexJarFile = j.dexJarFile
		javaInfo.InstallFile = j.installFile
		javaInfo.BootDexJarPath = j.bootDexJarPath
		javaInfo.UncompressDexState = j.uncompressDexState
		javaInfo.Active = j.active
		javaInfo.BuiltInstalled = j.builtInstalled
		javaInfo.ConfigPath = j.configPath
		javaInfo.LogtagsSrcs = j.logtagsSrcs
		javaInfo.ProguardDictionary = j.proguardDictionary
		javaInfo.ProguardUsageZip = j.proguardUsageZip
		javaInfo.LinterReports = j.reports
		javaInfo.HostdexInstallFile = j.hostdexInstallFile
		javaInfo.GeneratedSrcjars = j.properties.Generated_srcjars
		javaInfo.ProfileGuided = j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided

		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
	}

	setOutputFiles(ctx, j.Module)

	j.javaLibraryModuleInfoJSON(ctx)

	buildComplianceMetadata(ctx)

	j.createApiXmlFile(ctx)

	if j.dexer.proguardDictionary.Valid() {
		android.SetProvider(ctx, ProguardProvider, ProguardInfo{
			ModuleName:         ctx.ModuleName(),
			Class:              "JAVA_LIBRARIES",
			ProguardDictionary: j.dexer.proguardDictionary.Path(),
			ProguardUsageZip:   j.dexer.proguardUsageZip.Path(),
			ClassesJar:         j.implementationAndResourcesJar,
		})
	}
}

func (j *Library) javaLibraryModuleInfoJSON(ctx android.ModuleContext) *android.ModuleInfoJSON {
	moduleInfoJSON := ctx.ModuleInfoJSON()
	moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
	if j.implementationAndResourcesJar != nil {
		moduleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
	}
	moduleInfoJSON.SystemSharedLibs = []string{"none"}

	if j.hostDexNeeded() {
		hostDexModuleInfoJSON := ctx.ExtraModuleInfoJSON()
		hostDexModuleInfoJSON.SubName = "-hostdex"
		hostDexModuleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
		if j.implementationAndResourcesJar != nil {
			hostDexModuleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
		}
		hostDexModuleInfoJSON.SystemSharedLibs = []string{"none"}
		hostDexModuleInfoJSON.SupportedVariantsOverride = []string{"HOST"}
	}

	if j.hideApexVariantFromMake {
		moduleInfoJSON.Disabled = true
	}
	return moduleInfoJSON
}

func buildComplianceMetadata(ctx android.ModuleContext) {
	// Dump metadata that can not be done in android/compliance-metadata.go
	complianceMetadataInfo := ctx.ComplianceMetadataInfo()
	builtFiles := ctx.GetOutputFiles().DefaultOutputFiles.Strings()
	for _, paths := range ctx.GetOutputFiles().TaggedOutputFiles {
		builtFiles = append(builtFiles, paths.Strings()...)
	}
	complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.BUILT_FILES, android.SortedUniqueStrings(builtFiles))

	// Static deps
	staticDepNames := make([]string, 0)
	staticDepFiles := android.Paths{}
	ctx.VisitDirectDepsWithTag(staticLibTag, func(module android.Module) {
		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
			staticDepNames = append(staticDepNames, module.Name())
			staticDepFiles = append(staticDepFiles, dep.ImplementationJars...)
			staticDepFiles = append(staticDepFiles, dep.HeaderJars...)
			staticDepFiles = append(staticDepFiles, dep.ResourceJars...)
		}
	})
	complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.SortedUniqueStrings(staticDepNames))
	complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.SortedUniqueStrings(staticDepFiles.Strings()))
}

func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath {
	var installDir android.InstallPath
	if ctx.InstallInTestcases() {
		var archDir string
		if !ctx.Host() {
			archDir = ctx.DeviceConfig().DeviceArch()
		}
		installModuleName := ctx.ModuleName()
		// If this module is an impl library created from java_sdk_library,
		// install the files under the java_sdk_library module outdir instead of this module outdir.
		if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
			installModuleName = proptools.String(j.SdkLibraryName())
		}
		installDir = android.PathForModuleInstall(ctx, installModuleName, archDir)
	} else {
		installDir = android.PathForModuleInstall(ctx, "framework")
	}
	return installDir
}

func (j *Library) setInstallRules(ctx android.ModuleContext) {
	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)

	if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() {
		var extraInstallDeps android.InstallPaths
		if j.InstallMixin != nil {
			extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
		}
		hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host()
		if hostDexNeeded {
			j.hostdexInstallFile = ctx.InstallFileWithoutCheckbuild(
				android.PathForHostDexInstall(ctx, "framework"),
				j.Stem()+"-hostdex.jar", j.outputFile)
		}
		j.installFile = ctx.InstallFileWithoutCheckbuild(j.getJarInstallDir(ctx), j.Stem()+".jar", j.outputFile, extraInstallDeps...)
	}
}

func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.usesLibrary.deps(ctx, false)
	j.deps(ctx)

	if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
		if dexpreopt.IsDex2oatNeeded(ctx) {
			dexpreopt.RegisterToolDeps(ctx)
		}
		prebuiltSdkLibExists := ctx.OtherModuleExists(android.PrebuiltNameFromSource(proptools.String(j.SdkLibraryName())))
		if prebuiltSdkLibExists && ctx.OtherModuleExists("all_apex_contributions") {
			ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions")
		}
	}
}

var apiXMLGeneratingApiSurfaces = []android.SdkKind{
	android.SdkPublic,
	android.SdkSystem,
	android.SdkModule,
	android.SdkSystemServer,
	android.SdkTest,
}

func (j *Library) createApiXmlFile(ctx android.ModuleContext) {
	if kind, ok := android.JavaLibraryNameToSdkKind(ctx.ModuleName()); ok && android.InList(kind, apiXMLGeneratingApiSurfaces) {
		scopePrefix := AllApiScopes.matchingScopeFromSdkKind(kind).apiFilePrefix
		j.apiXmlFile = android.PathForModuleOut(ctx, fmt.Sprintf("%sapi.xml", scopePrefix))
		ctx.Build(pctx, android.BuildParams{
			Rule: generateApiXMLRule,
			// LOCAL_SOONG_CLASSES_JAR
			Input:  j.implementationAndResourcesJar,
			Output: j.apiXmlFile,
		})
		ctx.DistForGoal("dist_files", j.apiXmlFile)
	}
}

const (
	aidlIncludeDir   = "aidl"
	javaDir          = "java"
	jarFileSuffix    = ".jar"
	testConfigSuffix = "-AndroidTest.xml"
)

// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string {
	return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
}

func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string {
	return filepath.Join(javaDir, osPrefix, name+suffix)
}

type librarySdkMemberType struct {
	android.SdkMemberTypeBase

	// Function to retrieve the appropriate output jar (implementation or header) from
	// the library.
	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path

	// Function to compute the snapshot relative path to which the named library's
	// jar should be copied.
	snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string

	// True if only the jar should be copied to the snapshot, false if the jar plus any additional
	// files like aidl files should also be copied.
	onlyCopyJarToSnapshot bool
}

const (
	onlyCopyJarToSnapshot    = true
	copyEverythingToSnapshot = false
)

func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
	ctx.AddVariationDependencies(nil, dependencyTag, names...)
}

func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
	_, ok := module.(*Library)
	return ok
}

func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import")
}

func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
	return &librarySdkMemberProperties{}
}

type librarySdkMemberProperties struct {
	android.SdkMemberPropertiesBase

	JarToExport     android.Path `android:"arch_variant"`
	AidlIncludeDirs android.Paths

	// The list of permitted packages that need to be passed to the prebuilts as they are used to
	// create the updatable-bcp-packages.txt file.
	PermittedPackages []string

	// The value of the min_sdk_version property, translated into a number where possible.
	MinSdkVersion *string `supported_build_releases:"Tiramisu+"`

	DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
}

func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
	j := variant.(*Library)

	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)

	p.AidlIncludeDirs = j.AidlIncludeDirs()

	p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()

	// If the min_sdk_version was set then add the canonical representation of the API level to the
	// snapshot.
	if j.overridableProperties.Min_sdk_version != nil {
		canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
		if err != nil {
			ctx.ModuleErrorf("%s", err)
		}
		p.MinSdkVersion = proptools.StringPtr(canonical)
	}

	if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
		p.DexPreoptProfileGuided = proptools.BoolPtr(true)
	}
}

func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
	builder := ctx.SnapshotBuilder()

	memberType := ctx.MemberType().(*librarySdkMemberType)

	exportedJar := p.JarToExport
	if exportedJar != nil {
		// Delegate the creation of the snapshot relative path to the member type.
		snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name())

		// Copy the exported jar to the snapshot.
		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)

		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
	}

	if p.MinSdkVersion != nil {
		propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion)
	}

	if len(p.PermittedPackages) > 0 {
		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
	}

	dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
	if p.DexPreoptProfileGuided != nil {
		dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided))
	}

	// Do not copy anything else to the snapshot.
	if memberType.onlyCopyJarToSnapshot {
		return
	}

	aidlIncludeDirs := p.AidlIncludeDirs
	if len(aidlIncludeDirs) != 0 {
		sdkModuleContext := ctx.SdkModuleContext()
		for _, dir := range aidlIncludeDirs {
			// TODO(jiyong): copy parcelable declarations only
			aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
			for _, file := range aidlFiles {
				builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file))
			}
		}

		// TODO(b/151933053) - add aidl include dirs property
	}
}

// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
//
// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the device bootclasspath.  This jar is not suitable for installing on a device, but can be used
// as a `static_libs` dependency of another module.
//
// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
// a device.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
func LibraryFactory() android.Module {
	module := &Library{}

	module.addHostAndDeviceProperties()
	module.AddProperties(&module.sourceProperties)

	module.initModuleAndImport(module)

	android.InitApexModule(module)
	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

// java_library_static is an obsolete alias for java_library.
func LibraryStaticFactory() android.Module {
	return LibraryFactory()
}

// java_library_host builds and links sources into a `.jar` file for the host.
//
// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
func LibraryHostFactory() android.Module {
	module := &Library{}

	module.addHostProperties()

	module.Module.properties.Installable = proptools.BoolPtr(true)

	android.InitApexModule(module)
	InitJavaModule(module, android.HostSupported)
	return module
}

//
// Java Tests
//

// Test option struct.
type TestOptions struct {
	android.CommonTestOptions

	// a list of extra test configuration files that should be installed with the module.
	Extra_test_configs []string `android:"path,arch_variant"`

	// Extra <option> tags to add to the auto generated test xml file. The "key"
	// is optional in each of these.
	Tradefed_options []tradefed.Option

	// Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest.
	// The "key" is optional in each of these.
	Test_runner_options []tradefed.Option
}

type testProperties struct {
	// list of compatibility suites (for example "cts", "vts") that the module should be
	// installed into.
	Test_suites []string `android:"arch_variant"`

	// the name of the test configuration (for example "AndroidTest.xml") that should be
	// installed with the module.
	Test_config *string `android:"path,arch_variant"`

	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
	// should be installed with the module.
	Test_config_template *string `android:"path,arch_variant"`

	// list of files or filegroup modules that provide data that should be installed alongside
	// the test
	Data []string `android:"path"`

	// Same as data, but will add dependencies on modules using the device's os variation and
	// the common arch variation. Useful for a host test that wants to embed a module built for
	// device.
	Device_common_data []string `android:"path_device_common"`

	// same as data, but adds dependencies using the device's os variation and the device's first
	// architecture's variation. Can be used to add a module built for device to the data of a
	// host test.
	Device_first_data []string `android:"path_device_first"`

	// same as data, but adds dependencies using the device's os variation and the device's first
	// 32-bit architecture's variation. If a 32-bit arch doesn't exist for this device, it will use
	// a 64 bit arch instead. Can be used to add a module built for device to the data of a
	// host test.
	Device_first_prefer32_data []string `android:"path_device_first_prefer32"`

	// Same as data, but will add dependencies on modules using the host's os variation and
	// the common arch variation. Useful for a device test that wants to depend on a host
	// module, for example to include a custom Tradefed test runner.
	Host_common_data []string `android:"path_host_common"`

	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
	// explicitly.
	Auto_gen_config *bool

	// Add parameterized mainline modules to auto generated test config. The options will be
	// handled by TradeFed to do downloading and installing the specified modules on the device.
	Test_mainline_modules []string

	// Test options.
	Test_options TestOptions

	// Names of modules containing JNI libraries that should be installed alongside the test.
	Jni_libs proptools.Configurable[[]string]

	// Install the test into a folder named for the module in all test suites.
	Per_testcase_directory *bool
}

type hostTestProperties struct {
	// list of native binary modules that should be installed alongside the test
	Data_native_bins []string `android:"arch_variant"`

	// list of device binary modules that should be installed alongside the test
	// This property only adds the first variant of the dependency
	Data_device_bins_first []string `android:"arch_variant"`

	// list of device binary modules that should be installed alongside the test
	// This property adds 64bit AND 32bit variants of the dependency
	Data_device_bins_both []string `android:"arch_variant"`

	// list of device binary modules that should be installed alongside the test
	// This property only adds 64bit variants of the dependency
	Data_device_bins_64 []string `android:"arch_variant"`

	// list of device binary modules that should be installed alongside the test
	// This property adds 32bit variants of the dependency if available, or else
	// defaults to the 64bit variant
	Data_device_bins_prefer32 []string `android:"arch_variant"`

	// list of device binary modules that should be installed alongside the test
	// This property only adds 32bit variants of the dependency
	Data_device_bins_32 []string `android:"arch_variant"`
}

type testHelperLibraryProperties struct {
	// list of compatibility suites (for example "cts", "vts") that the module should be
	// installed into.
	Test_suites []string `android:"arch_variant"`

	// Install the test into a folder named for the module in all test suites.
	Per_testcase_directory *bool
}

type prebuiltTestProperties struct {
	// list of compatibility suites (for example "cts", "vts") that the module should be
	// installed into.
	Test_suites []string `android:"arch_variant"`

	// the name of the test configuration (for example "AndroidTest.xml") that should be
	// installed with the module.
	Test_config *string `android:"path,arch_variant"`
}

type Test struct {
	Library

	testProperties testProperties

	testConfig       android.Path
	extraTestConfigs android.Paths
	data             android.Paths
}

type TestHost struct {
	Test

	testHostProperties hostTestProperties
}

type TestHelperLibrary struct {
	Library

	testHelperLibraryProperties testHelperLibraryProperties
}

type JavaTestImport struct {
	Import

	prebuiltTestProperties prebuiltTestProperties

	testConfig android.Path
	dexJarFile android.Path
}

func (j *Test) InstallInTestcases() bool {
	// Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into
	// testcases by base_rules.mk.
	return !j.Host()
}

func (j *TestHelperLibrary) InstallInTestcases() bool {
	return true
}

func (j *JavaTestImport) InstallInTestcases() bool {
	return true
}

func (j *TestHost) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
	return ctx.DeviceConfig().NativeCoverageEnabled()
}

func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) {
	if len(j.testHostProperties.Data_device_bins_first) > 0 {
		deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...)
	}

	var maybeAndroid32Target *android.Target
	var maybeAndroid64Target *android.Target
	android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32")
	android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64")
	if len(android32TargetList) > 0 {
		maybeAndroid32Target = &android32TargetList[0]
	}
	if len(android64TargetList) > 0 {
		maybeAndroid64Target = &android64TargetList[0]
	}

	if len(j.testHostProperties.Data_device_bins_both) > 0 {
		if maybeAndroid32Target == nil && maybeAndroid64Target == nil {
			ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets)
			return
		}
		if maybeAndroid32Target != nil {
			ctx.AddFarVariationDependencies(
				maybeAndroid32Target.Variations(),
				dataDeviceBinsTag,
				j.testHostProperties.Data_device_bins_both...,
			)
		}
		if maybeAndroid64Target != nil {
			ctx.AddFarVariationDependencies(
				maybeAndroid64Target.Variations(),
				dataDeviceBinsTag,
				j.testHostProperties.Data_device_bins_both...,
			)
		}
	}

	if len(j.testHostProperties.Data_device_bins_prefer32) > 0 {
		if maybeAndroid32Target != nil {
			ctx.AddFarVariationDependencies(
				maybeAndroid32Target.Variations(),
				dataDeviceBinsTag,
				j.testHostProperties.Data_device_bins_prefer32...,
			)
		} else {
			if maybeAndroid64Target == nil {
				ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets)
				return
			}
			ctx.AddFarVariationDependencies(
				maybeAndroid64Target.Variations(),
				dataDeviceBinsTag,
				j.testHostProperties.Data_device_bins_prefer32...,
			)
		}
	}

	if len(j.testHostProperties.Data_device_bins_32) > 0 {
		if maybeAndroid32Target == nil {
			ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets)
			return
		}
		deviceVariations := maybeAndroid32Target.Variations()
		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...)
	}

	if len(j.testHostProperties.Data_device_bins_64) > 0 {
		if maybeAndroid64Target == nil {
			ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets)
			return
		}
		deviceVariations := maybeAndroid64Target.Variations()
		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...)
	}
}

func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
	if len(j.testHostProperties.Data_native_bins) > 0 {
		for _, target := range ctx.MultiTargets() {
			ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
		}
	}

	jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
	if len(jniLibs) > 0 {
		for _, target := range ctx.MultiTargets() {
			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
		}
	}

	j.addDataDeviceBinsDeps(ctx)
	j.deps(ctx)
}

func (j *TestHost) AddExtraResource(p android.Path) {
	j.extraResources = append(j.extraResources, p)
}

func (j *TestHost) dataDeviceBins() []string {
	ret := make([]string, 0,
		len(j.testHostProperties.Data_device_bins_first)+
			len(j.testHostProperties.Data_device_bins_both)+
			len(j.testHostProperties.Data_device_bins_prefer32)+
			len(j.testHostProperties.Data_device_bins_32)+
			len(j.testHostProperties.Data_device_bins_64),
	)

	ret = append(ret, j.testHostProperties.Data_device_bins_first...)
	ret = append(ret, j.testHostProperties.Data_device_bins_both...)
	ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...)
	ret = append(ret, j.testHostProperties.Data_device_bins_32...)
	ret = append(ret, j.testHostProperties.Data_device_bins_64...)

	return ret
}

func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	var configs []tradefed.Config
	dataDeviceBins := j.dataDeviceBins()
	if len(dataDeviceBins) > 0 {
		// add Tradefed configuration to push device bins to device for testing
		remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name())
		options := []tradefed.Option{{Name: "cleanup", Value: "true"}}
		for _, bin := range dataDeviceBins {
			fullPath := filepath.Join(remoteDir, bin)
			options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath})
		}
		configs = append(configs, tradefed.Object{
			Type:    "target_preparer",
			Class:   "com.android.tradefed.targetprep.PushFilePreparer",
			Options: options,
		})
	}

	j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
	android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
		TestcaseRelDataFiles: testcaseRel(j.data),
		OutputFile:           j.outputFile,
		TestConfig:           j.testConfig,
		RequiredModuleNames:  j.RequiredModuleNames(ctx),
		TestSuites:           j.testProperties.Test_suites,
		IsHost:               true,
		LocalSdkVersion:      j.sdkVersion.String(),
		IsUnitTest:           Bool(j.testProperties.Test_options.Unit_test),
		MkInclude:            "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
		MkAppClass:           "JAVA_LIBRARIES",
	})

	moduleInfoJSON := ctx.ModuleInfoJSON()
	if proptools.Bool(j.testProperties.Test_options.Unit_test) {
		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
	}
}

func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx))
	j.generateAndroidBuildActionsWithConfig(ctx, nil)
}

func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) {
	if j.testProperties.Test_options.Unit_test == nil && ctx.Host() {
		// TODO(b/): Clean temporary heuristic to avoid unexpected onboarding.
		defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites)
		j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
	}
	j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
		TestConfigProp:          j.testProperties.Test_config,
		TestConfigTemplateProp:  j.testProperties.Test_config_template,
		TestSuites:              j.testProperties.Test_suites,
		Config:                  configs,
		OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options,
		TestRunnerOptions:       j.testProperties.Test_options.Test_runner_options,
		AutoGenConfig:           j.testProperties.Auto_gen_config,
		UnitTest:                j.testProperties.Test_options.Unit_test,
		DeviceTemplate:          "${JavaTestConfigTemplate}",
		HostTemplate:            "${JavaHostTestConfigTemplate}",
		HostUnitTestTemplate:    "${JavaHostUnitTestConfigTemplate}",
	})

	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_prefer32_data)...)
	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Host_common_data)...)

	j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)

	ctx.VisitDirectDepsProxyWithTag(dataNativeBinsTag, func(dep android.ModuleProxy) {
		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
	})

	ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
	})

	var directImplementationDeps android.Paths
	var transitiveImplementationDeps []depset.DepSet[android.Path]
	ctx.VisitDirectDepsProxyWithTag(jniLibTag, func(dep android.ModuleProxy) {
		sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider)
		if sharedLibInfo.SharedLibrary != nil {
			// Copy to an intermediate output directory to append "lib[64]" to the path,
			// so that it's compatible with the default rpath values.
			var relPath string
			if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
				relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
			} else {
				relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
			}
			relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  sharedLibInfo.SharedLibrary,
				Output: relocatedLib,
			})
			j.data = append(j.data, relocatedLib)

			directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
			if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
				transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
			}
		} else {
			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
		}
	})

	android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
		ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
	})

	j.Library.GenerateAndroidBuildActions(ctx)

	moduleInfoJSON := ctx.ModuleInfoJSON()
	// LOCAL_MODULE_TAGS
	moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
	var allTestConfigs android.Paths
	if j.testConfig != nil {
		allTestConfigs = append(allTestConfigs, j.testConfig)
	}
	allTestConfigs = append(allTestConfigs, j.extraTestConfigs...)
	if len(allTestConfigs) > 0 {
		moduleInfoJSON.TestConfig = allTestConfigs.Strings()
	} else {
		optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
		if optionalConfig.Valid() {
			moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
		}
	}
	if len(j.testProperties.Test_suites) > 0 {
		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testProperties.Test_suites...)
	} else {
		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
	}
	if _, ok := j.testConfig.(android.WritablePath); ok {
		moduleInfoJSON.AutoTestConfig = []string{"true"}
	}
	if proptools.Bool(j.testProperties.Test_options.Unit_test) {
		moduleInfoJSON.IsUnitTest = "true"
		if ctx.Host() {
			moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
		}
	}
	moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...)

	// Install test deps
	if !ctx.Config().KatiEnabled() {
		pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName())
		if j.testConfig != nil {
			ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig)
		}
		dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
		if dynamicConfig.Valid() {
			ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
		}
		testDeps := append(j.data, j.extraTestConfigs...)
		for _, data := range android.SortedUniquePaths(testDeps) {
			dataPath := android.DataPath{SrcPath: data}
			ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
		}
		if j.outputFile != nil {
			ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
		}
	}

	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
		TestSuites: j.testProperties.Test_suites,
	})
}

func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.Library.GenerateAndroidBuildActions(ctx)

	moduleInfoJSON := ctx.ModuleInfoJSON()
	moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
	if len(j.testHelperLibraryProperties.Test_suites) > 0 {
		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testHelperLibraryProperties.Test_suites...)
	} else {
		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
	}
	optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
	if optionalConfig.Valid() {
		moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
	}

	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
		TestSuites: j.testHelperLibraryProperties.Test_suites,
	})
}

func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
		TestConfigProp:       j.prebuiltTestProperties.Test_config,
		TestSuites:           j.prebuiltTestProperties.Test_suites,
		DeviceTemplate:       "${JavaTestConfigTemplate}",
		HostTemplate:         "${JavaHostTestConfigTemplate}",
		HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}",
	})

	j.Import.GenerateAndroidBuildActions(ctx)
}

type testSdkMemberType struct {
	android.SdkMemberTypeBase
}

func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
	ctx.AddVariationDependencies(nil, dependencyTag, names...)
}

func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
	_, ok := module.(*Test)
	return ok
}

func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import")
}

func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
	return &testSdkMemberProperties{}
}

type testSdkMemberProperties struct {
	android.SdkMemberPropertiesBase

	JarToExport android.Path
	TestConfig  android.Path
}

func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
	test := variant.(*Test)

	implementationJars := test.ImplementationJars()
	if len(implementationJars) != 1 {
		panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
	}

	p.JarToExport = implementationJars[0]
	p.TestConfig = test.testConfig
}

func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
	builder := ctx.SnapshotBuilder()

	exportedJar := p.JarToExport
	if exportedJar != nil {
		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name())
		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)

		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
	}

	testConfig := p.TestConfig
	if testConfig != nil {
		snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix)
		builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath)
		propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath)
	}
}

// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
//
// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
// compiled against the device bootclasspath.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
func TestFactory() android.Module {
	module := &Test{}

	module.addHostAndDeviceProperties()
	module.AddProperties(&module.testProperties)

	module.Module.properties.Installable = proptools.BoolPtr(true)
	module.Module.dexpreopter.isTest = true
	module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
	module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
	module.Module.sourceProperties.Top_level_test_target = true

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
func TestHelperLibraryFactory() android.Module {
	module := &TestHelperLibrary{}

	module.addHostAndDeviceProperties()
	module.AddProperties(&module.testHelperLibraryProperties)

	module.Module.properties.Installable = proptools.BoolPtr(true)
	module.Module.dexpreopter.isTest = true
	module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
	module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
// and makes sure that it is added to the appropriate test suite.
//
// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against an Android classpath.
//
// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
// for host modules.
func JavaTestImportFactory() android.Module {
	module := &JavaTestImport{}

	module.AddProperties(
		&module.Import.properties,
		&module.prebuiltTestProperties)

	module.Import.properties.Installable = proptools.BoolPtr(true)

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitApexModule(module)
	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
// allow running the test with `atest` or a `TEST_MAPPING` file.
//
// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
func TestHostFactory() android.Module {
	module := &TestHost{}

	module.addHostProperties()
	module.AddProperties(&module.testProperties)
	module.AddProperties(&module.testHostProperties)

	InitTestHost(
		module,
		proptools.BoolPtr(true),
		nil,
		nil)

	InitJavaModuleMultiTargets(module, android.HostSupported)

	return module
}

func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) {
	th.properties.Installable = installable
	th.testProperties.Auto_gen_config = autoGenConfig
	th.testProperties.Test_suites = testSuites
	th.sourceProperties.Test_only = proptools.BoolPtr(true)
	th.sourceProperties.Top_level_test_target = true
}

//
// Java Binaries (.jar file plus wrapper script)
//

type binaryProperties struct {
	// installable script to execute the resulting jar
	Wrapper *string `android:"path,arch_variant"`

	// Name of the class containing main to be inserted into the manifest as Main-Class.
	Main_class *string

	// Names of modules containing JNI libraries that should be installed alongside the binary.
	Jni_libs []string `android:"arch_variant"`
}

type Binary struct {
	Library

	binaryProperties binaryProperties

	wrapperFile android.Path
	binaryFile  android.InstallPath

	androidMkNamesOfJniLibs []string
}

func (j *Binary) HostToolPath() android.OptionalPath {
	return android.OptionalPathForPath(j.binaryFile)
}

func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())

	// Handle the binary wrapper. This comes before compiling the jar so that the wrapper
	// is the first PackagingSpec
	if j.binaryProperties.Wrapper != nil {
		j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
	} else {
		if ctx.Windows() {
			ctx.PropertyErrorf("wrapper", "wrapper is required for Windows")
		}

		if ctx.Device() {
			// device binary should have a main_class property if it does not
			// have a specific wrapper, so that a default wrapper can
			// be generated for it.
			if j.binaryProperties.Main_class == nil {
				ctx.PropertyErrorf("main_class", "main_class property "+
					"is required for device binary if no default wrapper is assigned")
			} else {
				wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh")
				jarName := j.Stem() + ".jar"
				partition := j.PartitionTag(ctx.DeviceConfig())
				ctx.Build(pctx, android.BuildParams{
					Rule:   deviceBinaryWrapper,
					Output: wrapper,
					Args: map[string]string{
						"jar_name":   jarName,
						"partition":  partition,
						"main_class": String(j.binaryProperties.Main_class),
					},
				})
				j.wrapperFile = wrapper
			}
		} else {
			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
		}
	}

	ext := ""
	if ctx.Windows() {
		ext = ".bat"
	}

	// The host installation rules make the installed wrapper depend on all the dependencies
	// of the wrapper variant, which will include the common variant's jar file and any JNI
	// libraries.  This is verified by TestBinary. Also make it depend on the jar file so that
	// the binary file timestamp will update when the jar file timestamp does. The jar file is
	// built later on, in j.Library.GenerateAndroidBuildActions, so we have to create an identical
	// installpath representing it here.
	j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
		ctx.ModuleName()+ext, j.wrapperFile, j.getJarInstallDir(ctx).Join(ctx, j.Stem()+".jar"))

	// Set the jniLibs of this binary.
	// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
	// install these alongside the java binary.
	ctx.VisitDirectDepsProxyWithTag(jniInstallTag, func(jni android.ModuleProxy) {
		// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
		commonInfo := android.OtherModulePointerProviderOrDefault(ctx, jni, android.CommonModuleInfoProvider)
		j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, commonInfo.BaseModuleName+":"+commonInfo.Target.Arch.ArchType.Bitness())
	})
	// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
	ctx.VisitDirectDepsProxyWithTag(android.RequiredDepTag, func(dep android.ModuleProxy) {
		if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
			ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
		}
	})

	// Compile the jar
	if j.binaryProperties.Main_class != nil {
		if j.properties.Manifest != nil {
			ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
		}
		manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
		GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
		j.overrideManifest = android.OptionalPathForPath(manifestFile)
	}

	j.Library.GenerateAndroidBuildActions(ctx)
}

func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.deps(ctx)
	// These dependencies ensure the installation rules will install the jar file when the
	// wrapper is installed, and the jni libraries when the wrapper is installed.
	if ctx.Os().Class == android.Host {
		ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
	} else if ctx.Os().Class == android.Device {
		ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
	} else {
		ctx.ModuleErrorf("Unknown os class")
	}
}

// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
// as well.
//
// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
// compiled against the device bootclasspath.
//
// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
// compiled against the host bootclasspath.
func BinaryFactory() android.Module {
	module := &Binary{}

	module.addHostAndDeviceProperties()
	module.AddProperties(&module.binaryProperties, &module.sourceProperties)

	module.Module.properties.Installable = proptools.BoolPtr(true)

	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
	android.InitDefaultableModule(module)

	return module
}

// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
//
// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
func BinaryHostFactory() android.Module {
	module := &Binary{}

	module.addHostProperties()
	module.AddProperties(&module.binaryProperties)

	module.Module.properties.Installable = proptools.BoolPtr(true)

	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
	android.InitDefaultableModule(module)
	return module
}

type JavaApiContribution struct {
	android.ModuleBase
	android.DefaultableModuleBase
	embeddableInModuleAndImport

	properties struct {
		// name of the API surface
		Api_surface *string

		// relative path to the API signature text file
		Api_file *string `android:"path"`
	}
}

func ApiContributionFactory() android.Module {
	module := &JavaApiContribution{}
	android.InitAndroidModule(module)
	android.InitDefaultableModule(module)
	module.AddProperties(&module.properties)
	module.initModuleAndImport(module)
	return module
}

type JavaApiImportInfo struct {
	ApiFile    android.Path
	ApiSurface string
}

var JavaApiImportProvider = blueprint.NewProvider[JavaApiImportInfo]()

func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	var apiFile android.Path = nil
	if apiFileString := ap.properties.Api_file; apiFileString != nil {
		apiFile = android.PathForModuleSrc(ctx, String(apiFileString))
	}

	android.SetProvider(ctx, JavaApiImportProvider, JavaApiImportInfo{
		ApiFile:    apiFile,
		ApiSurface: proptools.String(ap.properties.Api_surface),
	})
}

type ApiLibrary struct {
	android.ModuleBase
	android.DefaultableModuleBase

	hiddenAPI
	dexer
	embeddableInModuleAndImport

	properties JavaApiLibraryProperties

	stubsSrcJar               android.WritablePath
	stubsJar                  android.WritablePath
	stubsJarWithoutStaticLibs android.WritablePath
	extractedSrcJar           android.WritablePath
	// .dex of stubs, used for hiddenapi processing
	dexJarFile OptionalDexJarPath

	validationPaths android.Paths

	stubsType StubsType

	aconfigProtoFiles android.Paths
}

type JavaApiLibraryProperties struct {
	// name of the API surface
	Api_surface *string

	// list of Java API contribution modules that consists this API surface
	// This is a list of Soong modules
	Api_contributions []string

	// List of flags to be passed to the javac compiler to generate jar file
	Javacflags []string

	// List of shared java libs that this module has dependencies to and
	// should be passed as classpath in javac invocation
	Libs proptools.Configurable[[]string]

	// List of java libs that this module has static dependencies to and will be
	// merge zipped after metalava invocation
	Static_libs proptools.Configurable[[]string]

	// Version of previously released API file for compatibility check.
	Previous_api *string `android:"path"`

	// java_system_modules module providing the jar to be added to the
	// bootclasspath when compiling the stubs.
	// The jar will also be passed to metalava as a classpath to
	// generate compilable stubs.
	System_modules *string

	// If true, the module runs validation on the API signature files provided
	// by the modules passed via api_contributions by checking if the files are
	// in sync with the source Java files. However, the environment variable
	// DISABLE_STUB_VALIDATION has precedence over this property.
	Enable_validation *bool

	// Type of stubs the module should generate. Must be one of "everything", "runtime" or
	// "exportable". Defaults to "everything".
	// - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state
	// of the flag.
	// - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or
	// READ_WRITE, and all other flagged apis are stripped.
	// - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and
	// READ_ONLY, and all other flagged apis are stripped.
	Stubs_type *string

	// List of aconfig_declarations module names that the stubs generated in this module
	// depend on.
	Aconfig_declarations []string

	// List of hard coded filegroups containing Metalava config files that are passed to every
	// Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd.
	ConfigFiles []string `android:"path" blueprint:"mutated"`

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

func ApiLibraryFactory() android.Module {
	module := &ApiLibrary{}
	module.AddProperties(&module.properties)
	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
	module.initModuleAndImport(module)
	android.InitDefaultableModule(module)
	return module
}

func (al *ApiLibrary) ApiSurface() *string {
	return al.properties.Api_surface
}

func (al *ApiLibrary) StubsJar() android.Path {
	return al.stubsJar
}

func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
	srcs android.Paths, homeDir android.WritablePath,
	classpath android.Paths, configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
	rule.Command().Text("rm -rf").Flag(homeDir.String())
	rule.Command().Text("mkdir -p").Flag(homeDir.String())

	cmd := rule.Command()
	cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())

	if metalavaUseRbe(ctx) {
		rule.Remoteable(android.RemoteRuleSupports{RBE: true})
		execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
		labels := map[string]string{"type": "tool", "name": "metalava"}

		pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
		rule.Rewrapper(&remoteexec.REParams{
			Labels:          labels,
			ExecStrategy:    execStrategy,
			ToolchainInputs: []string{config.JavaCmd(ctx).String()},
			Platform:        map[string]string{remoteexec.PoolKey: pool},
		})
	}

	cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
		Flag(config.JavacVmFlags).
		Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
		FlagWithInputList("--source-files ", srcs, " ")

	cmd.Flag("--color").
		Flag("--quiet").
		Flag("--include-annotations").
		// The flag makes nullability issues as warnings rather than errors by replacing
		// @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull,
		// and these packages are meant to have everything annotated
		// @RecentlyNullable/@RecentlyNonNull.
		FlagWithArg("--force-convert-to-warning-nullability-annotations ", "+*:-android.*:+android.icu.*:-dalvik.*").
		FlagWithArg("--repeat-errors-max ", "10").
		FlagWithArg("--hide ", "UnresolvedImport").
		FlagWithArg("--hide ", "InvalidNullabilityOverride").
		FlagWithArg("--hide ", "ChangedDefault")

	addMetalavaConfigFilesToCmd(cmd, configFiles)

	addOptionalApiSurfaceToCmd(cmd, apiSurface)

	if len(classpath) == 0 {
		// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
		// classes on the classpath when an API file contains missing classes. However, as this command
		// does not specify `--classpath` this is not needed for that. However, this is also used as a
		// signal to the special metalava code for generating stubs from text files that it needs to add
		// some additional items into the API (e.g. default constructors).
		cmd.FlagWithArg("--api-class-resolution ", "api")
	} else {
		cmd.FlagWithArg("--api-class-resolution ", "api:classpath")
		cmd.FlagWithInputList("--classpath ", classpath, ":")
	}

	return cmd
}

func (al *ApiLibrary) HeaderJars() android.Paths {
	return android.Paths{al.stubsJar}
}

func (al *ApiLibrary) OutputDirAndDeps() (android.Path, android.Paths) {
	return nil, nil
}

func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
	if stubsDir.Valid() {
		cmd.FlagWithArg("--stubs ", stubsDir.String())
	}
}

func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, validationPaths android.Paths) {
	for _, validationPath := range validationPaths {
		cmd.Validation(validationPath)
	}
}

func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
	apiContributions := al.properties.Api_contributions
	addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") &&
		!ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") &&
		!ctx.Config().PartialCompileFlags().Disable_stub_validation &&
		proptools.BoolDefault(al.properties.Enable_validation, true)
	for _, apiContributionName := range apiContributions {
		ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)

		// Add the java_api_contribution module generating droidstubs module
		// as dependency when validation adding conditions are met and
		// the java_api_contribution module name has ".api.contribution" suffix.
		// All droidstubs-generated modules possess the suffix in the name,
		// but there is no such guarantee for tests.
		if addValidations {
			if strings.HasSuffix(apiContributionName, ".api.contribution") {
				ctx.AddDependency(ctx.Module(), metalavaCurrentApiTimestampTag, strings.TrimSuffix(apiContributionName, ".api.contribution"))
			} else {
				ctx.ModuleErrorf("Validation is enabled for module %s but a "+
					"current timestamp provider is not found for the api "+
					"contribution %s",
					ctx.ModuleName(),
					apiContributionName,
				)
			}
		}
	}
	if ctx.Device() {
		sdkDep := decodeSdkDep(ctx, android.SdkContext(al))
		if sdkDep.useModule {
			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
			ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
			ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)

		}
	}
	ctx.AddVariationDependencies(nil, libTag, al.properties.Libs.GetOrDefault(ctx, nil)...)
	ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs.GetOrDefault(ctx, nil)...)

	for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations {
		ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName)
	}
}

// Map where key is the api scope name and value is the int value
// representing the order of the api scope, narrowest to the widest
var scopeOrderMap = AllApiScopes.MapToIndex(
	func(s *apiScope) string { return s.name })

// Add some extra entries into scopeOrderMap for some special api surface names needed by libcore,
// external/conscrypt and external/icu and java/core-libraries.
func init() {
	count := len(scopeOrderMap)
	scopeOrderMap["core"] = count + 1
	scopeOrderMap["core-platform"] = count + 2
	scopeOrderMap["intra-core"] = count + 3
	scopeOrderMap["core-platform-plus-public"] = count + 4
	scopeOrderMap["core-platform-legacy"] = count + 5
}

func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
	for _, srcFileInfo := range srcFilesInfo {
		if srcFileInfo.ApiSurface == "" {
			ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile)
		}
	}
	sort.Slice(srcFilesInfo, func(i, j int) bool {
		return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface]
	})

	return srcFilesInfo
}

var validstubsType = []StubsType{Everything, Runtime, Exportable}

func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) {
	if al.properties.Stubs_type == nil {
		ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.")
	} else {
		al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type))
	}

	if !android.InList(al.stubsType, validstubsType) {
		ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+
			"Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType)
	}
}

func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	al.validateProperties(ctx)

	rule := android.NewRuleBuilder(pctx, ctx)

	rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
		android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
		SandboxInputs()

	stubsDir := android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir"))
	rule.Command().Text("rm -rf").Text(stubsDir.String())
	rule.Command().Text("mkdir -p").Text(stubsDir.String())

	homeDir := android.PathForModuleOut(ctx, "metalava", "home")

	var srcFilesInfo []JavaApiImportInfo
	var classPaths android.Paths
	var bootclassPaths android.Paths
	var staticLibs android.Paths
	var systemModulesPaths android.Paths
	ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
		tag := ctx.OtherModuleDependencyTag(dep)
		switch tag {
		case javaApiContributionTag:
			provider, _ := android.OtherModuleProvider(ctx, dep, JavaApiImportProvider)
			if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() {
				ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name())
			}
			srcFilesInfo = append(srcFilesInfo, provider)
		case libTag:
			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
				classPaths = append(classPaths, provider.HeaderJars...)
				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
			}
		case bootClasspathTag:
			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
				bootclassPaths = append(bootclassPaths, provider.HeaderJars...)
				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
			}
		case staticLibTag:
			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
				staticLibs = append(staticLibs, provider.HeaderJars...)
				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
			}
		case systemModulesTag:
			if sm, ok := android.OtherModuleProvider(ctx, dep, SystemModulesProvider); ok {
				systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...)
			}
		case metalavaCurrentApiTimestampTag:
			if currentApiTimestampProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider); ok {
				al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp)
			}
		case aconfigDeclarationTag:
			if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
			} else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
			} else {
				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
					"module type is allowed for flags_packages property, but %s is neither "+
					"of these supported module types",
					dep.Name(),
				)
			}
		}
	})

	srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo)
	var srcFiles android.Paths
	for _, srcFileInfo := range srcFilesInfo {
		srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
	}

	if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
		ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
	}

	configFiles := android.PathsForModuleSrc(ctx, al.properties.ConfigFiles)

	combinedPaths := append(([]android.Path)(nil), systemModulesPaths...)
	combinedPaths = append(combinedPaths, classPaths...)
	combinedPaths = append(combinedPaths, bootclassPaths...)
	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles, al.properties.Api_surface)

	al.stubsFlags(ctx, cmd, stubsDir)

	previousApi := String(al.properties.Previous_api)
	if previousApi != "" {
		previousApiFiles := android.PathsForModuleSrc(ctx, []string{previousApi})
		cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
	}

	al.addValidation(ctx, cmd, al.validationPaths)

	generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles)

	al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
	al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar")
	al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))

	rule.Command().
		BuiltTool("soong_zip").
		Flag("-write_if_changed").
		Flag("-jar").
		FlagWithOutput("-o ", al.stubsSrcJar).
		FlagWithArg("-C ", stubsDir.String()).
		FlagWithArg("-D ", stubsDir.String())

	rule.Build("metalava", "metalava merged text")

	javacFlags := javaBuilderFlags{
		javaVersion:   getStubsJavaVersion(),
		javacFlags:    strings.Join(al.properties.Javacflags, " "),
		classpath:     classpath(classPaths),
		bootClasspath: classpath(append(systemModulesPaths, bootclassPaths...)),
	}

	annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar")

	TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
		android.Paths{al.stubsSrcJar}, annoSrcJar, javacFlags, android.Paths{})

	builder := android.NewRuleBuilder(pctx, ctx)
	builder.Command().
		BuiltTool("merge_zips").
		Output(al.stubsJar).
		Inputs(android.Paths{al.stubsJarWithoutStaticLibs}).
		Inputs(staticLibs)
	builder.Build("merge_zips", "merge jar files")

	// compile stubs to .dex for hiddenapi processing
	dexParams := &compileDexParams{
		flags:         javacFlags,
		sdkVersion:    al.SdkVersion(ctx),
		minSdkVersion: al.MinSdkVersion(ctx),
		classesJar:    al.stubsJar,
		jarName:       ctx.ModuleName() + ".jar",
	}
	dexOutputFile, _ := al.dexer.compileDex(ctx, dexParams)
	uncompressed := true
	al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed)
	dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile)
	al.dexJarFile = makeDexJarPathFromPath(dexOutputFile)

	ctx.Phony(ctx.ModuleName(), al.stubsJar)

	javaInfo := &JavaInfo{
		HeaderJars:                             android.PathsIfNonNil(al.stubsJar),
		LocalHeaderJars:                        android.PathsIfNonNil(al.stubsJar),
		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
		TransitiveStaticLibsImplementationJars: depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
		ImplementationAndResourcesJars:         android.PathsIfNonNil(al.stubsJar),
		ImplementationJars:                     android.PathsIfNonNil(al.stubsJar),
		AidlIncludeDirs:                        android.Paths{},
		StubsLinkType:                          Stubs,
		// No aconfig libraries on api libraries
	}
	setExtraJavaInfo(ctx, al, javaInfo)
	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}

func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
	return al.dexJarFile
}

func (al *ApiLibrary) DexJarInstallPath() android.Path {
	return al.dexJarFile.Path()
}

func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
	return nil
}

// Most java_api_library constitues the sdk, but there are some java_api_library that
// does not contribute to the api surface. Such modules are allowed to set sdk_version
// other than "none"
func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
	return android.SdkSpecFrom(ctx, proptools.String(al.properties.Sdk_version))
}

// java_api_library is always at "current". Return FutureApiLevel
func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	return al.SdkVersion(ctx).ApiLevel
}

func (al *ApiLibrary) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
	return al.SdkVersion(ctx).ApiLevel
}

func (al *ApiLibrary) SystemModules() string {
	return proptools.String(al.properties.System_modules)
}

func (al *ApiLibrary) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	return al.SdkVersion(ctx).ApiLevel
}

func (al *ApiLibrary) IDEInfo(ctx android.BaseModuleContext, i *android.IdeInfo) {
	i.Deps = append(i.Deps, al.ideDeps(ctx)...)
	i.Libs = append(i.Libs, al.properties.Libs.GetOrDefault(ctx, nil)...)
	i.Static_libs = append(i.Static_libs, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
	i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String())
}

// deps of java_api_library for module_bp_java_deps.json
func (al *ApiLibrary) ideDeps(ctx android.BaseModuleContext) []string {
	ret := []string{}
	ret = append(ret, al.properties.Libs.GetOrDefault(ctx, nil)...)
	ret = append(ret, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
	if proptools.StringDefault(al.properties.System_modules, "none") != "none" {
		ret = append(ret, proptools.String(al.properties.System_modules))
	}
	// Other non java_library dependencies like java_api_contribution are ignored for now.
	return ret
}

// implement the following interfaces for hiddenapi processing
var _ hiddenAPIModule = (*ApiLibrary)(nil)
var _ UsesLibraryDependency = (*ApiLibrary)(nil)
var _ android.SdkContext = (*ApiLibrary)(nil)

// implement the following interface for IDE completion.
var _ android.IDEInfo = (*ApiLibrary)(nil)

//
// Java prebuilts
//

type ImportProperties struct {
	Jars []string `android:"path,arch_variant"`

	// The version of the SDK that the source prebuilt file was built against. Defaults to the
	// current version if not specified.
	Sdk_version *string

	// The minimum version of the SDK that this module supports. Defaults to sdk_version if not
	// specified.
	Min_sdk_version *string

	// The max sdk version placeholder used to replace maxSdkVersion attributes on permission
	// and uses-permission tags in manifest_fixer.
	Replace_max_sdk_version_placeholder *string

	Installable *bool

	// If not empty, classes are restricted to the specified packages and their sub-packages.
	Permitted_packages []string

	// List of shared java libs that this module has dependencies to
	Libs []string

	// List of static java libs that this module has dependencies to
	Static_libs proptools.Configurable[[]string]

	// List of files to remove from the jar file(s)
	Exclude_files []string

	// List of directories to remove from the jar file(s)
	Exclude_dirs []string

	// if set to true, run Jetifier against .jar file. Defaults to false.
	Jetifier *bool

	// set the name of the output
	Stem *string

	Aidl struct {
		// 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
	}

	// Name of the source soong module that gets shadowed by this prebuilt
	// If unspecified, follows the naming convention that the source module of
	// the prebuilt is Name() without "prebuilt_" prefix
	Source_module_name *string

	// Non-nil if this java_import module was dynamically created by a java_sdk_library_import
	// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
	// (without any prebuilt_ prefix)
	Created_by_java_sdk_library_name *string `blueprint:"mutated"`

	// Property signifying whether the module provides stubs jar or not.
	Is_stubs_module *bool
}

type Import struct {
	android.ModuleBase
	android.DefaultableModuleBase
	android.ApexModuleBase
	prebuilt android.Prebuilt

	// Functionality common to Module and Import.
	embeddableInModuleAndImport

	hiddenAPI
	dexer
	dexpreopter

	properties ImportProperties

	// output file containing classes.dex and resources
	dexJarFile        OptionalDexJarPath
	dexJarFileErr     error
	dexJarInstallFile android.Path

	combinedImplementationFile android.Path
	combinedHeaderFile         android.Path
	classLoaderContexts        dexpreopt.ClassLoaderContextMap
	exportAidlIncludeDirs      android.Paths

	hideApexVariantFromMake bool

	sdkVersion    android.SdkSpec
	minSdkVersion android.ApiLevel

	stubsLinkType StubsLinkType
}

var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)

func (j *Import) PermittedPackagesForUpdatableBootJars() []string {
	return j.properties.Permitted_packages
}

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

func (j *Import) SystemModules() string {
	return "none"
}

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

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

func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	return j.SdkVersion(ctx).ApiLevel
}

func (j *Import) Prebuilt() *android.Prebuilt {
	return &j.prebuilt
}

func (j *Import) PrebuiltSrcs() []string {
	return j.properties.Jars
}

func (j *Import) BaseModuleName() string {
	return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
}

func (j *Import) Name() string {
	return j.prebuilt.Name(j.ModuleBase.Name())
}

func (j *Import) Stem() string {
	return proptools.StringDefault(j.properties.Stem, j.BaseModuleName())
}

func (j *Import) CreatedByJavaSdkLibraryName() *string {
	return j.properties.Created_by_java_sdk_library_name
}

func (a *Import) JacocoReportClassesFile() android.Path {
	return nil
}

func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...)

	if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
		sdkDeps(ctx, android.SdkContext(j), j.dexer)
	}
}

func (j *Import) commonBuildActions(ctx android.ModuleContext) {
	j.sdkVersion = j.SdkVersion(ctx)
	j.minSdkVersion = j.MinSdkVersion(ctx)

	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	if !apexInfo.IsForPlatform() {
		j.hideApexVariantFromMake = true
	}

	if ctx.Windows() {
		j.HideFromMake()
	}

	if proptools.Bool(j.properties.Is_stubs_module) {
		j.stubsLinkType = Stubs
	} else {
		j.stubsLinkType = Implementation
	}
}

func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.commonBuildActions(ctx)

	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)

	var flags javaBuilderFlags

	var transitiveClasspathHeaderJars []depset.DepSet[android.Path]
	var transitiveBootClasspathHeaderJars []depset.DepSet[android.Path]
	var transitiveStaticLibsHeaderJars []depset.DepSet[android.Path]
	var transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
	var transitiveStaticLibsResourceJars []depset.DepSet[android.Path]

	j.collectTransitiveHeaderJarsForR8(ctx)
	var staticJars android.Paths
	var staticResourceJars android.Paths
	var staticHeaderJars android.Paths
	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
		tag := ctx.OtherModuleDependencyTag(module)
		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
			switch tag {
			case libTag, sdkLibTag:
				flags.classpath = append(flags.classpath, dep.HeaderJars...)
				flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
			case staticLibTag:
				flags.classpath = append(flags.classpath, dep.HeaderJars...)
				staticJars = append(staticJars, dep.ImplementationJars...)
				staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
				staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
				transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
				transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars)
				transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars)
			case bootClasspathTag:
				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
				transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
			}
		} else if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
			switch tag {
			case libTag, sdkLibTag:
				sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
				generatingLibsString := android.PrettyConcat(
					getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
				ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
			}
		}

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

	localJars := android.PathsForModuleSrc(ctx, j.properties.Jars)
	jarName := j.Stem() + ".jar"

	// Combine only the local jars together for use in transitive classpaths.
	// Always pass input jar through TransformJarsToJar to strip module-info.class from prebuilts.
	localCombinedHeaderJar := android.PathForModuleOut(ctx, "local-combined", jarName)
	TransformJarsToJar(ctx, localCombinedHeaderJar, "combine local prebuilt implementation jars", localJars, android.OptionalPath{},
		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
	localStrippedJars := android.Paths{localCombinedHeaderJar}

	completeStaticLibsHeaderJars := depset.New(depset.PREORDER, localStrippedJars, transitiveStaticLibsHeaderJars)
	completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localStrippedJars, transitiveStaticLibsImplementationJars)
	completeStaticLibsResourceJars := depset.New(depset.PREORDER, nil, transitiveStaticLibsResourceJars)

	// Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output
	// file of the module to be named jarName.
	var outputFile android.Path
	combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName)
	implementationJars := completeStaticLibsImplementationJars.ToList()
	TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
	outputFile = combinedImplementationJar

	// If no dependencies have separate header jars then there is no need to create a separate
	// header jar for this module.
	reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars)

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

	var headerJar android.Path
	if reuseImplementationJarAsHeaderJar {
		headerJar = outputFile
	} else {
		headerJars := completeStaticLibsHeaderJars.ToList()
		headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
		TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
			false, j.properties.Exclude_files, j.properties.Exclude_dirs)
		headerJar = headerOutputFile
	}

	if Bool(j.properties.Jetifier) {
		jetifierOutputFile := android.PathForModuleOut(ctx, "jetifier", jarName)
		TransformJetifier(ctx, jetifierOutputFile, outputFile)
		outputFile = jetifierOutputFile

		if !reuseImplementationJarAsHeaderJar {
			jetifierHeaderJar := android.PathForModuleOut(ctx, "jetifier-headers", jarName)
			TransformJetifier(ctx, jetifierHeaderJar, headerJar)
			headerJar = jetifierHeaderJar
		} else {
			headerJar = outputFile
		}

		// Enabling jetifier requires modifying classes from transitive dependencies, disable transitive
		// classpath and use the combined header jar instead.
		completeStaticLibsHeaderJars = depset.New(depset.PREORDER, android.Paths{headerJar}, nil)
		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, android.Paths{outputFile}, nil)
	}

	implementationJarFile := outputFile

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

	proguardFlags := android.PathForModuleOut(ctx, "proguard_flags")
	TransformJarToR8Rules(ctx, proguardFlags, outputFile)

	transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
	android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
		ProguardFlagsFiles: depset.New[android.Path](
			depset.POSTORDER,
			android.Paths{proguardFlags},
			transitiveProguardFlags,
		),
		UnconditionallyExportedProguardFlags: depset.New[android.Path](
			depset.POSTORDER,
			nil,
			transitiveUnconditionalExportedFlags,
		),
	})

	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
	// Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
	// in a module that depends on this module considers them equal.
	j.combinedHeaderFile = headerJar.WithoutRel()
	j.combinedImplementationFile = outputFile.WithoutRel()

	j.maybeInstall(ctx, jarName, outputFile)

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

	ctx.CheckbuildFile(localJars...)

	if ctx.Device() {
		// Shared libraries deapexed from prebuilt apexes are no longer supported.
		// Set the dexJarBuildPath to a fake path.
		// This allows soong analysis pass, but will be an error during ninja execution if there are
		// any rdeps.
		ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
		if ai.ForPrebuiltApex {
			j.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported"))
			j.initHiddenAPI(ctx, j.dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
		} else if Bool(j.dexProperties.Compile_dex) {
			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.
				flags.classpath = append(flags.classpath, sdkDep.jars...)
			}

			// Dex compilation

			j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
				ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", jarName))
			setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
			j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex

			var dexOutputFile android.Path
			dexParams := &compileDexParams{
				flags:         flags,
				sdkVersion:    j.SdkVersion(ctx),
				minSdkVersion: j.MinSdkVersion(ctx),
				classesJar:    outputFile,
				jarName:       jarName,
			}

			dexOutputFile, _ = j.dexer.compileDex(ctx, dexParams)
			if ctx.Failed() {
				return
			}
			ctx.CheckbuildFile(dexOutputFile)

			// Initialize the hiddenapi structure.
			j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex)

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

			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
			j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
		}
	}

	javaInfo := &JavaInfo{
		HeaderJars:                             android.PathsIfNonNil(j.combinedHeaderFile),
		LocalHeaderJars:                        android.PathsIfNonNil(j.combinedHeaderFile),
		TransitiveLibsHeaderJarsForR8:          j.transitiveLibsHeaderJarsForR8,
		TransitiveStaticLibsHeaderJarsForR8:    j.transitiveStaticLibsHeaderJarsForR8,
		TransitiveStaticLibsHeaderJars:         completeStaticLibsHeaderJars,
		TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
		TransitiveStaticLibsResourceJars:       completeStaticLibsResourceJars,
		ImplementationAndResourcesJars:         android.PathsIfNonNil(j.combinedImplementationFile),
		ImplementationJars:                     android.PathsIfNonNil(implementationJarFile.WithoutRel()),
		ResourceJars:                           android.PathsIfNonNil(resourceJarFile),
		AidlIncludeDirs:                        j.exportAidlIncludeDirs,
		StubsLinkType:                          j.stubsLinkType,
		// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
	}
	setExtraJavaInfo(ctx, j, javaInfo)
	android.SetProvider(ctx, JavaInfoProvider, javaInfo)

	android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
		Prebuilt: true,
	})

	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")

	buildComplianceMetadata(ctx)
}

func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
	if !Bool(j.properties.Installable) {
		return
	}

	var installDir android.InstallPath
	if ctx.InstallInTestcases() {
		var archDir string
		if !ctx.Host() {
			archDir = ctx.DeviceConfig().DeviceArch()
		}
		installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir)
	} else {
		installDir = android.PathForModuleInstall(ctx, "framework")
	}
	ctx.InstallFile(installDir, jarName, outputFile)
}

func (j *Import) HeaderJars() android.Paths {
	return android.PathsIfNonNil(j.combinedHeaderFile)
}

func (j *Import) ImplementationAndResourcesJars() android.Paths {
	return android.PathsIfNonNil(j.combinedImplementationFile)
}

func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
	if j.dexJarFileErr != nil {
		ctx.ModuleErrorf(j.dexJarFileErr.Error())
	}
	return j.dexJarFile
}

func (j *Import) DexJarInstallPath() android.Path {
	return j.dexJarInstallFile
}

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

var _ android.ApexModule = (*Import)(nil)

// Implements android.ApexModule
func (m *Import) GetDepInSameApexChecker() android.DepInSameApexChecker {
	return JavaImportDepInSameApexChecker{}
}

type JavaImportDepInSameApexChecker struct {
	android.BaseDepInSameApexChecker
}

func (m JavaImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
	return depIsInSameApex(tag)
}

// Implements android.ApexModule
func (j *Import) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
	sdkVersionSpec := j.SdkVersion(ctx)
	minSdkVersion := j.MinSdkVersion(ctx)

	// If the module is compiling against core (via sdk_version), skip comparison check.
	if sdkVersionSpec.Kind == android.SdkCore {
		return android.MinApiLevel
	}

	return minSdkVersion
}

// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
// java_sdk_library_import with the specified base module name requires to be exported from a
// prebuilt_apex/apex_set.
func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string {
	dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name)
	// Add the dex implementation jar to the set of exported files.
	files := []string{
		dexJarFileApexRootRelative,
	}
	if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) {
		files = append(files, dexJarFileApexRootRelative+".prof")
	}
	return files
}

// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
// the java library with the specified name.
func ApexRootRelativePathToJavaLib(name string) string {
	return filepath.Join("javalib", name+".jar")
}

var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil)

func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string {
	name := j.BaseModuleName()
	return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter)
}

func (j *Import) UseProfileGuidedDexpreopt() bool {
	return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided)
}

// Add compile time check for interface implementation
var _ android.IDEInfo = (*Import)(nil)

// Collect information for opening IDE project files in java/jdeps.go.
func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
	dpInfo.Jars = append(dpInfo.Jars, j.combinedImplementationFile.String())
}

var _ android.PrebuiltInterface = (*Import)(nil)

func (j *Import) IsInstallable() bool {
	return Bool(j.properties.Installable)
}

var _ DexpreopterInterface = (*Import)(nil)

// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
//
// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against an Android classpath.
//
// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
// for host modules.
func ImportFactory() android.Module {
	module := &Import{}

	module.AddProperties(
		&module.properties,
		&module.dexer.dexProperties,
		&module.importDexpreoptProperties,
	)

	module.initModuleAndImport(module)

	module.dexProperties.Optimize.EnabledByDefault = false

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitApexModule(module)
	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
// module.
//
// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
// compiled against a host bootclasspath.
func ImportFactoryHost() android.Module {
	module := &Import{}

	module.AddProperties(&module.properties)

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitApexModule(module)
	InitJavaModule(module, android.HostSupported)
	return module
}

// dex_import module

type DexImportProperties struct {
	Jars []string `android:"path"`

	// set the name of the output
	Stem *string
}

type DexImport struct {
	android.ModuleBase
	android.DefaultableModuleBase
	android.ApexModuleBase
	prebuilt android.Prebuilt

	properties DexImportProperties

	dexJarFile OptionalDexJarPath

	dexpreopter

	hideApexVariantFromMake bool
}

func (j *DexImport) Prebuilt() *android.Prebuilt {
	return &j.prebuilt
}

func (j *DexImport) PrebuiltSrcs() []string {
	return j.properties.Jars
}

func (j *DexImport) Name() string {
	return j.prebuilt.Name(j.ModuleBase.Name())
}

func (j *DexImport) Stem() string {
	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}

func (a *DexImport) JacocoReportClassesFile() android.Path {
	return nil
}

func (j *DexImport) IsInstallable() bool {
	return true
}

func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if len(j.properties.Jars) != 1 {
		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
	}

	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	if !apexInfo.IsForPlatform() {
		j.hideApexVariantFromMake = true
	}

	j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
		ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter)

	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")

	if j.dexpreopter.uncompressedDex {
		rule := android.NewRuleBuilder(pctx, ctx)

		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
		rule.Temporary(temporary)

		// use zip2zip to uncompress classes*.dex files
		rule.Command().
			BuiltTool("zip2zip").
			FlagWithInput("-i ", inputJar).
			FlagWithOutput("-o ", temporary).
			FlagWithArg("-0 ", "'classes*.dex'")

		// use zipalign to align uncompressed classes*.dex files
		rule.Command().
			BuiltTool("zipalign").
			Flag("-f").
			Text("4").
			Input(temporary).
			Output(dexOutputFile)

		rule.DeleteTemporaryFiles()

		rule.Build("uncompress_dex", "uncompress dex")
	} else {
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Cp,
			Input:  inputJar,
			Output: dexOutputFile,
		})
	}

	j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)

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

	if apexInfo.IsForPlatform() {
		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
			j.Stem()+".jar", dexOutputFile)
	}

	javaInfo := &JavaInfo{}
	setExtraJavaInfo(ctx, j, javaInfo)
	android.SetProvider(ctx, JavaInfoProvider, javaInfo)

	android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{})
}

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

var _ android.ApexModule = (*DexImport)(nil)

// Implements android.ApexModule
func (m *DexImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
	return android.MinApiLevel
}

// dex_import imports a `.jar` file containing classes.dex files.
//
// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
// to the device.
func DexImportFactory() android.Module {
	module := &DexImport{}

	module.AddProperties(&module.properties)

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitApexModule(module)
	InitJavaModule(module, android.DeviceSupported)
	return module
}

// Defaults
type Defaults struct {
	android.ModuleBase
	android.DefaultsModuleBase
}

// java_defaults provides a set of properties that can be inherited by other java or android modules.
//
// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`.  Each
// property in the defaults module that exists in the depending module will be prepended to the depending module's
// value for that property.
//
// Example:
//
//	java_defaults {
//	    name: "example_defaults",
//	    srcs: ["common/**/*.java"],
//	    javacflags: ["-Xlint:all"],
//	    aaptflags: ["--auto-add-overlay"],
//	}
//
//	java_library {
//	    name: "example",
//	    defaults: ["example_defaults"],
//	    srcs: ["example/**/*.java"],
//	}
//
// is functionally identical to:
//
//	java_library {
//	    name: "example",
//	    srcs: [
//	        "common/**/*.java",
//	        "example/**/*.java",
//	    ],
//	    javacflags: ["-Xlint:all"],
//	}
func DefaultsFactory() android.Module {
	module := &Defaults{}

	module.AddProperties(
		&CommonProperties{},
		&DeviceProperties{},
		&OverridableProperties{},
		&DexProperties{},
		&DexpreoptProperties{},
		&android.ProtoProperties{},
		&aaptProperties{},
		&androidLibraryProperties{},
		&appProperties{},
		&appTestProperties{},
		&overridableAppProperties{},
		&hostTestProperties{},
		&testProperties{},
		&ImportProperties{},
		&AARImportProperties{},
		&sdkLibraryProperties{},
		&commonToSdkLibraryAndImportProperties{},
		&DexImportProperties{},
		&android.ApexProperties{},
		&RuntimeResourceOverlayProperties{},
		&LintProperties{},
		&appTestHelperAppProperties{},
		&JavaApiLibraryProperties{},
		&bootclasspathFragmentProperties{},
		&SourceOnlyBootclasspathProperties{},
		&ravenwoodTestProperties{},
		&AndroidAppImportProperties{},
		&UsesLibraryProperties{},
	)

	android.InitDefaultsModule(module)
	return module
}

func kytheExtractJavaFactory() android.Singleton {
	return &kytheExtractJavaSingleton{}
}

type kytheExtractJavaSingleton struct {
}

func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	var xrefTargets android.Paths
	var xrefKotlinTargets android.Paths
	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
		if javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
			xrefTargets = append(xrefTargets, javaInfo.XrefJavaFiles...)
			xrefKotlinTargets = append(xrefKotlinTargets, javaInfo.XrefKotlinFiles...)
		}
	})
	// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
	if len(xrefTargets) > 0 {
		ctx.Phony("xref_java", xrefTargets...)
	}
	if len(xrefKotlinTargets) > 0 {
		ctx.Phony("xref_kotlin", xrefKotlinTargets...)
	}
}

var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
var inList = android.InList[string]

// Add class loader context (CLC) of a given dependency to the current CLC.
func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
	clcMap dexpreopt.ClassLoaderContextMap) {

	dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
	if !ok || dep.UsesLibraryDependencyInfo == nil {
		return
	}

	depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule))

	var sdkLib *string
	if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
		// A shared SDK library. This should be added as a top-level CLC element.
		sdkLib = &depName
	} else if lib := dep.SdkLibraryComponentDependencyInfo; lib != nil && lib.OptionalSdkLibraryImplementation != nil {
		if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation)+".impl" {
			sdkLib = lib.OptionalSdkLibraryImplementation
		}
	} else if ulib := dep.ProvidesUsesLibInfo; ulib != nil {
		// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
		// property. This should be handled in the same way as a shared SDK library.
		sdkLib = ulib.ProvidesUsesLib
	}

	depTag := ctx.OtherModuleDependencyTag(depModule)
	if IsLibDepTag(depTag) {
		// Ok, propagate <uses-library> through non-static library dependencies.
	} else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion {
		// Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies.
	} else if depTag == staticLibTag {
		// Propagate <uses-library> through static library dependencies, unless it is a component
		// library (such as stubs). Component libraries have a dependency on their SDK library,
		// which should not be pulled just because of a static component library.
		if sdkLib != nil {
			return
		}
	} else {
		// Don't propagate <uses-library> for other dependency tags.
		return
	}

	// If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree,
	// and its CLC should be added as subtree of that node. Otherwise the library is not a
	// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
	// from its CLC should be added to the current CLC.
	if sdkLib != nil {
		optional := false
		if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok {
			if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
				optional = true
			}
		}
		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
			dep.DexJarBuildPath.PathOrNil(),
			dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts)
	} else {
		clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName)
	}
}

func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
	usesLibrary *usesLibrary) {

	dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
	if !ok {
		return
	}

	for _, lib := range dep.MissingOptionalUsesLibs {
		if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
			usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
				append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
		}
	}
}

type JavaApiContributionImport struct {
	JavaApiContribution

	prebuilt           android.Prebuilt
	prebuiltProperties javaApiContributionImportProperties
}

type javaApiContributionImportProperties struct {
	// Name of the source soong module that gets shadowed by this prebuilt
	// If unspecified, follows the naming convention that the source module of
	// the prebuilt is Name() without "prebuilt_" prefix
	Source_module_name *string

	// Non-nil if this java_import module was dynamically created by a java_sdk_library_import
	// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
	// (without any prebuilt_ prefix)
	Created_by_java_sdk_library_name *string `blueprint:"mutated"`
}

func ApiContributionImportFactory() android.Module {
	module := &JavaApiContributionImport{}
	android.InitAndroidModule(module)
	android.InitDefaultableModule(module)
	android.InitPrebuiltModule(module, &[]string{""})
	module.AddProperties(&module.properties, &module.prebuiltProperties)
	module.AddProperties(&module.sdkLibraryComponentProperties)
	return module
}

func (module *JavaApiContributionImport) Prebuilt() *android.Prebuilt {
	return &module.prebuilt
}

func (module *JavaApiContributionImport) Name() string {
	return module.prebuilt.Name(module.ModuleBase.Name())
}

func (j *JavaApiContributionImport) BaseModuleName() string {
	return proptools.StringDefault(j.prebuiltProperties.Source_module_name, j.ModuleBase.Name())
}

func (j *JavaApiContributionImport) CreatedByJavaSdkLibraryName() *string {
	return j.prebuiltProperties.Created_by_java_sdk_library_name
}

func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
}

func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo *JavaInfo) {
	if alDep, ok := module.(AndroidLibraryDependency); ok {
		javaInfo.AndroidLibraryDependencyInfo = &AndroidLibraryDependencyInfo{
			ExportPackage:       alDep.ExportPackage(),
			ResourcesNodeDepSet: alDep.ResourcesNodeDepSet(),
			RRODirsDepSet:       alDep.RRODirsDepSet(),
			ManifestsDepSet:     alDep.ManifestsDepSet(),
		}
	}

	if ulDep, ok := module.(UsesLibraryDependency); ok {
		javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{
			DexJarInstallPath:   ulDep.DexJarInstallPath(),
			ClassLoaderContexts: ulDep.ClassLoaderContexts(),
		}
	}

	if slcDep, ok := module.(SdkLibraryComponentDependency); ok {
		javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{
			OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(),
		}
	}

	if pul, ok := module.(ProvidesUsesLib); ok {
		javaInfo.ProvidesUsesLibInfo = &ProvidesUsesLibInfo{
			ProvidesUsesLib: pul.ProvidesUsesLib(),
		}
	}

	if mwul, ok := module.(ModuleWithUsesLibrary); ok {
		javaInfo.MissingOptionalUsesLibs = mwul.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs
	}

	if mwsd, ok := module.(moduleWithSdkDep); ok {
		linkType, stubs := mwsd.getSdkLinkType(ctx, ctx.ModuleName())
		javaInfo.ModuleWithSdkDepInfo = &ModuleWithSdkDepInfo{
			SdkLinkType: linkType,
			Stubs:       stubs,
		}
	}

	if st, ok := module.(ModuleWithStem); ok {
		javaInfo.Stem = st.Stem()
	}

	if mm, ok := module.(interface {
		DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
	}); ok {
		javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx)
	}

	if di, ok := module.(DexpreopterInterface); ok {
		javaInfo.DexpreopterInfo = &DexpreopterInfo{
			OutputProfilePathOnHost:           di.OutputProfilePathOnHost(),
			ApexSystemServerDexpreoptInstalls: di.ApexSystemServerDexpreoptInstalls(),
			ApexSystemServerDexJars:           di.ApexSystemServerDexJars(),
		}
	}

	if xr, ok := module.(xref); ok {
		javaInfo.XrefJavaFiles = xr.XrefJavaFiles()
		javaInfo.XrefKotlinFiles = xr.XrefKotlinFiles()
	}
}
