// 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"
	"strconv"
	"strings"

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

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

func init() {
	android.RegisterModuleType("java_defaults", defaultsFactory)

	android.RegisterModuleType("java_library", LibraryFactory)
	android.RegisterModuleType("java_library_static", LibraryFactory)
	android.RegisterModuleType("java_library_host", LibraryHostFactory)
	android.RegisterModuleType("java_binary", BinaryFactory)
	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
	android.RegisterModuleType("java_test", TestFactory)
	android.RegisterModuleType("java_test_host", TestHostFactory)
	android.RegisterModuleType("java_import", ImportFactory)
	android.RegisterModuleType("java_import_host", ImportFactoryHost)

	android.RegisterSingletonType("logtags", LogtagsSingleton)
}

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

type CompilerProperties struct {
	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
	// or .aidl files.
	Srcs []string `android:"arch_variant"`

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

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

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

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

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

	// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
	// ext, and framework for device targets)
	No_standard_libs *bool

	// don't build against the framework libraries (legacy-test, core-junit,
	// ext, and framework for device targets)
	No_framework_libs *bool

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

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

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

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

	// manifest file to be included in resulting jar
	Manifest *string

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

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

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

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

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

	// List of classes to pass to javac to use as annotation processors
	Annotation_processor_classes []string

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

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

	Openjdk9 struct {
		// List of source files that should only be used when passing -source 1.9
		Srcs []string

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

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

	Jacoco struct {
		// List of classes to include for instrumentation with jacoco to collect coverage
		// information at runtime when building with coverage enabled.  If unset defaults to all
		// classes.
		// Supports '*' as the last character of an entry in the list as a wildcard match.
		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
		// it matches classes in the package that have the class name as a prefix.
		Include_filter []string

		// List of classes to exclude from instrumentation with jacoco to collect coverage
		// information at runtime when building with coverage enabled.  Overrides classes selected
		// by the include_filter property.
		// Supports '*' as the last character of an entry in the list as a wildcard match.
		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
		// it matches classes in the package that have the class name as a prefix.
		Exclude_filter []string
	}

	Errorprone struct {
		// List of javac flags that should only be used when running errorprone.
		Javacflags []string
	}

	Proto struct {
		// List of extra options that will be passed to the proto generator.
		Output_params []string
	}

	Instrument bool `blueprint:"mutated"`
}

type CompilerDeviceProperties struct {
	// list of module-specific flags that will be used for dex compiles
	Dxflags []string `android:"arch_variant"`

	// if not blank, set to the version of the sdk to compile against.  Defaults to compiling against the current
	// sdk if platform_apis is not set.
	Sdk_version *string

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

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

	// if true, compile against the platform APIs instead of an SDK.
	Platform_apis *bool

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

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

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

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

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

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

	// If set to true, compile dex regardless of installable.  Defaults to false.
	Compile_dex *bool

	Optimize struct {
		// If false, disable all optimization.  Defaults to true for android_app and android_test
		// modules, false for java_library and java_test modules.
		Enabled *bool

		// If true, optimize for size by removing unused code.  Defaults to true for apps,
		// false for libraries and tests.
		Shrink *bool

		// If true, optimize bytecode.  Defaults to false.
		Optimize *bool

		// If true, obfuscate bytecode.  Defaults to false.
		Obfuscate *bool

		// If true, do not use the flag files generated by aapt that automatically keep
		// classes referenced by the app manifest.  Defaults to false.
		No_aapt_flags *bool

		// Flags to pass to proguard.
		Proguard_flags []string

		// Specifies the locations of files containing proguard flags.
		Proguard_flags_files []string
	}

	// When targeting 1.9, override the modules to use with --system
	System_modules *string

	UncompressDex bool `blueprint:"mutated"`
	IsSDKLibrary  bool `blueprint:"mutated"`
}

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

	properties       CompilerProperties
	protoProperties  android.ProtoProperties
	deviceProperties CompilerDeviceProperties

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

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

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

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

	// output file containing classes.dex and resources
	dexJarFile android.Path

	// output file that contains classes.dex if it should be in the output file
	maybeStrippedDexJarFile android.Path

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

	// output file containing mapping of obfuscated names
	proguardDictionary android.Path

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

	exportAidlIncludeDirs android.Paths

	logtagsSrcs android.Paths

	// installed file for binary dependency
	installFile android.Path

	// list of .java files and srcjars that was passed to javac
	compiledJavaSrcs android.Paths
	compiledSrcJars  android.Paths

	// list of extra progurad flag files
	extraProguardFlagFiles android.Paths

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

	// list of SDK lib names that this java moudule is exporting
	exportedSdkLibs []string

	// list of source files, collected from compiledJavaSrcs and compiledSrcJars
	// filter out Exclude_srcs, will be used by android.IDEInfo struct
	expandIDEInfoCompiledSrcs []string

	dexpreopter
}

