// Copyright 2021 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package java

import (
	"fmt"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/java/config"
	"android/soong/remoteexec"
)

// The values allowed for Droidstubs' Api_levels_sdk_type
var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}

type StubsType int

const (
	Everything StubsType = iota
	Runtime
	Exportable
	Unavailable
)

func (s StubsType) String() string {
	switch s {
	case Everything:
		return "everything"
	case Runtime:
		return "runtime"
	case Exportable:
		return "exportable"
	default:
		return ""
	}
}

func StringToStubsType(s string) StubsType {
	switch strings.ToLower(s) {
	case Everything.String():
		return Everything
	case Runtime.String():
		return Runtime
	case Exportable.String():
		return Exportable
	default:
		return Unavailable
	}
}

func init() {
	RegisterStubsBuildComponents(android.InitRegistrationContext)
}

func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)

	ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
	ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)

	ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
}

type stubsArtifacts struct {
	nullabilityWarningsFile android.WritablePath
	annotationsZip          android.WritablePath
	apiVersionsXml          android.WritablePath
	metadataZip             android.WritablePath
	metadataDir             android.WritablePath
}

// Droidstubs
type Droidstubs struct {
	Javadoc
	embeddableInModuleAndImport

	properties     DroidstubsProperties
	apiFile        android.Path
	removedApiFile android.Path

	checkCurrentApiTimestamp      android.WritablePath
	updateCurrentApiTimestamp     android.WritablePath
	checkLastReleasedApiTimestamp android.WritablePath
	apiLintTimestamp              android.WritablePath
	apiLintReport                 android.WritablePath

	checkNullabilityWarningsTimestamp android.WritablePath

	everythingArtifacts stubsArtifacts
	exportableArtifacts stubsArtifacts

	exportableApiFile        android.WritablePath
	exportableRemovedApiFile android.WritablePath
}

type DroidstubsProperties struct {
	// The generated public API filename by Metalava, defaults to <module>_api.txt
	Api_filename *string

	// the generated removed API filename by Metalava, defaults to <module>_removed.txt
	Removed_api_filename *string

	Check_api struct {
		Last_released ApiToCheck

		Current ApiToCheck

		Api_lint struct {
			Enabled *bool

			// If set, performs api_lint on any new APIs not found in the given signature file
			New_since *string `android:"path"`

			// If not blank, path to the baseline txt file for approved API lint violations.
			Baseline_file *string `android:"path"`
		}
	}

	// user can specify the version of previous released API file in order to do compatibility check.
	Previous_api *string `android:"path"`

	// is set to true, Metalava will allow framework SDK to contain annotations.
	Annotations_enabled *bool

	// a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
	Merge_annotations_dirs []string

	// a list of top-level directories containing Java stub files to merge show/hide annotations from.
	Merge_inclusion_annotations_dirs []string

	// a file containing a list of classes to do nullability validation for.
	Validate_nullability_from_list *string

	// a file containing expected warnings produced by validation of nullability annotations.
	Check_nullability_warnings *string

	// if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
	Create_doc_stubs *bool

	// if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
	// Has no effect if create_doc_stubs: true.
	Output_javadoc_comments *bool

	// if set to false then do not write out stubs. Defaults to true.
	//
	// TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
	Generate_stubs *bool

	// if set to true, provides a hint to the build system that this rule uses a lot of memory,
	// which can be used for scheduling purposes
	High_mem *bool

	// if set to true, Metalava will allow framework SDK to contain API levels annotations.
	Api_levels_annotations_enabled *bool

	// Apply the api levels database created by this module rather than generating one in this droidstubs.
	Api_levels_module *string

	// the dirs which Metalava extracts API levels annotations from.
	Api_levels_annotations_dirs []string

	// the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system', 'module-lib' and 'system-server'; defaults to public.
	Api_levels_sdk_type *string

	// the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
	Api_levels_jar_filename *string

	// if set to true, collect the values used by the Dev tools and
	// write them in files packaged with the SDK. Defaults to false.
	Write_sdk_values *bool

	// path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
	// what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
	Extensions_info_file *string `android:"path"`

	// API surface of this module. If set, the module contributes to an API surface.
	// For the full list of available API surfaces, refer to soong/android/sdk_version.go
	Api_surface *string

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

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

// Used by xsd_config
type ApiFilePath interface {
	ApiFilePath(StubsType) (android.Path, error)
}

type ApiStubsSrcProvider interface {
	StubsSrcJar(StubsType) (android.Path, error)
}

// Provider of information about API stubs, used by java_sdk_library.
type ApiStubsProvider interface {
	AnnotationsZip(StubsType) (android.Path, error)
	ApiFilePath
	RemovedApiFilePath(StubsType) (android.Path, error)

	ApiStubsSrcProvider
}

type currentApiTimestampProvider interface {
	CurrentApiTimestamp() android.Path
}

type annotationFlagsParams struct {
	migratingNullability    bool
	validatingNullability   bool
	nullabilityWarningsFile android.WritablePath
	annotationsZip          android.WritablePath
}
type stubsCommandParams struct {
	srcJarDir               android.ModuleOutPath
	stubsDir                android.OptionalPath
	stubsSrcJar             android.WritablePath
	metadataZip             android.WritablePath
	metadataDir             android.WritablePath
	apiVersionsXml          android.WritablePath
	nullabilityWarningsFile android.WritablePath
	annotationsZip          android.WritablePath
	stubConfig              stubsCommandConfigParams
}
type stubsCommandConfigParams struct {
	stubsType             StubsType
	javaVersion           javaVersion
	deps                  deps
	checkApi              bool
	generateStubs         bool
	doApiLint             bool
	doCheckReleased       bool
	writeSdkValues        bool
	migratingNullability  bool
	validatingNullability bool
}

// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
// documented, filtering out hidden classes and methods.  The resulting .java files are intended to be passed to
// a droiddoc module to generate documentation.
func DroidstubsFactory() android.Module {
	module := &Droidstubs{}

	module.AddProperties(&module.properties,
		&module.Javadoc.properties)
	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
	module.initModuleAndImport(module)

	InitDroiddocModule(module, android.HostAndDeviceSupported)

	module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
		module.createApiContribution(ctx)
	})
	return module
}

// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
// to be documented, filtering out hidden classes and methods.  The resulting .java files are intended to be
// passed to a droiddoc_host module to generate documentation.  Use a droidstubs_host instead of a droidstubs
// module when symbols needed by the source files are provided by java_library_host modules.
func DroidstubsHostFactory() android.Module {
	module := &Droidstubs{}

	module.AddProperties(&module.properties,
		&module.Javadoc.properties)

	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
	InitDroiddocModule(module, android.HostSupported)
	return module
}

func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.everythingArtifacts.annotationsZip, nil
	case Exportable:
		ret, err = d.exportableArtifacts.annotationsZip, nil
	default:
		ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.apiFile, nil
	case Exportable:
		ret, err = d.exportableApiFile, nil
	default:
		ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
	}
	if ret == nil && err == nil {
		err = fmt.Errorf("api file is null for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.everythingArtifacts.apiVersionsXml, nil
	case Exportable:
		ret, err = d.exportableArtifacts.apiVersionsXml, nil
	default:
		ret, err = nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
	}
	if ret == nil && err == nil {
		err = fmt.Errorf("api versions xml file is null for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) DocZip(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.docZip, nil
	default:
		ret, err = nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
	}
	if ret == nil && err == nil {
		err = fmt.Errorf("docs zip is null for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.removedApiFile, nil
	case Exportable:
		ret, err = d.exportableRemovedApiFile, nil
	default:
		ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
	}
	if ret == nil && err == nil {
		err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
	switch stubsType {
	case Everything:
		ret, err = d.stubsSrcJar, nil
	case Exportable:
		ret, err = d.exportableStubsSrcJar, nil
	default:
		ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
	}
	if ret == nil && err == nil {
		err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
	}
	return ret, err
}

func (d *Droidstubs) CurrentApiTimestamp() android.Path {
	return d.checkCurrentApiTimestamp
}

var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}

func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
	d.Javadoc.addDeps(ctx)

	if len(d.properties.Merge_annotations_dirs) != 0 {
		for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
			ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
		}
	}

	if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
		for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
			ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
		}
	}

	if len(d.properties.Api_levels_annotations_dirs) != 0 {
		for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
			ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
		}
	}

	if len(d.properties.Aconfig_declarations) != 0 {
		for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
			ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
		}
	}

	if d.properties.Api_levels_module != nil {
		ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
	}
}

func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
	cmd.FlagWithArg("--sdk-values ", metadataDir.String())
}

func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {

	apiFileName := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
	uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), apiFileName)
	cmd.FlagWithOutput("--api ", uncheckedApiFile)
	if checkApi || String(d.properties.Api_filename) != "" {
		if stubsType == Everything {
			d.apiFile = uncheckedApiFile
		} else if stubsType == Exportable {
			d.exportableApiFile = uncheckedApiFile
		}
	} else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
		if stubsType == Everything {
			// If check api is disabled then make the source file available for export.
			d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
		} else if stubsType == Exportable {
			d.exportableApiFile = uncheckedApiFile
		}
	}

	removedApiFileName := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
	uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), removedApiFileName)
	cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
	if checkApi || String(d.properties.Removed_api_filename) != "" {
		if stubsType == Everything {
			d.removedApiFile = uncheckedRemovedFile
		} else if stubsType == Exportable {
			d.exportableRemovedApiFile = uncheckedRemovedFile
		}
	} else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
		if stubsType == Everything {
			// If check api is disabled then make the source removed api file available for export.
			d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
		} else if stubsType == Exportable {
			d.exportableRemovedApiFile = uncheckedRemovedFile
		}
	}

	if stubsDir.Valid() {
		if Bool(d.properties.Create_doc_stubs) {
			cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
		} else {
			cmd.FlagWithArg("--stubs ", stubsDir.String())
			if !Bool(d.properties.Output_javadoc_comments) {
				cmd.Flag("--exclude-documentation-from-stubs")
			}
		}
	}
}

