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

	// 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 {
	DexJarBuildPath     OptionalDexJarPath
	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

	ModuleWithUsesLibraryInfo *ModuleWithUsesLibraryInfo

	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

	// ApexSystemServerDexpreoptInstalls stores the list of dexpreopt artifacts if this is a system server
	// jar in an apex.
	ApexSystemServerDexpreoptInstalls []DexpreopterInstall

	// ApexSystemServerDexJars stores the list of dex jars if this is a system server jar in an apex.
	ApexSystemServerDexJars android.Paths

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

	// The path to the profile on host that dexpreopter generates. This is used as the input for
	// dex2oat.
	OutputProfilePathOnHost android.Path

	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
}

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

type JavaLibraryInfo struct{}

var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]()

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

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

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

	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.ApexSystemServerDexpreoptInstalls = j.apexSystemServerDexpreoptInstalls
		javaInfo.ApexSystemServerDexJars = j.apexSystemServerDexJars
		javaInfo.BuiltInstalled = j.builtInstalled
		javaInfo.ConfigPath = j.configPath
		javaInfo.OutputProfilePathOnHost = j.outputProfilePathOnHost
		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)
}

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.FirstUniqueStrings(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.FirstUniqueStrings(staticDepNames))
	complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(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")
		}
	}
}

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

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

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

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.OtherModuleProvider(ctx, jni, android.CommonModuleInfoKey)
		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") &&
		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)
	var implementationJars android.Paths
	if ctx.Config().UseTransitiveJarsInClasspath() {
		implementationJars = completeStaticLibsImplementationJars.ToList()
	} else {
		implementationJars = append(slices.Clone(localJars), staticJars...)
	}
	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 {
		var headerJars android.Paths
		if ctx.Config().UseTransitiveJarsInClasspath() {
			headerJars = completeStaticLibsHeaderJars.ToList()
		} else {
			headerJars = append(slices.Clone(localJars), staticHeaderJars...)
		}
		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)

	if ctx.Config().UseTransitiveJarsInClasspath() {
		ctx.CheckbuildFile(localJars...)
	} else {
		ctx.CheckbuildFile(outputFile)
	}

	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)

	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 (j *Import) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
	return j.depIsInSameApex(tag)
}

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

// 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)
var _ android.IDECustomizedModuleName = (*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())
}

func (j *Import) IDECustomizedModuleName() string {
	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
	// solution to get the Import name.
	return android.RemoveOptionalPrebuiltPrefix(j.Name())
}

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

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

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

// Implements android.ApexModule
func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
	sdkVersion android.ApiLevel) error {
	// we don't check prebuilt modules for sdk_version
	return nil
}

// 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
	android.ApexModuleBase
}

// 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.VisitAllModules(func(module android.Module) {
		if javaModule, ok := module.(xref); ok {
			xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
			xrefKotlinTargets = append(xrefKotlinTargets, javaModule.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.UsesLibraryDependencyInfo.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 || dep.ModuleWithUsesLibraryInfo == nil {
		return
	}

	for _, lib := range dep.ModuleWithUsesLibraryInfo.UsesLibrary.usesLibraryProperties.Missing_optional_uses_libs {
		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{
			DexJarBuildPath:     ulDep.DexJarBuildPath(ctx),
			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.ModuleWithUsesLibraryInfo = &ModuleWithUsesLibraryInfo{
			UsesLibrary: mwul.UsesLibrary(),
		}
	}

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