func (j *Module) Srcs() android.Paths {
	return android.Paths{j.outputFile}
}

func (j *Module) DexJarFile() android.Path {
	return j.dexJarFile
}

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

type Dependency interface {
	HeaderJars() android.Paths
	ImplementationJars() android.Paths
	ResourceJars() android.Paths
	ImplementationAndResourcesJars() android.Paths
	AidlIncludeDirs() android.Paths
	ExportedSdkLibs() []string
}

type SdkLibraryDependency interface {
	HeaderJars(linkType linkType) android.Paths
	ImplementationJars(linkType linkType) android.Paths
}

type SrcDependency interface {
	CompiledSrcs() android.Paths
	CompiledSrcJars() android.Paths
}

func (j *Module) CompiledSrcs() android.Paths {
	return j.compiledJavaSrcs
}

func (j *Module) CompiledSrcJars() android.Paths {
	return j.compiledSrcJars
}

var _ SrcDependency = (*Module)(nil)

func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
	android.InitDefaultableModule(module)
}

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string
}

type jniDependencyTag struct {
	blueprint.BaseDependencyTag
	target android.Target
}

var (
	staticLibTag          = dependencyTag{name: "staticlib"}
	libTag                = dependencyTag{name: "javalib"}
	annoTag               = dependencyTag{name: "annotation processor"}
	bootClasspathTag      = dependencyTag{name: "bootclasspath"}
	systemModulesTag      = dependencyTag{name: "system modules"}
	frameworkResTag       = dependencyTag{name: "framework-res"}
	frameworkApkTag       = dependencyTag{name: "framework-apk"}
	kotlinStdlibTag       = dependencyTag{name: "kotlin-stdlib"}
	proguardRaiseTag      = dependencyTag{name: "proguard-raise"}
	certificateTag        = dependencyTag{name: "certificate"}
	instrumentationForTag = dependencyTag{name: "instrumentation_for"}
)

type sdkDep struct {
	useModule, useFiles, useDefaultLibs, invalidVersion bool

	modules       []string
	systemModules string

	frameworkResModule string

	jars android.Paths
	aidl android.Path
}

type jniLib struct {
	name   string
	path   android.Path
	target android.Target
}

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

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

func (j *Module) sdkVersion() string {
	return String(j.deviceProperties.Sdk_version)
}

func (j *Module) minSdkVersion() string {
	if j.deviceProperties.Min_sdk_version != nil {
		return *j.deviceProperties.Min_sdk_version
	}
	return j.sdkVersion()
}

func (j *Module) targetSdkVersion() string {
	if j.deviceProperties.Target_sdk_version != nil {
		return *j.deviceProperties.Target_sdk_version
	}
	return j.sdkVersion()
}

type sdkContext interface {
	// sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
	sdkVersion() string
	// minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
	minSdkVersion() string
	// targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
	targetSdkVersion() string
}

func sdkVersionOrDefault(ctx android.BaseContext, v string) string {
	switch v {
	case "", "current", "system_current", "test_current", "core_current":
		return ctx.Config().DefaultAppTargetSdk()
	default:
		return v
	}
}

// Returns a sdk version as a number.  For modules targeting an unreleased SDK (meaning it does not yet have a number)
// it returns android.FutureApiLevel (10000).
func sdkVersionToNumber(ctx android.BaseContext, v string) (int, error) {
	switch v {
	case "", "current", "test_current", "system_current", "core_current":
		return ctx.Config().DefaultAppTargetSdkInt(), nil
	default:
		n := android.GetNumericSdkVersion(v)
		if i, err := strconv.Atoi(n); err != nil {
			return -1, fmt.Errorf("invalid sdk version %q", n)
		} else {
			return i, nil
		}
	}
}