func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
	if Bool(d.properties.Annotations_enabled) {
		cmd.Flag(config.MetalavaAnnotationsFlags)

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

		if s := String(d.properties.Validate_nullability_from_list); s != "" {
			cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
		}

		if params.validatingNullability {
			cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
		}

		cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)

		if len(d.properties.Merge_annotations_dirs) != 0 {
			d.mergeAnnoDirFlags(ctx, cmd)
		}

		cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
	}
}

func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
	ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
		if t, ok := m.(*ExportedDroiddocDir); ok {
			cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
		} else {
			ctx.PropertyErrorf("merge_annotations_dirs",
				"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
		}
	})
}

func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
	ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
		if t, ok := m.(*ExportedDroiddocDir); ok {
			cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
		} else {
			ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
				"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
		}
	})
}

func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
	var apiVersions android.Path
	if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
		d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
		apiVersions = apiVersionsXml
	} else {
		ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
			if s, ok := m.(*Droidstubs); ok {
				if stubsType == Everything {
					apiVersions = s.everythingArtifacts.apiVersionsXml
				} else if stubsType == Exportable {
					apiVersions = s.exportableArtifacts.apiVersionsXml
				} else {
					ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
				}
			} else {
				ctx.PropertyErrorf("api_levels_module",
					"module %q is not a droidstubs module", ctx.OtherModuleName(m))
			}
		})
	}
	if apiVersions != nil {
		cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
		cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
		cmd.FlagWithInput("--apply-api-levels ", apiVersions)
	}
}

// AndroidPlusUpdatableJar is the name of some extra jars added into `module-lib` and
// `system-server` directories that contain all the APIs provided by the platform and updatable
// modules because the `android.jar` files do not. See b/337836752.
const AndroidPlusUpdatableJar = "android-plus-updatable.jar"

func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
	if len(d.properties.Api_levels_annotations_dirs) == 0 {
		ctx.PropertyErrorf("api_levels_annotations_dirs",
			"has to be non-empty if api levels annotations was enabled!")
	}

	cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)

	filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")

	// TODO: Avoid the duplication of API surfaces, reuse apiScope.
	// Add all relevant --android-jar-pattern patterns for Metalava.
	// When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
	// an actual file present on disk (in the order the patterns were passed). For system APIs for
	// privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
	// for older releases. Similarly, module-lib falls back to system API.
	var sdkDirs []string
	apiLevelsSdkType := proptools.StringDefault(d.properties.Api_levels_sdk_type, "public")
	switch apiLevelsSdkType {
	case "system-server":
		sdkDirs = []string{"system-server", "module-lib", "system", "public"}
	case "module-lib":
		sdkDirs = []string{"module-lib", "system", "public"}
	case "system":
		sdkDirs = []string{"system", "public"}
	case "public":
		sdkDirs = []string{"public"}
	default:
		ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
		return
	}

	// Construct a pattern to match the appropriate extensions that should be included in the
	// generated api-versions.xml file.
	//
	// Use the first item in the sdkDirs array as that is the sdk type for the target API levels
	// being generated but has the advantage over `Api_levels_sdk_type` as it has been validated.
	// The exception is for system-server which needs to include module-lib and system-server. That
	// is because while system-server extends module-lib the system-server extension directory only
	// contains service-* modules which provide system-server APIs it does not list the modules which
	// only provide a module-lib, so they have to be included separately.
	extensionSurfacesPattern := sdkDirs[0]
	if apiLevelsSdkType == "system-server" {
		// Take the first two items in sdkDirs, which are system-server and module-lib, and construct
		// a pattern that will match either.
		extensionSurfacesPattern = strings.Join(sdkDirs[0:2], "|")
	}
	extensionsPattern := fmt.Sprintf(`/extensions/[0-9]+/(%s)/.*\.jar`, extensionSurfacesPattern)

	var dirs []string
	var extensions_dir string
	ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
		if t, ok := m.(*ExportedDroiddocDir); ok {
			extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern)

			// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
			// ideally this should be read from prebuiltApis.properties.Extensions_*
			for _, dep := range t.deps {
				// Check to see if it matches an extension first.
				depBase := dep.Base()
				if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
					if extensions_dir == "" {
						extensions_dir = t.dir.String() + "/extensions"
					}
					cmd.Implicit(dep)
				} else if depBase == filename {
					// Check to see if it matches a dessert release for an SDK, e.g. Android, Car, Wear, etc..
					cmd.Implicit(dep)
				} else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
					// The output api-versions.xml has been requested to include information on SDK
					// extensions. That means it also needs to include
					// so
					// The module-lib and system-server directories should use `android-plus-updatable.jar`
					// instead of `android.jar`. See AndroidPlusUpdatableJar for more information.
					cmd.Implicit(dep)
				} else if filename != "android.jar" && depBase == "android.jar" {
					// Metalava implicitly searches these patterns:
					//  prebuilts/tools/common/api-versions/android-%/android.jar
					//  prebuilts/sdk/%/public/android.jar
					// Add android.jar files from the api_levels_annotations_dirs directories to try
					// to satisfy these patterns.  If Metalava can't find a match for an API level
					// between 1 and 28 in at least one pattern it will fail.
					cmd.Implicit(dep)
				}
			}

			dirs = append(dirs, t.dir.String())
		} else {
			ctx.PropertyErrorf("api_levels_annotations_dirs",
				"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
		}
	})

	// Generate the list of --android-jar-pattern options. The order matters so the first one which
	// matches will be the one that is used for a specific api level..
	for _, sdkDir := range sdkDirs {
		for _, dir := range dirs {
			addPattern := func(jarFilename string) {
				cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
			}

			if sdkDir == "module-lib" || sdkDir == "system-server" {
				// The module-lib and system-server android.jars do not include the updatable modules (as
				// doing so in the source would introduce dependency cycles and the prebuilts have to
				// match the sources). So, instead an additional `android-plus-updatable.jar` will be used
				// that does include the updatable modules and this pattern will match that. This pattern
				// is added in addition to the following pattern to decouple this change from the change
				// to add the `android-plus-updatable.jar`.
				addPattern(AndroidPlusUpdatableJar)
			}

			addPattern(filename)
		}
	}

	if d.properties.Extensions_info_file != nil {
		if extensions_dir == "" {
			ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
		}
		info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
		cmd.Implicit(info_file)
		cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
		cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
	}
}

