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

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

	android.RegisterModuleType("java_library", LibraryFactory(true))
	android.RegisterModuleType("java_library_static", LibraryFactory(false))
	android.RegisterModuleType("java_library_host", LibraryHostFactory)
	android.RegisterModuleType("java_binary", BinaryFactory)
	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
	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
	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 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 false, don't allow this module to be installed.  Defaults to true.
	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

	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
	}

	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
	}

	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
	Sdk_version *string

	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
	}

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

	Dex_preopt struct {
		// If false, prevent dexpreopting and stripping the dex file from the final jar.  Defaults to
		// true.
		Enabled *bool

		// If true, generate an app image (.art file) for this module.
		App_image *bool

		// If true, use a checked-in profile to guide optimization.  Defaults to false unless
		// a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR
		// that matches the name of this module, in which case it is defaulted to true.
		Profile_guided *bool

		// If set, provides the path to profile relative to the Android.bp file.  If not set,
		// defaults to searching for a file that matches the name of this module in the default
		// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
		Profile *string
	}

	Optimize struct {
		// If false, disable all optimization.  Defaults to true for apps, false for
		// libraries and tests.
		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
}

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

	// header jar file suitable for inserting into the bootclasspath/classpath of another compile
	headerJarFile android.Path

	// full implementation jar file suitable for static dependency of another module compile
	implementationJarFile android.Path

	// output file containing classes.dex
	dexJarFile 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 suitable for installing or running
	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
}

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

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

type Dependency interface {
	HeaderJars() android.Paths
	ImplementationJars() android.Paths
	AidlIncludeDirs() android.Paths
}

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

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string
}

var (
	staticLibTag     = dependencyTag{name: "staticlib"}
	libTag           = dependencyTag{name: "javalib"}
	bootClasspathTag = dependencyTag{name: "bootclasspath"}
	systemModulesTag = dependencyTag{name: "system modules"}
	frameworkResTag  = dependencyTag{name: "framework-res"}
	kotlinStdlibTag  = dependencyTag{name: "kotlin-stdlib"}
	proguardRaiseTag = dependencyTag{name: "proguard-raise"}
)

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

	module        string
	systemModules string

	jar  android.Path
	aidl android.Path
}

func sdkStringToNumber(ctx android.BaseContext, v string) int {
	switch v {
	case "", "current", "system_current", "test_current":
		return 10000
	default:
		if i, err := strconv.Atoi(android.GetNumericSdkVersion(v)); err != nil {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version")
			return -1
		} else {
			return i
		}
	}
}

func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
	i := sdkStringToNumber(ctx, v)
	if i == -1 {
		// Invalid sdk version, error handled by sdkStringToNumber.
		return sdkDep{}
	}

	toFile := func(v string) sdkDep {
		dir := filepath.Join("prebuilts/sdk", v)
		jar := filepath.Join(dir, "android.jar")
		aidl := filepath.Join(dir, "framework.aidl")
		jarPath := android.ExistentPathForSource(ctx, "sdkdir", jar)
		aidlPath := android.ExistentPathForSource(ctx, "sdkdir", aidl)

		if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
			if strings.Contains(v, "system_") {
				return sdkDep{
					invalidVersion: true,
					module:         "vsdk_v" + strings.Replace(v, "system_", "", 1),
				}
			}
			return sdkDep{
				invalidVersion: true,
				module:         "sdk_v" + 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,
			jar:      jarPath.Path(),
			aidl:     aidlPath.Path(),
		}
	}

	//toModule := func(m string) sdkDep {
	//	return sdkDep{
	//		useModule:     true,
	//		module:        m,
	//		systemModules: m + "_system_modules",
	//	}
	//}

	if ctx.Config().UnbundledBuild() && v != "" {
		return toFile(v)
	}

	switch v {
	case "":
		return sdkDep{
			useDefaultLibs: true,
		}
	// TODO(ccross): re-enable these once we generate stubs, until then
	// use the stubs in prebuilts/sdk/*current
	//case "current":
	//	return toModule("android_stubs_current")
	//case "system_current":
	//	return toModule("android_system_stubs_current")
	//case "test_current":
	//	return toModule("android_test_stubs_current")
	default:
		return toFile(v)
	}
}