func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, error) {
	n, err := sdkVersionToNumber(ctx, v)
	if err != nil {
		return "", err
	}
	return strconv.Itoa(n), nil
}

func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep {
	v := sdkContext.sdkVersion()
	i, err := sdkVersionToNumber(ctx, v)
	if err != nil {
		ctx.PropertyErrorf("sdk_version", "%s", err)
		return sdkDep{}
	}

	// Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks)
	// or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set)
	if strings.HasPrefix(v, "system_") && i != android.FutureApiLevel {
		allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions()
		if ctx.DeviceSpecific() || ctx.SocSpecific() {
			if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 {
				allowed_versions = ctx.DeviceConfig().SystemSdkVersions()
			}
		}
		version := strings.TrimPrefix(v, "system_")
		if len(allowed_versions) > 0 && !android.InList(version, allowed_versions) {
			ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
				v, allowed_versions)
		}
	}

	toPrebuilt := func(sdk string) sdkDep {
		var api, v string
		if strings.Contains(sdk, "_") {
			t := strings.Split(sdk, "_")
			api = t[0]
			v = t[1]
		} else {
			api = "public"
			v = sdk
		}
		dir := filepath.Join("prebuilts", "sdk", v, api)
		jar := filepath.Join(dir, "android.jar")
		// There's no aidl for other SDKs yet.
		// TODO(77525052): Add aidl files for other SDKs too.
		public_dir := filepath.Join("prebuilts", "sdk", v, "public")
		aidl := filepath.Join(public_dir, "framework.aidl")
		jarPath := android.ExistentPathForSource(ctx, jar)
		aidlPath := android.ExistentPathForSource(ctx, aidl)
		lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)

		if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
			return sdkDep{
				invalidVersion: true,
				modules:        []string{fmt.Sprintf("sdk_%s_%s_android", api, v)},
			}
		}

		if !jarPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
			return sdkDep{}
		}

		if !aidlPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
			return sdkDep{}
		}

		return sdkDep{
			useFiles: true,
			jars:     android.Paths{jarPath.Path(), lambdaStubsPath},
			aidl:     aidlPath.Path(),
		}
	}

	toModule := func(m, r string) sdkDep {
		ret := sdkDep{
			useModule:          true,
			modules:            []string{m, config.DefaultLambdaStubsLibrary},
			systemModules:      m + "_system_modules",
			frameworkResModule: r,
		}
		if m == "core.current.stubs" {
			ret.systemModules = "core-system-modules"
		} else if m == "core.platform.api.stubs" {
			ret.systemModules = "core-platform-api-stubs-system-modules"
		}
		return ret
	}

	if ctx.Config().UnbundledBuildPrebuiltSdks() && v != "" {
		return toPrebuilt(v)
	}

	switch v {
	case "":
		return sdkDep{
			useDefaultLibs:     true,
			frameworkResModule: "framework-res",
		}
	case "current":
		return toModule("android_stubs_current", "framework-res")
	case "system_current":
		return toModule("android_system_stubs_current", "framework-res")
	case "test_current":
		return toModule("android_test_stubs_current", "framework-res")
	case "core_current":
		return toModule("core.current.stubs", "")
	default:
		return toPrebuilt(v)
	}
}

func (j *Module) deps(ctx android.BottomUpMutatorContext) {
	if ctx.Device() {
		if !Bool(j.properties.No_standard_libs) {
			sdkDep := decodeSdkDep(ctx, sdkContext(j))
			if sdkDep.useDefaultLibs {
				ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
				ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
				if !Bool(j.properties.No_framework_libs) {
					ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
				}
			} else if sdkDep.useModule {
				ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
				ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
				if Bool(j.deviceProperties.Optimize.Enabled) {
					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
				}
			}
		} else if j.deviceProperties.System_modules == nil {
			ctx.PropertyErrorf("no_standard_libs",
				"system_modules is required to be set when no_standard_libs is true, did you mean no_framework_libs?")
		} else if *j.deviceProperties.System_modules != "none" {
			ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
		}
		if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
			ctx.AddVariationDependencies(nil, frameworkResTag, "framework-res")
		}
		if ctx.ModuleName() == "android_stubs_current" ||
			ctx.ModuleName() == "android_system_stubs_current" ||
			ctx.ModuleName() == "android_test_stubs_current" {
			ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
		}
	}

	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
	ctx.AddFarVariationDependencies([]blueprint.Variation{
		{Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
	}, annoTag, j.properties.Annotation_processors...)

	android.ExtractSourcesDeps(ctx, j.properties.Srcs)
	android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
	android.ExtractSourcesDeps(ctx, j.properties.Java_resources)
	android.ExtractSourceDeps(ctx, j.properties.Manifest)

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

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

	if j.shouldInstrumentStatic(ctx) {
		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
	}
}

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

	return false
}