func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType) {
	if len(d.Javadoc.properties.Out) > 0 {
		ctx.PropertyErrorf("out", "out property may not be combined with check_api")
	}

	apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)})
	removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)})

	cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles)
	cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles)

	baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
	if baselineFile.Valid() {
		cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
	}
}

func metalavaUseRbe(ctx android.ModuleContext) bool {
	return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
}

func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
	srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams, configFiles android.Paths) *android.RuleBuilderCommand {
	rule.Command().Text("rm -rf").Flag(homeDir.String())
	rule.Command().Text("mkdir -p").Flag(homeDir.String())

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

	if metalavaUseRbe(ctx) {
		rule.Remoteable(android.RemoteRuleSupports{RBE: true})
		execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
		compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
		remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
		labels := map[string]string{"type": "tool", "name": "metalava"}
		// TODO: metalava pool rejects these jobs
		pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
		rule.Rewrapper(&remoteexec.REParams{
			Labels:              labels,
			ExecStrategy:        execStrategy,
			ToolchainInputs:     []string{config.JavaCmd(ctx).String()},
			Platform:            map[string]string{remoteexec.PoolKey: pool},
			Compare:             compare,
			NumLocalRuns:        1,
			NumRemoteRuns:       1,
			NoRemoteUpdateCache: !remoteUpdateCache,
		})
	}

	cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
		Flag(config.JavacVmFlags).
		Flag(config.MetalavaAddOpens).
		FlagWithArg("--java-source ", params.javaVersion.String()).
		FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, fmt.Sprintf("%s.metalava.rsp", params.stubsType.String())), srcs).
		FlagWithInput("@", srcJarList)

	// Metalava does not differentiate between bootclasspath and classpath and has not done so for
	// years, so it is unlikely to change any time soon.
	combinedPaths := append(([]android.Path)(nil), params.deps.bootClasspath.Paths()...)
	combinedPaths = append(combinedPaths, params.deps.classpath.Paths()...)
	if len(combinedPaths) > 0 {
		cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
	}

	cmd.Flag(config.MetalavaFlags)

	addMetalavaConfigFilesToCmd(cmd, configFiles)

	return cmd
}

// MetalavaConfigFilegroup is the name of the filegroup in build/soong/java/metalava that lists
// the configuration files to pass to Metalava.
const MetalavaConfigFilegroup = "metalava-config-files"

// Get a reference to the MetalavaConfigFilegroup suitable for use in a property.
func getMetalavaConfigFilegroupReference() []string {
	return []string{":" + MetalavaConfigFilegroup}
}

// addMetalavaConfigFilesToCmd adds --config-file options to use the config files list in the
// MetalavaConfigFilegroup filegroup.
func addMetalavaConfigFilesToCmd(cmd *android.RuleBuilderCommand, configFiles android.Paths) {
	cmd.FlagForEachInput("--config-file ", configFiles)
}

// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
// property is defined, apply transformations and only revert the flagged apis that are not
// enabled via release configurations and are not specified in aconfig_declarations
func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {

	if len(aconfigFlagsPaths) == 0 {
		cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
		return
	}

	releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
	revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))

	var filterArgs string
	switch stubsType {
	// No flagged apis specific flags need to be passed to metalava when generating
	// everything stubs
	case Everything:
		return

	case Runtime:
		filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"

	case Exportable:
		// When the build flag RELEASE_EXPORT_RUNTIME_APIS is set to true, apis marked with
		// the flagged apis that have read_write permissions are exposed on top of the enabled
		// and read_only apis. This is to support local override of flag values at runtime.
		if ctx.Config().ReleaseExportRuntimeApis() {
			filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
		} else {
			filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
		}
	}

	ctx.Build(pctx, android.BuildParams{
		Rule:        gatherReleasedFlaggedApisRule,
		Inputs:      aconfigFlagsPaths,
		Output:      releasedFlaggedApisFile,
		Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
		Args: map[string]string{
			"flags_path":  android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
			"filter_args": filterArgs,
		},
	})

	ctx.Build(pctx, android.BuildParams{
		Rule:        generateMetalavaRevertAnnotationsRule,
		Input:       releasedFlaggedApisFile,
		Output:      revertAnnotationsFile,
		Description: fmt.Sprintf("%s revert annotations", stubsType),
	})

	cmd.FlagWithInput("@", revertAnnotationsFile)
}