func (j *Module) deps(ctx android.BottomUpMutatorContext) {
	if ctx.Device() {
		if !proptools.Bool(j.properties.No_standard_libs) {
			sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version))
			if sdkDep.useDefaultLibs {
				ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
				if ctx.Config().TargetOpenJDK9() {
					ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
				}
				if !proptools.Bool(j.properties.No_framework_libs) {
					ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
				}
			} else if sdkDep.useModule {
				if ctx.Config().TargetOpenJDK9() {
					ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
				}
				ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
				if Bool(j.deviceProperties.Optimize.Enabled) {
					ctx.AddDependency(ctx.Module(), proguardRaiseTag, config.DefaultBootclasspathLibraries...)
					ctx.AddDependency(ctx.Module(), 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.Config().TargetOpenJDK9() {
			ctx.AddDependency(ctx.Module(), systemModulesTag, *j.deviceProperties.System_modules)
		}
		if ctx.ModuleName() == "framework" {
			ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
		}
	}

	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
	ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
	ctx.AddDependency(ctx.Module(), libTag, j.properties.Annotation_processors...)

	android.ExtractSourcesDeps(ctx, j.properties.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.AddDependency(ctx.Module(), kotlinStdlibTag, "kotlin-stdlib")
	}
}

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

	var flags []string
	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())
	}

	return flags
}

type deps struct {
	classpath          android.Paths
	bootClasspath      android.Paths
	staticJars         android.Paths
	staticHeaderJars   android.Paths
	staticJarResources android.Paths
	aidlIncludeDirs    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)))
		}
	}
}

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

	sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version))
	if sdkDep.invalidVersion {
		ctx.AddMissingDependencies([]string{sdkDep.module})
	} else if sdkDep.useFiles {
		// sdkDep.jar is actually equivalent to turbine header.jar.
		deps.classpath = append(deps.classpath, sdkDep.jar)
		deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
	}

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

		switch dep := module.(type) {
		case Dependency:
			switch tag {
			case bootClasspathTag:
				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
			case libTag:
				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
			case staticLibTag:
				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
			case frameworkResTag:
				if ctx.ModuleName() == "framework" {
					// 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 kotlinStdlibTag:
				deps.kotlinStdlib = dep.HeaderJars()
			default:
				panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
			}

			deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
		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)
			}
		}
	})

	return deps
}

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

	var flags javaBuilderFlags

	// javac flags.
	javacFlags := j.properties.Javacflags
	if ctx.Config().TargetOpenJDK9() {
		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 len(javacFlags) > 0 {
		// optimization.
		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
		flags.javacFlags = "$javacFlags"
	}

	// javaVersion flag.
	sdk := sdkStringToNumber(ctx, String(j.deviceProperties.Sdk_version))
	if j.properties.Java_version != nil {
		flags.javaVersion = *j.properties.Java_version
	} else if ctx.Device() && sdk <= 23 {
		flags.javaVersion = "1.7"
	} else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
		flags.javaVersion = "1.8"
	} else if ctx.Device() && String(j.deviceProperties.Sdk_version) != "" && sdk == 10000 {
		// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
		flags.javaVersion = "1.8"
	} else {
		flags.javaVersion = "1.9"
	}

	// classpath
	flags.bootClasspath.AddPaths(deps.bootClasspath)
	flags.classpath.AddPaths(deps.classpath)

	if len(flags.bootClasspath) == 0 && ctx.Host() && !ctx.Config().TargetOpenJDK9() &&
		!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"))
	}

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

	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 ctx.Config().TargetOpenJDK9() {
		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...)

	var jars android.Paths

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

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

		flags.kotlincFlags = "-no-stdlib"
		if ctx.Device() {
			flags.kotlincFlags += " -no-jdk"
		}

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

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

		// Make javac rule depend on the kotlinc rule
		flags.classpath = append(flags.classpath, kotlinJar)
		// Jar kotlin classes into the final jar after javac
		jars = append(jars, kotlinJar)
		jars = append(jars, deps.kotlinStdlib...)
	}

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

	// 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)
			}
		}
		// If sdk jar is java module, then directly return classesJar as header.jar
		if j.Name() != "android_stubs_current" && j.Name() != "android_system_stubs_current" &&
			j.Name() != "android_test_stubs_current" {
			j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName)
			if ctx.Failed() {
				return
			}
		}
	}
	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
		var extraJarDeps android.Paths
		if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") {
			// 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.AddPaths([]android.Path{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)
	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 proptools.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)
		if ctx.Failed() {
			return
		}

		jars = append(jars, resourceJar)
	}

	// static classpath jars have the resources in them, so the resource jars aren't necessary here
	jars = append(jars, deps.staticJars...)

	var manifest android.OptionalPath
	if 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.Path

	if len(jars) == 1 && !manifest.Valid() {
		// 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 = jars[0]
	} else {
		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest, false, nil)
		outputFile = 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, "jarjar", jarName)
		TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules)
		outputFile = jarjarFile
		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 ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && j.properties.Instrument {
		outputFile = j.instrument(ctx, flags, outputFile, jarName)
	}

	if ctx.Device() && j.installable() {
		outputFile = j.compileDex(ctx, flags, outputFile, jarName)
		if ctx.Failed() {
			return
		}
	}
	ctx.CheckbuildFile(outputFile)
	j.outputFile = outputFile
}