func shardPaths(paths android.Paths, shardSize int) []android.Paths {
	ret := make([]android.Paths, 0, (len(paths)+shardSize-1)/shardSize)
	for len(paths) > shardSize {
		ret = append(ret, paths[0:shardSize])
		paths = paths[shardSize:]
	}
	if len(paths) > 0 {
		ret = append(ret, paths)
	}
	return ret
}

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

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

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

	flags := []string{"-b"}

	if aidlPreprocess.Valid() {
		flags = append(flags, "-p"+aidlPreprocess.String())
	} else {
		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
	}

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

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

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

	return flags
}

type deps struct {
	classpath          classpath
	bootClasspath      classpath
	processorPath      classpath
	staticJars         android.Paths
	staticHeaderJars   android.Paths
	staticResourceJars android.Paths
	aidlIncludeDirs    android.Paths
	srcs               android.Paths
	srcJars            android.Paths
	systemModules      android.Path
	aidlPreprocess     android.OptionalPath
	kotlinStdlib       android.Paths
}

func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
	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(dep.(blueprint.Module)))
		}
	}
}

type linkType int

const (
	javaCore linkType = iota
	javaSdk
	javaSystem
	javaPlatform
)

func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
	ver := m.sdkVersion()
	switch {
	case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
		name == "stub-annotations" || name == "private-stub-annotations-jar" ||
		name == "core-lambda-stubs":
		return javaCore, true
	case ver == "core_current":
		return javaCore, false
	case name == "android_system_stubs_current":
		return javaSystem, true
	case strings.HasPrefix(ver, "system_"):
		return javaSystem, false
	case name == "android_test_stubs_current":
		return javaSystem, true
	case strings.HasPrefix(ver, "test_"):
		return javaPlatform, false
	case name == "android_stubs_current":
		return javaSdk, true
	case ver == "current":
		return javaSdk, false
	case ver == "":
		return javaPlatform, false
	default:
		if _, err := strconv.Atoi(ver); err != nil {
			panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
		}
		return javaSdk, false
	}
}