func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
	params stubsCommandParams) *android.RuleBuilderCommand {
	if BoolDefault(d.properties.High_mem, false) {
		// This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
		rule.HighMem()
	}

	if params.stubConfig.generateStubs {
		rule.Command().Text("rm -rf").Text(params.stubsDir.String())
		rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
	}

	srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)

	homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")

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

	cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig, configFiles)
	cmd.Implicits(d.Javadoc.implicits)

	d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)

	if params.stubConfig.writeSdkValues {
		d.sdkValuesFlags(ctx, cmd, params.metadataDir)
	}

	annotationParams := annotationFlagsParams{
		migratingNullability:    params.stubConfig.migratingNullability,
		validatingNullability:   params.stubConfig.validatingNullability,
		nullabilityWarningsFile: params.nullabilityWarningsFile,
		annotationsZip:          params.annotationsZip,
	}

	d.annotationsFlags(ctx, cmd, annotationParams)
	d.inclusionAnnotationsFlags(ctx, cmd)
	d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)

	if params.stubConfig.doCheckReleased {
		d.apiCompatibilityFlags(ctx, cmd, params.stubConfig.stubsType)
	}

	d.expandArgs(ctx, cmd)

	for _, o := range d.Javadoc.properties.Out {
		cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
	}

	return cmd
}

// Sandbox rule for generating the everything stubs and other artifacts
func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
	srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
		android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
		SandboxInputs()

	var stubsDir android.OptionalPath
	if params.generateStubs {
		stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
		d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
	}

	if params.writeSdkValues {
		d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
		d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
	}

	if Bool(d.properties.Annotations_enabled) {
		if params.validatingNullability {
			d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
		}
		d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
	}
	if Bool(d.properties.Api_levels_annotations_enabled) {
		d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
	}

	commonCmdParams := stubsCommandParams{
		srcJarDir:               srcJarDir,
		stubsDir:                stubsDir,
		stubsSrcJar:             d.Javadoc.stubsSrcJar,
		metadataDir:             d.everythingArtifacts.metadataDir,
		apiVersionsXml:          d.everythingArtifacts.apiVersionsXml,
		nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
		annotationsZip:          d.everythingArtifacts.annotationsZip,
		stubConfig:              params,
	}

	cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)

	d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)

	if params.generateStubs {
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
			Flag("-jar").
			FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
			FlagWithArg("-C ", stubsDir.String()).
			FlagWithArg("-D ", stubsDir.String())
	}

	if params.writeSdkValues {
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
			Flag("-d").
			FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
			FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
			FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
	}

	// TODO: We don't really need two separate API files, but this is a reminiscence of how
	// we used to run metalava separately for API lint and the "last_released" check. Unify them.
	if params.doApiLint {
		rule.Command().Text("touch").Output(d.apiLintTimestamp)
	}
	if params.doCheckReleased {
		rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
	}

	// TODO(b/183630617): rewrapper doesn't support restat rules
	if !metalavaUseRbe(ctx) {
		rule.Restat()
	}

	zipSyncCleanupCmd(rule, srcJarDir)

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