func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
	deps deps, flags javaBuilderFlags, jarName string) 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)
	}

	// 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, []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.Path {

	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
}

// Returns a sdk version as a string that is guaranteed to be a parseable as a number.  For
// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns "10000".
func (j *Module) minSdkVersionNumber(ctx android.ModuleContext) string {
	switch String(j.deviceProperties.Sdk_version) {
	case "", "current", "test_current", "system_current":
		return strconv.Itoa(ctx.Config().DefaultAppTargetSdkInt())
	default:
		return android.GetNumericSdkVersion(String(j.deviceProperties.Sdk_version))
	}
}

func (j *Module) installable() bool {
	return j.properties.Installable == nil || *j.properties.Installable
}

var _ Dependency = (*Library)(nil)

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

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

func (j *Module) AidlIncludeDirs() android.Paths {
	return j.exportAidlIncludeDirs
}

var _ logtagsProducer = (*Module)(nil)

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

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

type Library struct {
	Module
}

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

	if j.installable() {
		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(installable bool) func() android.Module {
	return func() android.Module {
		module := &Library{}

		if !installable {
			module.properties.Installable = proptools.BoolPtr(false)
		}

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

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

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

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

	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
}

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
		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.protoProperties,
		&module.binaryProperties)

	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.deviceProperties,
		&module.Module.protoProperties,
		&module.binaryProperties)

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

//
// Java prebuilts
//

type ImportProperties struct {
	Jars []string

	Sdk_version *string

	Installable *bool
}

type Import struct {
	android.ModuleBase
	prebuilt android.Prebuilt

	properties ImportProperties

	classpathFiles        android.Paths
	combinedClasspathFile android.Path
}

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

func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)

	outputFile := android.PathForModuleOut(ctx, "classes.jar")
	TransformJarsToJar(ctx, outputFile, "for prebuilts", j.classpathFiles, android.OptionalPath{}, false, nil)
	j.combinedClasspathFile = outputFile
}

var _ Dependency = (*Import)(nil)

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

func (j *Import) ImplementationJars() android.Paths {
	return j.classpathFiles
}

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

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

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

	module.AddProperties(&module.properties)

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

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

	module.AddProperties(&module.properties)

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

func inList(s string, l []string) bool {
	for _, e := range l {
		if e == s {
			return true
		}
	}
	return false
}

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

	android.InitDefaultsModule(module)

	return module
}

var Bool = proptools.Bool
var String = proptools.String