func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dependencyTag) {
	if ctx.Host() {
		return
	}

	myLinkType, stubs := getLinkType(from, ctx.ModuleName())
	if stubs {
		return
	}
	otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
	commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."

	switch myLinkType {
	case javaCore:
		if otherLinkType != javaCore {
			ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
				ctx.OtherModuleName(to))
		}
		break
	case javaSdk:
		if otherLinkType != javaCore && otherLinkType != javaSdk {
			ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
				ctx.OtherModuleName(to))
		}
		break
	case javaSystem:
		if otherLinkType == javaPlatform {
			ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
				ctx.OtherModuleName(to))
		}
		break
	case javaPlatform:
		// no restriction on link-type
		break
	}
}

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

	if ctx.Device() {
		sdkDep := decodeSdkDep(ctx, sdkContext(j))
		if sdkDep.invalidVersion {
			ctx.AddMissingDependencies(sdkDep.modules)
		} else if sdkDep.useFiles {
			// sdkDep.jar is actually equivalent to turbine header.jar.
			deps.classpath = append(deps.classpath, sdkDep.jars...)
			deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
		}
	}

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

		if _, ok := tag.(*jniDependencyTag); ok {
			// Handled by AndroidApp.collectAppDeps
			return
		}
		if tag == certificateTag {
			// Handled by AndroidApp.collectAppDeps
			return
		}

		if to, ok := module.(*Library); ok {
			switch tag {
			case bootClasspathTag, libTag, staticLibTag:
				checkLinkType(ctx, j, to, tag.(dependencyTag))
			}
		}
		switch dep := module.(type) {
		case Dependency:
			switch tag {
			case bootClasspathTag:
				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
			case libTag, instrumentationForTag:
				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
				// sdk lib names from dependencies are re-exported
				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
			case staticLibTag:
				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
				// sdk lib names from dependencies are re-exported
				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
			case annoTag:
				deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
			case frameworkResTag:
				if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
					// framework.jar has a one-off dependency on the R.java and Manifest.java files
					// generated by framework-res.apk
					deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
				}
			case frameworkApkTag:
				if ctx.ModuleName() == "android_stubs_current" ||
					ctx.ModuleName() == "android_system_stubs_current" ||
					ctx.ModuleName() == "android_test_stubs_current" {
					// framework stubs.jar need to depend on framework-res.apk, in order to pull the
					// resource files out of there for aapt.
					//
					// Normally the package rule runs aapt, which includes the resource,
					// but we're not running that in our package rule so just copy in the
					// resource files here.
					deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
				}
			case kotlinStdlibTag:
				deps.kotlinStdlib = dep.HeaderJars()
			}

			deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
		case SdkLibraryDependency:
			switch tag {
			case libTag:
				linkType, _ := getLinkType(j, ctx.ModuleName())
				deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
				// names of sdk libs that are directly depended are exported
				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
			default:
				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
			}
		case android.SourceFileProducer:
			switch tag {
			case libTag:
				checkProducesJars(ctx, dep)
				deps.classpath = append(deps.classpath, dep.Srcs()...)
			case staticLibTag:
				checkProducesJars(ctx, dep)
				deps.classpath = append(deps.classpath, dep.Srcs()...)
				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
			case android.DefaultsDepTag, android.SourceDepTag:
				// Nothing to do
			default:
				ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs, or static_libs", otherName)
			}
		default:
			switch tag {
			case android.DefaultsDepTag, android.SourceDepTag:
				// Nothing to do
			case systemModulesTag:
				if deps.systemModules != nil {
					panic("Found two system module dependencies")
				}
				sm := module.(*SystemModules)
				if sm.outputFile == nil {
					panic("Missing directory for system module dependency")
				}
				deps.systemModules = sm.outputFile
			default:
				ctx.ModuleErrorf("depends on non-java module %q", otherName)
			}
		}
	})

	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)

	return deps
}

func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string {
	var ret string
	sdk, err := sdkVersionToNumber(ctx, sdkContext.sdkVersion())
	if err != nil {
		ctx.PropertyErrorf("sdk_version", "%s", err)
	}
	if javaVersion != "" {
		ret = javaVersion
	} else if ctx.Device() && sdk <= 23 {
		ret = "1.7"
	} else if ctx.Device() && sdk <= 28 || !ctx.Config().TargetOpenJDK9() {
		ret = "1.8"
	} else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel {
		// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
		ret = "1.8"
	} else {
		ret = "1.9"
	}

	return ret
}

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

	var flags javaBuilderFlags

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

	// javac flags.
	javacFlags := j.properties.Javacflags
	if flags.javaVersion == "1.9" {
		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
	}
	if ctx.Config().MinimizeJavaDebugInfo() {
		// Override the -g flag passed globally to remove local variable debug info to reduce
		// disk and memory usage.
		javacFlags = append(javacFlags, "-g:source,lines")
	}

	if ctx.Config().RunErrorProne() {
		if config.ErrorProneClasspath == nil {
			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
		}

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

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

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

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

	if j.properties.Patch_module != nil && flags.javaVersion == "1.9" {
		// Manually specify build directory in case it is not under the repo root.
		// (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
		// just adding a symlink under the root doesn't help.)
		patchPaths := ".:" + ctx.Config().BuildDir()
		classPath := flags.classpath.FormJavaClassPath("")
		if classPath != "" {
			patchPaths += ":" + classPath
		}
		javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths)
	}

	// systemModules
	if deps.systemModules != nil {
		flags.systemModules = append(flags.systemModules, deps.systemModules)
	}

	// aidl flags.
	aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
	if len(aidlFlags) > 0 {
		// optimization.
		ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
		flags.aidlFlags = "$aidlFlags"
	}

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

	return flags
}