// Sandbox rule for generating the everything artifacts that are not run by
// default but only run based on the module configurations
func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {

	// Add API lint options.
	treatDocumentationIssuesAsErrors := false
	if doApiLint {
		var newSince android.Paths
		if d.properties.Check_api.Api_lint.New_since != nil {
			newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)})
		}
		cmd.Flag("--api-lint")
		cmd.FlagForEachInput("--api-lint-previous-api ", newSince)
		d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO:  Change to ":api-lint"

		// If UnflaggedApi issues have not already been configured then make sure that existing
		// UnflaggedApi issues are reported as warnings but issues in new/changed code are treated as
		// errors by the Build Warnings Aye Aye Analyzer in Gerrit.
		// Once existing issues have been fixed this will be changed to error.
		// TODO(b/362771529): Switch to --error
		if !strings.Contains(cmd.String(), " UnflaggedApi ") {
			cmd.Flag("--error-when-new UnflaggedApi")
		}

		// TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
		if d.Name() != "android.car-system-stubs-docs" &&
			d.Name() != "android.car-stubs-docs" {
			treatDocumentationIssuesAsErrors = true
			cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
		}

		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
		updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
		d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")

		// Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
		//
		// TODO: metalava also has a slightly different message hardcoded. Should we unify this
		// message and metalava's one?
		msg := `$'` + // Enclose with $' ... '
			`************************************************************\n` +
			`Your API changes are triggering API Lint warnings or errors.\n` +
			`\n` +
			`To make the failures go away:\n` +
			`\n` +
			`1. REQUIRED: Read the messages carefully and address them by` +
			`   fixing the API if appropriate.\n` +
			`2. If the failure is a false positive, you can suppress it with:\n` +
			`        @SuppressLint("<id>")\n` +
			`   where the <id> is given in brackets in the error message above.\n`

		if baselineFile.Valid() {
			cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
			cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)

			msg += fmt.Sprintf(``+
				`3. FOR LSC ONLY: You can update the baseline by executing\n`+
				`   the following command:\n`+
				`       (cd $ANDROID_BUILD_TOP && cp \\\n`+
				`       "%s" \\\n`+
				`       "%s")\n`+
				`   To submit the revised baseline.txt to the main Android\n`+
				`   repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
		} else {
			msg += fmt.Sprintf(``+
				`3. FOR LSC ONLY: You can add a baseline file of existing lint failures\n`+
				`   to the build rule of %s.\n`, d.Name())
		}
		// Note the message ends with a ' (single quote), to close the $' ... ' .
		msg += `************************************************************\n'`

		cmd.FlagWithArg("--error-message:api-lint ", msg)
	}

	if !treatDocumentationIssuesAsErrors {
		treatDocumentationIssuesAsWarningErrorWhenNew(cmd)
	}

	// Add "check released" options. (Detect incompatible API changes from the last public release)
	if doCheckReleased {
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
		if baselineFile.Valid() {
			updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
			cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
		}
		// Note this string includes quote ($' ... '), which decodes the "\n"s.
		msg := `$'\n******************************\n` +
			`You have tried to change the API from what has been previously released in\n` +
			`an SDK.  Please fix the errors listed above.\n` +
			`******************************\n'`

		cmd.FlagWithArg("--error-message:compatibility:released ", msg)
	}

	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
		// Pass the current API file into metalava so it can use it as the basis for determining how to
		// generate the output signature files (both api and removed).
		currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
		cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
	}
}

// HIDDEN_DOCUMENTATION_ISSUES is the set of documentation related issues that should always be
// hidden as they are very noisy and provide little value.
var HIDDEN_DOCUMENTATION_ISSUES = []string{
	"Deprecated",
	"IntDef",
	"Nullable",
}

func treatDocumentationIssuesAsWarningErrorWhenNew(cmd *android.RuleBuilderCommand) {
	// Treat documentation issues as warnings, but error when new.
	cmd.Flag("--error-when-new-category").Flag("Documentation")

	// Hide some documentation issues that generated a lot of noise for little benefit.
	cmd.FlagForEachArg("--hide ", HIDDEN_DOCUMENTATION_ISSUES)
}

// Sandbox rule for generating exportable stubs and other artifacts
func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
	optionalCmdParams := stubsCommandParams{
		stubConfig: params,
	}

	if params.generateStubs {
		d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
		optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
	}

	if params.writeSdkValues {
		d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
		d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
		optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
		optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
	}

	if Bool(d.properties.Annotations_enabled) {
		if params.validatingNullability {
			d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
			optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
		}
		d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
		optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
	}
	if Bool(d.properties.Api_levels_annotations_enabled) {
		d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
		optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
	}

	if params.checkApi || String(d.properties.Api_filename) != "" {
		filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
		d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
	}

	if params.checkApi || String(d.properties.Removed_api_filename) != "" {
		filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
		d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
	}

	d.optionalStubCmd(ctx, optionalCmdParams)
}

func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {

	params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
		android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
		SandboxInputs()

	if params.stubConfig.generateStubs {
		params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
	}

	cmd := d.commonMetalavaStubCmd(ctx, rule, params)

	generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)

	if params.stubConfig.doApiLint {
		// Pass the lint baseline file as an input to resolve the lint errors.
		// The exportable stubs generation does not update the lint baseline file.
		// Lint baseline file update is handled by the everything stubs
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
		if baselineFile.Valid() {
			cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
		}
	}

	// Treat documentation issues as warnings, but error when new.
	treatDocumentationIssuesAsWarningErrorWhenNew(cmd)

	if params.stubConfig.generateStubs {
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
			Flag("-jar").
			FlagWithOutput("-o ", params.stubsSrcJar).
			FlagWithArg("-C ", params.stubsDir.String()).
			FlagWithArg("-D ", params.stubsDir.String())
	}

	if params.stubConfig.writeSdkValues {
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
			Flag("-d").
			FlagWithOutput("-o ", params.metadataZip).
			FlagWithArg("-C ", params.metadataDir.String()).
			FlagWithArg("-D ", params.metadataDir.String())
	}

	// TODO(b/183630617): rewrapper doesn't support restat rules
	if !metalavaUseRbe(ctx) {
		rule.Restat()
	}

	zipSyncCleanupCmd(rule, params.srcJarDir)

	rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
}