func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path) {

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

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

	if flags.javaVersion == "1.9" {
		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
	}
	srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
	if hasSrcExt(srcFiles.Strings(), ".proto") {
		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
	}

	srcFiles = j.genSources(ctx, srcFiles, flags)

	srcJars := srcFiles.FilterByExt(".srcjar")
	srcJars = append(srcJars, deps.srcJars...)
	srcJars = append(srcJars, extraSrcJars...)

	// Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs
	// that IDEInfo struct will use
	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)

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

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

	var kotlinJars android.Paths

	if srcFiles.HasExt(".kt") {
		// user defined kotlin flags.
		kotlincFlags := j.properties.Kotlincflags
		CheckKotlincFlags(ctx, kotlincFlags)

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

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

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

		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
		TransformKotlinToClasses(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags)
		if ctx.Failed() {
			return
		}

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

		// Jar kotlin classes into the final jar after javac
		kotlinJars = append(kotlinJars, kotlinJar)
		kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
	}

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

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

	enable_sharding := false
	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
			enable_sharding = true
			if len(j.properties.Annotation_processors) != 0 ||
				len(j.properties.Annotation_processor_classes) != 0 {
				ctx.PropertyErrorf("javac_shard_size",
					"%q cannot be set when annotation processors are enabled.",
					j.properties.Javac_shard_size)
			}
		}
		j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
		if ctx.Failed() {
			return
		}
	}
	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
		var extraJarDeps android.Paths
		if ctx.Config().RunErrorProne() {
			// If error-prone is enabled, add an additional rule to compile the java files into
			// a separate set of classes (so that they don't overwrite the normal ones and require
			// a rebuild when error-prone is turned off).
			// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
			//    enable error-prone without affecting the output class files.
			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
			RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
			extraJarDeps = append(extraJarDeps, errorprone)
		}

		if enable_sharding {
			flags.classpath = append(flags.classpath, j.headerJarFile)
			shardSize := int(*(j.properties.Javac_shard_size))
			var shardSrcs []android.Paths
			if len(uniqueSrcFiles) > 0 {
				shardSrcs = shardPaths(uniqueSrcFiles, shardSize)
				for idx, shardSrc := range shardSrcs {
					classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(idx))
					TransformJavaToClasses(ctx, classes, idx, shardSrc, nil, flags, extraJarDeps)
					jars = append(jars, classes)
				}
			}
			if len(srcJars) > 0 {
				classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(len(shardSrcs)))
				TransformJavaToClasses(ctx, classes, len(shardSrcs), nil, srcJars, flags, extraJarDeps)
				jars = append(jars, classes)
			}
		} else {
			classes := android.PathForModuleOut(ctx, "javac", jarName)
			TransformJavaToClasses(ctx, classes, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
			jars = append(jars, classes)
		}
		if ctx.Failed() {
			return
		}
	}

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

	var resArgs []string
	var resDeps android.Paths

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

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

	if Bool(j.properties.Include_srcs) {
		srcArgs, srcDeps := SourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
		resArgs = append(resArgs, srcArgs...)
		resDeps = append(resDeps, srcDeps...)
	}

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

	if len(deps.staticResourceJars) > 0 {
		var jars android.Paths
		if j.resourceJar != nil {
			jars = append(jars, j.resourceJar)
		}
		jars = append(jars, deps.staticResourceJars...)

		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
			false, nil, nil)
		j.resourceJar = combinedJar
	}

	jars = append(jars, deps.staticJars...)
	jars = append(jars, deps.staticResourceJars...)

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

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

	if len(jars) == 1 && !manifest.Valid() {
		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
			// Optimization: skip the combine step if there is nothing to do
			// TODO(ccross): this leaves any module-info.class files, but those should only come from
			// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
			// any if len(jars) == 1.
			outputFile = moduleOutPath
		} else {
			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  jars[0],
				Output: combinedJar,
			})
			outputFile = combinedJar
		}
	} else {
		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
			false, nil, nil)
		outputFile = combinedJar
	}

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

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

		if ctx.Failed() {
			return
		}
	}
	j.implementationJarFile = outputFile
	if j.headerJarFile == nil {
		j.headerJarFile = j.implementationJarFile
	}

	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
		if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
			j.properties.Instrument = true
		}
	}

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

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

	j.implementationAndResourcesJar = implementationAndResourcesJar

	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
		var dexOutputFile android.ModuleOutPath
		dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
		if ctx.Failed() {
			return
		}

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

		j.dexJarFile = dexOutputFile

		dexOutputFile = j.dexpreopt(ctx, dexOutputFile)

		j.maybeStrippedDexJarFile = dexOutputFile

		outputFile = dexOutputFile

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

	ctx.CheckbuildFile(outputFile)

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

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

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

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

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

	jars = append(jars, extraJars...)

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

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

	if j.properties.Jarjar_rules != nil {
		jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
		// Transform classes.jar into classes-jarjar.jar
		jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
		TransformJarJar(ctx, jarjarFile, headerJar, jarjar_rules)
		headerJar = jarjarFile
		if ctx.Failed() {
			return nil
		}
	}

	return headerJar
}

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

	specs := j.jacocoModuleToZipCommand(ctx)

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

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

	j.jacocoReportClassesFile = jacocoReportClassesFile

	return instrumentedJar
}