func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	deps := d.Javadoc.collectDeps(ctx)

	javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
	generateStubs := BoolDefault(d.properties.Generate_stubs, true)

	// Add options for the other optional tasks: API-lint and check-released.
	// We generate separate timestamp files for them.
	doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
	doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")

	writeSdkValues := Bool(d.properties.Write_sdk_values)

	annotationsEnabled := Bool(d.properties.Annotations_enabled)

	migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
	validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
		String(d.properties.Validate_nullability_from_list) != "")

	checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")

	stubCmdParams := stubsCommandConfigParams{
		javaVersion:           javaVersion,
		deps:                  deps,
		checkApi:              checkApi,
		generateStubs:         generateStubs,
		doApiLint:             doApiLint,
		doCheckReleased:       doCheckReleased,
		writeSdkValues:        writeSdkValues,
		migratingNullability:  migratingNullability,
		validatingNullability: validatingNullability,
	}
	stubCmdParams.stubsType = Everything
	// Create default (i.e. "everything" stubs) rule for metalava
	d.everythingStubCmd(ctx, stubCmdParams)

	// The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
	// aconfig_declarations property is defined or not. If the property is not defined, the module simply
	// strips all flagged apis to generate the "exportable" stubs
	stubCmdParams.stubsType = Exportable
	d.exportableStubCmd(ctx, stubCmdParams)

	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {

		if len(d.Javadoc.properties.Out) > 0 {
			ctx.PropertyErrorf("out", "out property may not be combined with check_api")
		}

		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)

		if baselineFile.Valid() {
			ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
		}

		d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")

		rule := android.NewRuleBuilder(pctx, ctx)

		// Diff command line.
		// -F matches the closest "opening" line, such as "package android {"
		// and "  public class Intent {".
		diff := `diff -u -F '{ *$'`

		rule.Command().Text("( true")
		rule.Command().
			Text(diff).
			Input(apiFile).Input(d.apiFile)

		rule.Command().
			Text(diff).
			Input(removedApiFile).Input(d.removedApiFile)

		msg := fmt.Sprintf(`\n******************************\n`+
			`You have tried to change the API from what has been previously approved.\n\n`+
			`To make these errors go away, you have two choices:\n`+
			`   1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
			`      to the new methods, etc. shown in the above diff.\n\n`+
			`   2. You can update current.txt and/or removed.txt by executing the following command:\n`+
			`         m %s-update-current-api\n\n`+
			`      To submit the revised current.txt to the main Android repository,\n`+
			`      you will need approval.\n`+
			`If your build failed due to stub validation, you can resolve the errors with\n`+
			`either of the two choices above and try re-building the target.\n`+
			`If the mismatch between the stubs and the current.txt is intended,\n`+
			`you can try re-building the target by executing the following command:\n`+
			`m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
			`Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
			`******************************\n`, ctx.ModuleName())

		rule.Command().
			Text("touch").Output(d.checkCurrentApiTimestamp).
			Text(") || (").
			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
			Text("; exit 38").
			Text(")")

		rule.Build("metalavaCurrentApiCheck", "check current API")

		d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")

		// update API rule
		rule = android.NewRuleBuilder(pctx, ctx)

		rule.Command().Text("( true")

		rule.Command().
			Text("cp").Flag("-f").
			Input(d.apiFile).Flag(apiFile.String())

		rule.Command().
			Text("cp").Flag("-f").
			Input(d.removedApiFile).Flag(removedApiFile.String())

		msg = "failed to update public API"

		rule.Command().
			Text("touch").Output(d.updateCurrentApiTimestamp).
			Text(") || (").
			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
			Text("; exit 38").
			Text(")")

		rule.Build("metalavaCurrentApiUpdate", "update current API")
	}

	if String(d.properties.Check_nullability_warnings) != "" {
		if d.everythingArtifacts.nullabilityWarningsFile == nil {
			ctx.PropertyErrorf("check_nullability_warnings",
				"Cannot specify check_nullability_warnings unless validating nullability")
		}

		checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))

		d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")

		msg := fmt.Sprintf(`\n******************************\n`+
			`The warnings encountered during nullability annotation validation did\n`+
			`not match the checked in file of expected warnings. The diffs are shown\n`+
			`above. You have two options:\n`+
			`   1. Resolve the differences by editing the nullability annotations.\n`+
			`   2. Update the file of expected warnings by running:\n`+
			`         cp %s %s\n`+
			`       and submitting the updated file as part of your change.`,
			d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)

		rule := android.NewRuleBuilder(pctx, ctx)

		rule.Command().
			Text("(").
			Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
			Text("&&").
			Text("touch").Output(d.checkNullabilityWarningsTimestamp).
			Text(") || (").
			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
			Text("; exit 38").
			Text(")")

		rule.Build("nullabilityWarningsCheck", "nullability warnings check")
	}

	d.setOutputFiles(ctx)
}

// This method sets the outputFiles property, which is used to set the
// OutputFilesProvider later.
// Droidstubs' tag supports specifying with the stubs type.
// While supporting the pre-existing tags, it also supports tags with
// the stubs type prefix. Some examples are shown below:
// {.annotations.zip} - pre-existing behavior. Returns the path to the
// annotation zip.
// {.exportable} - Returns the path to the exportable stubs src jar.
// {.exportable.annotations.zip} - Returns the path to the exportable
// annotations zip file.
// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
// xml file. For unsupported combinations, the default everything output file
// is returned.
func (d *Droidstubs) setOutputFiles(ctx android.ModuleContext) {
	tagToOutputFileFunc := map[string]func(StubsType) (android.Path, error){
		"":                     d.StubsSrcJar,
		".docs.zip":            d.DocZip,
		".api.txt":             d.ApiFilePath,
		android.DefaultDistTag: d.ApiFilePath,
		".removed-api.txt":     d.RemovedApiFilePath,
		".annotations.zip":     d.AnnotationsZip,
		".api_versions.xml":    d.ApiVersionsXmlFilePath,
	}
	stubsTypeToPrefix := map[StubsType]string{
		Everything: "",
		Exportable: ".exportable",
	}
	for _, tag := range android.SortedKeys(tagToOutputFileFunc) {
		for _, stubType := range android.SortedKeys(stubsTypeToPrefix) {
			tagWithPrefix := stubsTypeToPrefix[stubType] + tag
			outputFile, err := tagToOutputFileFunc[tag](stubType)
			if err == nil && outputFile != nil {
				ctx.SetOutputFiles(android.Paths{outputFile}, tagWithPrefix)
			}
		}
	}
}

func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
	api_file := d.properties.Check_api.Current.Api_file
	api_surface := d.properties.Api_surface

	props := struct {
		Name        *string
		Api_surface *string
		Api_file    *string
		Visibility  []string
	}{}

	props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
	props.Api_surface = api_surface
	props.Api_file = api_file
	props.Visibility = []string{"//visibility:override", "//visibility:public"}

	ctx.CreateModule(ApiContributionFactory, &props)
}

// TODO (b/262014796): Export the API contributions of CorePlatformApi
// A map to populate the api surface of a droidstub from a substring appearing in its name
// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
// use a strict naming convention
var (
	droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
		// public is commented out since the core libraries use public in their java_sdk_library names
		"intracore":     android.SdkIntraCore,
		"intra.core":    android.SdkIntraCore,
		"system_server": android.SdkSystemServer,
		"system-server": android.SdkSystemServer,
		"system":        android.SdkSystem,
		"module_lib":    android.SdkModule,
		"module-lib":    android.SdkModule,
		"platform.api":  android.SdkCorePlatform,
		"test":          android.SdkTest,
		"toolchain":     android.SdkToolchain,
	}
)

func StubsDefaultsFactory() android.Module {
	module := &DocDefaults{}

	module.AddProperties(
		&JavadocProperties{},
		&DroidstubsProperties{},
	)

	android.InitDefaultsModule(module)

	return module
}

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

type PrebuiltStubsSourcesProperties struct {
	Srcs []string `android:"path"`

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

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

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

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

type PrebuiltStubsSources struct {
	android.ModuleBase
	android.DefaultableModuleBase
	embeddableInModuleAndImport

	prebuilt android.Prebuilt

	properties PrebuiltStubsSourcesProperties

	stubsSrcJar android.Path
}

func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
	return d.stubsSrcJar, nil
}

func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if len(p.properties.Srcs) != 1 {
		ctx.PropertyErrorf("srcs", "must only specify one directory path or srcjar, contains %d paths", len(p.properties.Srcs))
		return
	}

	src := p.properties.Srcs[0]
	if filepath.Ext(src) == ".srcjar" {
		// This is a srcjar. We can use it directly.
		p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
	} else {
		outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")

		// This is a directory. Glob the contents just in case the directory does not exist.
		srcGlob := src + "/**/*"
		srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})

		// Although PathForModuleSrc can return nil if either the path doesn't exist or
		// the path components are invalid it won't in this case because no components
		// are specified and the module directory must exist in order to get this far.
		srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)

		rule := android.NewRuleBuilder(pctx, ctx)
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
			Flag("-jar").
			FlagWithOutput("-o ", outPath).
			FlagWithArg("-C ", srcDir.String()).
			FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
		rule.Restat()
		rule.Build("zip src", "Create srcjar from prebuilt source")
		p.stubsSrcJar = outPath
	}

	ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, "")
	// prebuilt droidstubs does not output "exportable" stubs.
	// Output the "everything" stubs srcjar file if the tag is ".exportable".
	ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, ".exportable")
}

func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
	return &p.prebuilt
}

func (p *PrebuiltStubsSources) Name() string {
	return p.prebuilt.Name(p.ModuleBase.Name())
}

// prebuilt_stubs_sources imports a set of java source files as if they were
// generated by droidstubs.
//
// By default, a prebuilt_stubs_sources has a single variant that expects a
// set of `.java` files generated by droidstubs.
//
// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
// for host modules.
//
// Intended only for use by sdk snapshots.
func PrebuiltStubsSourcesFactory() android.Module {
	module := &PrebuiltStubsSources{}

	module.AddProperties(&module.properties)
	module.initModuleAndImport(module)

	android.InitPrebuiltModule(module, &module.properties.Srcs)
	InitDroiddocModule(module, android.HostAndDeviceSupported)
	return module
}