var _ Dependency = (*Module)(nil)

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

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

func (j *Module) ResourceJars() android.Paths {
	if j.resourceJar == nil {
		return nil
	}
	return android.Paths{j.resourceJar}
}

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

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

func (j *Module) ExportedSdkLibs() []string {
	// exportedSdkLibs is type []string
	return j.exportedSdkLibs
}

var _ logtagsProducer = (*Module)(nil)

func (j *Module) logtags() android.Paths {
	return j.logtagsSrcs
}

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

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

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

type Library struct {
	Module
}

func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
	j.compile(ctx)

	if Bool(j.properties.Installable) || ctx.Host() {
		if j.deviceProperties.UncompressDex {
			alignedOutputFile := android.PathForModuleOut(ctx, "aligned", ctx.ModuleName()+".jar")
			TransformZipAlign(ctx, alignedOutputFile, j.outputFile)
			j.outputFile = alignedOutputFile
		}

		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
			ctx.ModuleName()+".jar", j.outputFile)
	}
}

func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.deps(ctx)
}

func LibraryFactory() android.Module {
	module := &Library{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.deviceProperties,
		&module.Module.dexpreoptProperties,
		&module.Module.protoProperties)

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

func LibraryHostFactory() android.Module {
	module := &Library{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.protoProperties)

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

	InitJavaModule(module, android.HostSupported)
	return module
}

//
// Java Tests
//

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

	// list of files or filegroup modules that provide data that should be installed alongside
	// the test
	Data []string
}

type Test struct {
	Library

	testProperties testProperties

	testConfig android.Path
	data       android.Paths
}

func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template)
	j.data = ctx.ExpandSources(j.testProperties.Data, nil)

	j.Library.GenerateAndroidBuildActions(ctx)
}

func (j *Test) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.deps(ctx)
	android.ExtractSourceDeps(ctx, j.testProperties.Test_config)
	android.ExtractSourceDeps(ctx, j.testProperties.Test_config_template)
	android.ExtractSourcesDeps(ctx, j.testProperties.Data)
}

func TestFactory() android.Module {
	module := &Test{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.deviceProperties,
		&module.Module.dexpreoptProperties,
		&module.Module.protoProperties,
		&module.testProperties)

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

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

func TestHostFactory() android.Module {
	module := &Test{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.protoProperties,
		&module.testProperties)

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

	InitJavaModule(module, android.HostSupported)
	return module
}

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

type binaryProperties struct {
	// installable script to execute the resulting jar
	Wrapper *string

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

type Binary struct {
	Library

	binaryProperties binaryProperties

	isWrapperVariant bool

	wrapperFile android.Path
	binaryFile  android.OutputPath
}

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

func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if ctx.Arch().ArchType == android.Common {
		// 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)
	} else {
		// Handle the binary wrapper
		j.isWrapperVariant = true

		if j.binaryProperties.Wrapper != nil {
			j.wrapperFile = ctx.ExpandSource(*j.binaryProperties.Wrapper, "wrapper")
		} else {
			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
		}

		// Depend on the installed jar so that the wrapper doesn't get executed by
		// another build rule before the jar has been installed.
		jarFile := ctx.PrimaryModule().(*Binary).installFile

		j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
			ctx.ModuleName(), j.wrapperFile, jarFile)
	}
}

func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
	if ctx.Arch().ArchType == android.Common {
		j.deps(ctx)
	} else {
		android.ExtractSourceDeps(ctx, j.binaryProperties.Wrapper)
	}
}

func BinaryFactory() android.Module {
	module := &Binary{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.deviceProperties,
		&module.Module.dexpreoptProperties,
		&module.Module.protoProperties,
		&module.binaryProperties)

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

	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
	android.InitDefaultableModule(module)
	return module
}

func BinaryHostFactory() android.Module {
	module := &Binary{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.protoProperties,
		&module.binaryProperties)

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

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

//
// Java prebuilts
//

type ImportProperties struct {
	Jars []string

	Sdk_version *string

	Installable *bool

	// List of shared java libs that this module has dependencies to
	Libs []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_enabled *bool
}

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

	properties ImportProperties

	combinedClasspathFile android.Path
	exportedSdkLibs       []string
}

func (j *Import) sdkVersion() string {
	return String(j.properties.Sdk_version)
}

func (j *Import) minSdkVersion() string {
	return j.sdkVersion()
}

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

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

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

func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
	android.ExtractSourcesDeps(ctx, j.properties.Jars)
	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
}

func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	jars := ctx.ExpandSources(j.properties.Jars, nil)

	jarName := ctx.ModuleName() + ".jar"
	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
	TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
	if Bool(j.properties.Jetifier_enabled) {
		inputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
		TransformJetifier(ctx, outputFile, inputFile)
	}
	j.combinedClasspathFile = outputFile

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

		switch dep := module.(type) {
		case Dependency:
			switch tag {
			case libTag, staticLibTag:
				// sdk lib names from dependencies are re-exported
				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
			}
		case SdkLibraryDependency:
			switch tag {
			case libTag:
				// names of sdk libs that are directly depended are exported
				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
			}
		}
	})

	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
	if Bool(j.properties.Installable) {
		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
			ctx.ModuleName()+".jar", outputFile)
	}
}

var _ Dependency = (*Import)(nil)

func (j *Import) HeaderJars() android.Paths {
	if j.combinedClasspathFile == nil {
		return nil
	}
	return android.Paths{j.combinedClasspathFile}
}

func (j *Import) ImplementationJars() android.Paths {
	if j.combinedClasspathFile == nil {
		return nil
	}
	return android.Paths{j.combinedClasspathFile}
}

func (j *Import) ResourceJars() android.Paths {
	return nil
}

func (j *Import) ImplementationAndResourcesJars() android.Paths {
	if j.combinedClasspathFile == nil {
		return nil
	}
	return android.Paths{j.combinedClasspathFile}
}

func (j *Import) AidlIncludeDirs() android.Paths {
	return nil
}

func (j *Import) ExportedSdkLibs() []string {
	return j.exportedSdkLibs
}

// 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.
const (
	removedPrefix = "prebuilt_"
)

func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
	dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
}

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.
	name := j.Name()
	if strings.HasPrefix(name, removedPrefix) {
		name = strings.TrimPrefix(name, removedPrefix)
	}
	return name
}

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

func ImportFactory() android.Module {
	module := &Import{}

	module.AddProperties(&module.properties)

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

func ImportFactoryHost() android.Module {
	module := &Import{}

	module.AddProperties(&module.properties)

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

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

func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}

func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
}

func defaultsFactory() android.Module {
	return DefaultsFactory()
}

func DefaultsFactory(props ...interface{}) android.Module {
	module := &Defaults{}

	module.AddProperties(props...)
	module.AddProperties(
		&CompilerProperties{},
		&CompilerDeviceProperties{},
		&DexpreoptProperties{},
		&android.ProtoProperties{},
		&aaptProperties{},
		&androidLibraryProperties{},
		&appProperties{},
		&appTestProperties{},
		&ImportProperties{},
		&AARImportProperties{},
		&sdkLibraryProperties{},
	)

	android.InitDefaultsModule(module)

	return module
}

var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
var inList = android.InList
