// Copyright 2015 The Bazel Authors. 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 com.google.devtools.build.lib.rules.android;

import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_KEYED_STRING_DICT;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import static com.google.devtools.build.lib.packages.Type.INTEGER;
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
import static com.google.devtools.build.lib.util.FileTypeSet.NO_FILE;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.PlatformOptions;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.CoreOptions;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.android.databinding.DataBinding;
import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagProvider;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaRuleClasses;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkbuildapi.android.AndroidSplitTransititionApi;
import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.List;

/** Rule definitions for Android rules. */
public final class AndroidRuleClasses {
  /** Sources generated by a given target, in particular, {@code R.java}. */
  public static final SafeImplicitOutputsFunction ANDROID_JAVA_SOURCE_JAR =
      fromTemplates("%{name}.srcjar");
  /** Sources compiled in a given target, excluding {@link #ANDROID_JAVA_SOURCE_JAR}. */
  public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_SOURCE_JAR =
      JavaSemantics.JAVA_LIBRARY_SOURCE_JAR;
  /**
   * Compiled sources of a given target, excluding {@link #ANDROID_JAVA_SOURCE_JAR}. This is the
   * conventional output Jar of any java library target, including android libs.
   */
  public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_CLASS_JAR =
      JavaSemantics.JAVA_LIBRARY_CLASS_JAR;

  public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_AAR =
      fromTemplates("%{name}.aar");
  // TODO(b/30307842): Remove this once it is no longer needed for resources migration.
  public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_APK =
      fromTemplates("%{name}_files/library.ap_");

  /**
   * Source Jar for {@link #ANDROID_RESOURCES_CLASS_JAR}, which should be the same as {@link
   * #ANDROID_JAVA_SOURCE_JAR}.
   */
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_SOURCE_JAR =
      fromTemplates("%{name}_resources-src.jar");
  /** Compiled {@link #ANDROID_JAVA_SOURCE_JAR}. */
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_CLASS_JAR =
      fromTemplates("%{name}_resources.jar");

  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_APK =
      fromTemplates("%{name}.ap_");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_AAPT2_LIBRARY_APK =
      fromTemplates("%{name}_files/aapt2_library.apk");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_AAPT2_R_TXT =
      fromTemplates("%{name}_symbols/R.aapt2.txt");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_AAPT2_VALIDATION_ARTIFACT =
      fromTemplates("%{name}_symbols/aapt2.validation.txt");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_AAPT2_SOURCE_JAR =
      fromTemplates("%{name}_files/%{name}_resources_aapt2-src.jar");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_SHRUNK_APK =
      fromTemplates("%{name}_shrunk.ap_");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_OPTIMIZED_APK =
      fromTemplates("%{name}_optimized.ap_");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_ZIP =
      fromTemplates("%{name}_files/resource_files.zip");
  public static final SafeImplicitOutputsFunction ANDROID_ASSETS_ZIP =
      fromTemplates("%{name}_files/assets.zip");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCES_SHRUNK_ZIP =
      fromTemplates("%{name}_files/resource_files_shrunk.zip");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCE_SHRINKER_LOG =
      fromTemplates("%{name}_files/resource_shrinker.log");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCE_OPTIMIZATION_CONFIG =
      fromTemplates("%{name}_files/resource_optimization.cfg");
  public static final SafeImplicitOutputsFunction ANDROID_RESOURCE_PATH_SHORTENING_MAP =
      fromTemplates("%{name}_resource_paths.map");
  public static final SafeImplicitOutputsFunction ANDROID_INCREMENTAL_RESOURCES_APK =
      fromTemplates("%{name}_files/incremental.ap_");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_APK = fromTemplates("%{name}.apk");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_INCREMENTAL_APK =
      fromTemplates("%{name}_incremental.apk");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_UNSIGNED_APK =
      fromTemplates("%{name}_unsigned.apk");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_DEPLOY_JAR =
      fromTemplates("%{name}_deploy.jar");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_PROGUARD_JAR =
      fromTemplates("%{name}_proguard.jar");
  public static final SafeImplicitOutputsFunction ANDROID_BINARY_INSTRUMENTED_JAR =
      fromTemplates("%{name}_instrumented.jar");
  public static final SafeImplicitOutputsFunction ANDROID_TEST_FILTERED_JAR =
      fromTemplates("%{name}_filtered.jar");
  public static final SafeImplicitOutputsFunction ANDROID_R_TXT =
      fromTemplates("%{name}_symbols/R.txt");
  public static final SafeImplicitOutputsFunction ANDROID_LOCAL_SYMBOLS =
      fromTemplates("%{name}_symbols/local.bin");
  public static final SafeImplicitOutputsFunction ANDROID_MERGED_SYMBOLS =
      fromTemplates("%{name}_symbols/merged.bin");
  public static final SafeImplicitOutputsFunction ANDROID_ASSET_SYMBOLS =
      fromTemplates("%{name}_symbols/assets.bin");
  public static final SafeImplicitOutputsFunction ANDROID_COMPILED_SYMBOLS =
      fromTemplates("%{name}_symbols/symbols.zip");
  public static final SafeImplicitOutputsFunction ANDROID_ASSET_COMPILED_SYMBOLS =
      fromTemplates("%{name}_symbols/assets.zip");
  public static final SafeImplicitOutputsFunction ANDROID_SYMLINKED_MANIFEST =
      fromTemplates("%{name}_symlinked_manifest/AndroidManifest.xml");
  public static final SafeImplicitOutputsFunction ANDROID_PROCESSED_MANIFEST =
      fromTemplates("%{name}_processed_manifest/AndroidManifest.xml");
  public static final SafeImplicitOutputsFunction MOBILE_INSTALL_STUB_APPLICATION_MANIFEST =
      fromTemplates("%{name}_files/mobile_install/AndroidManifest.xml");
  public static final SafeImplicitOutputsFunction FULL_DEPLOY_MARKER =
      fromTemplates("%{name}_files/full_deploy_marker");
  public static final SafeImplicitOutputsFunction INCREMENTAL_DEPLOY_MARKER =
      fromTemplates("%{name}_files/incremental_deploy_marker");
  public static final SafeImplicitOutputsFunction SPLIT_DEPLOY_MARKER =
      fromTemplates("%{name}_files/split_deploy_marker");
  public static final SafeImplicitOutputsFunction MOBILE_INSTALL_ARGS =
      fromTemplates("%{name}_files/mobile_install_args");
  public static final SafeImplicitOutputsFunction DEPLOY_INFO =
      fromTemplates("%{name}_files/deploy_info.deployinfo.pb");
  public static final SafeImplicitOutputsFunction DEPLOY_INFO_INCREMENTAL =
      fromTemplates("%{name}_files/deploy_info_incremental.deployinfo.pb");
  public static final SafeImplicitOutputsFunction DEPLOY_INFO_SPLIT =
      fromTemplates("%{name}_files/deploy_info_split.deployinfo.pb");
  public static final SafeImplicitOutputsFunction REX_OUTPUT_PACKAGE_MAP =
      fromTemplates("%{name}_rex/rex_output_package.map");
  public static final SafeImplicitOutputsFunction INSTRUMENTATION_TEST_CHECK_RESULTS =
      fromTemplates("%{name}_files/instrumentation_test_check_results.txt");

  // This needs to be in its own directory because ApkBuilder only has a function (-rf) for source
  // folders but not source files, and it's easiest to guarantee that nothing gets put beside this
  // file in the ApkBuilder invocation in this manner
  public static final SafeImplicitOutputsFunction MOBILE_INSTALL_STUB_APPLICATION_DATA =
      fromTemplates("%{name}_files/stub_application_data/stub_application_data.txt");
  public static final SafeImplicitOutputsFunction DEX_MANIFEST =
      fromTemplates("%{name}_files/dexmanifest.txt");
  public static final SafeImplicitOutputsFunction JAVA_RESOURCES_JAR =
      fromTemplates("%{name}_files/java_resources.jar");
  public static final String BUILD_INCREMENTAL_DEXMANIFEST_LABEL =
      "//tools/android:build_incremental_dexmanifest";
  public static final String STUBIFY_MANIFEST_LABEL = "//tools/android:stubify_manifest";
  public static final String INCREMENTAL_INSTALL_LABEL = "//tools/android:incremental_install";
  public static final String BUILD_SPLIT_MANIFEST_LABEL = "//tools/android:build_split_manifest";
  public static final String STRIP_RESOURCES_LABEL = "//tools/android:strip_resources";
  public static final String DEFAULT_INCREMENTAL_STUB_APPLICATION =
      "//tools/android:incremental_stub_application";
  public static final String DEFAULT_INCREMENTAL_SPLIT_STUB_APPLICATION =
      "//tools/android:incremental_split_stub_application";
  public static final String DEFAULT_RESOURCES_BUSYBOX = "//tools/android:busybox";
  public static final String DEFAULT_SDK = "//tools/android:sdk";
  public static final SafeImplicitOutputsFunction ANDROID_DEVICE_USERDATA_IMAGES =
      fromTemplates("%{name}_images/userdata_images.dat");
  public static final SafeImplicitOutputsFunction ANDROID_DEVICE_EMULATOR_METADATA =
      fromTemplates("%{name}_images/emulator-meta-data.pb");
  static final FileType APK = FileType.of(".apk");

  public static final String NOCOMPRESS_EXTENSIONS_ATTR = "nocompress_extensions";

  public static final ImmutableList<SkylarkProviderIdentifier> CONTAINS_CC_INFO_PARAMS =
      ImmutableList.of(SkylarkProviderIdentifier.forKey(CcInfo.PROVIDER.getKey()));

  /** The default label of android_sdk option */
  public static LabelLateBoundDefault<?> getAndroidSdkLabel(Label androidSdk) {
    return LabelLateBoundDefault.fromTargetConfiguration(
        AndroidConfiguration.class,
        androidSdk,
        (rule, attributes, configuration) -> configuration.getSdk());
  }

  @AutoCodec
  public static final AndroidSplitTransition ANDROID_SPLIT_TRANSITION =
      new AndroidSplitTransition();

  @AutoCodec
  static final LabelLateBoundDefault<AndroidConfiguration> LEGACY_MAIN_DEX_LIST_GENERATOR =
      LabelLateBoundDefault.fromTargetConfiguration(
          AndroidConfiguration.class,
          null,
          (rule, attributes, androidConfig) -> androidConfig.getLegacyMainDexListGenerator());

  /** Android Split configuration transition for properly handling native dependencies */
  public static final class AndroidSplitTransition
      implements SplitTransition, AndroidSplitTransititionApi {
    private static void setCrosstoolToAndroid(BuildOptions options) {
      AndroidConfiguration.Options androidOptions = options.get(AndroidConfiguration.Options.class);

      CppOptions cppOptions = options.get(CppOptions.class);
      if (androidOptions.androidCrosstoolTop != null) {
        cppOptions.crosstoolTop = androidOptions.androidCrosstoolTop;
      }

      androidOptions.configurationDistinguisher = ConfigurationDistinguisher.ANDROID;
    }

    @Override
    public ImmutableMap<String, BuildOptions> split(
        BuildOptions buildOptions, EventHandler eventHandler) {

      AndroidConfiguration.Options androidOptions =
          buildOptions.get(AndroidConfiguration.Options.class);
      CppOptions cppOptions = buildOptions.get(CppOptions.class);
      Label androidCrosstoolTop = androidOptions.androidCrosstoolTop;

      if (androidOptions.fatApkCpus.isEmpty()) {

        if (androidOptions.cpu.isEmpty()
            || androidCrosstoolTop == null
            || androidCrosstoolTop.equals(cppOptions.crosstoolTop)) {
          return ImmutableMap.of(buildOptions.get(CoreOptions.class).cpu, buildOptions);

        } else {

          BuildOptions splitOptions = buildOptions.clone();
          splitOptions.get(CoreOptions.class).cpu = androidOptions.cpu;
          setCommonAndroidOptions(androidOptions, splitOptions);
          return ImmutableMap.of(androidOptions.cpu, splitOptions);
        }

      } else {

        ImmutableMap.Builder<String, BuildOptions> result = ImmutableMap.builder();
        for (String cpu : ImmutableSortedSet.copyOf(androidOptions.fatApkCpus)) {
          BuildOptions splitOptions = buildOptions.clone();
          // Disable fat APKs for the child configurations.
          splitOptions.get(AndroidConfiguration.Options.class).fatApkCpus = ImmutableList.of();

          // Set the cpu & android_cpu.
          // TODO(bazel-team): --android_cpu doesn't follow --cpu right now; it should.
          splitOptions.get(AndroidConfiguration.Options.class).cpu = cpu;
          splitOptions.get(CoreOptions.class).cpu = cpu;
          setCommonAndroidOptions(androidOptions, splitOptions);
          result.put(cpu, splitOptions);
        }
        return result.build();
      }
    }

    private void setCommonAndroidOptions(
        AndroidConfiguration.Options androidOptions, BuildOptions newOptions) {
      newOptions.get(CppOptions.class).cppCompiler = androidOptions.cppCompiler;
      newOptions.get(CppOptions.class).libcTopLabel = androidOptions.androidLibcTopLabel;
      newOptions.get(CppOptions.class).dynamicMode = androidOptions.dynamicMode;
      setCrosstoolToAndroid(newOptions);

      // Ensure platforms aren't set so that platform mapping can take place.
      newOptions.get(PlatformOptions.class).platforms = ImmutableList.of();
    }

    @Override
    public boolean isImmutable() {
      return true;
    }

    @Override
    public void repr(Printer printer) {
      printer.append("android_common.multi_cpu_configuration");
    }
  }

  public static final FileType ANDROID_IDL = FileType.of(".aidl");

  public static final String[] ALLOWED_DEPENDENCIES = {
    "aar_import",
    "android_library",
    "cc_library",
    "java_import",
    "java_library",
    "java_lite_proto_library",
  };

  public static boolean hasProguardSpecs(AttributeMap rule) {
    // The below is a hack to support configurable attributes (proguard_specs seems like
    // too valuable an attribute to make nonconfigurable, and we don't currently
    // have the ability to know the configuration when determining implicit outputs). So if the
    // attribute is configurable, we create the proguard implicit output. At analysis time, we know
    // the actual value of proguard_specs, and if it is empty we do not use the proguarded jar for
    // dexing. If the user explicitly tries to build the proguard jar, it will fail.
    //
    // TODO(bazel-team): find a stronger approach for this. One simple approach is to somehow
    // receive 'rule' as an AggregatingAttributeMapper instead of a RawAttributeMapper,
    // check that all possible values are non-empty, and simply don't support configurable
    // instances that mix empty and non-empty lists. A more ambitious approach would be
    // to somehow determine implicit outputs after the configuration is known. A third
    // approach is to refactor the Android rule logic to avoid these dependencies in the
    // first place.
    return rule.isConfigurable("proguard_specs")
        || !rule.get("proguard_specs", LABEL_LIST).isEmpty();
  }

  public static final SafeImplicitOutputsFunction ANDROID_BINARY_IMPLICIT_OUTPUTS =
      new SafeImplicitOutputsFunction() {

        @Override
        public Iterable<String> getImplicitOutputs(EventHandler eventHandler, AttributeMap rule) {
          List<SafeImplicitOutputsFunction> functions = Lists.newArrayList();
          functions.add(AndroidRuleClasses.ANDROID_BINARY_APK);
          functions.add(AndroidRuleClasses.ANDROID_BINARY_UNSIGNED_APK);
          functions.add(AndroidRuleClasses.ANDROID_BINARY_DEPLOY_JAR);

          if (hasProguardSpecs(rule)) {
            functions.add(AndroidRuleClasses.ANDROID_BINARY_PROGUARD_JAR);
            functions.add(JavaSemantics.JAVA_BINARY_PROGUARD_CONFIG);
            if (ProguardHelper.genProguardMapping(rule)) {
              functions.add(JavaSemantics.JAVA_BINARY_PROGUARD_MAP);
            }
          }
          return fromFunctions(functions).getImplicitOutputs(eventHandler, rule);
        }
      };

  public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_IMPLICIT_OUTPUTS =
      new SafeImplicitOutputsFunction() {
        @Override
        public Iterable<String> getImplicitOutputs(
            EventHandler eventHandler, AttributeMap attributes) {

          ImmutableList.Builder<SafeImplicitOutputsFunction> implicitOutputs =
              ImmutableList.builder();

          implicitOutputs.add(
              AndroidRuleClasses.ANDROID_LIBRARY_CLASS_JAR,
              AndroidRuleClasses.ANDROID_LIBRARY_SOURCE_JAR,
              AndroidRuleClasses.ANDROID_LIBRARY_AAR /* TODO(b/36518935): remove this */);

          if (AndroidResources.definesAndroidResources(attributes)) {
            implicitOutputs.add(
                AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR,
                AndroidRuleClasses.ANDROID_R_TXT,
                AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);
          }

          return fromFunctions(implicitOutputs.build())
              .getImplicitOutputs(eventHandler, attributes);
        }
      };

  /** Base class for rule definitions that support resource declarations. */
  public static final class AndroidResourceSupportRule implements RuleDefinition {
    @Override
    public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
      return builder
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(manifest) -->
          The name of the Android manifest file, normally <code>AndroidManifest.xml</code>.
          Must be defined if resource_files or assets are defined.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("manifest", LABEL).allowedFileTypes(FileType.of(".xml")))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(resource_files) -->
          The list of resources to be packaged.
          This is typically a <code>glob</code> of all files under the
          <code>res</code> directory.
          <br/>
          Generated files (from genrules) can be referenced by
          <a href="../build-ref.html#labels">Label</a> here as well. The only restriction is that
          the generated outputs must be under the same "<code>res</code>" directory as any other
          resource files that are included.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("resource_files", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(assets_dir) -->
          The string giving the path to the files in <code>assets</code>.
          The pair <code>assets</code> and <code>assets_dir</code> describe packaged
          assets and either both attributes should be provided or none of them.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("assets_dir", STRING))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(assets) -->
          The list of assets to be packaged.
          This is typically a <code>glob</code> of all files under the
          <code>assets</code> directory. You can also reference other rules (any rule that produces
          files) or exported files in the other packages, as long as all those files are under the
          <code>assets_dir</code> directory in the corresponding package.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("assets", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(inline_constants) -->
          Let the compiler inline the constants defined in the generated java sources.
          This attribute must be set to 0 for all <code>android_library</code> rules
          used directly by an <code>android_binary</code>,
          and for any <code>android_binary</code> that has an <code>android_library</code>
          in its transitive closure.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("inline_constants", BOOLEAN)
                  .undocumented("deprecated noop on library")
                  .value(false))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(custom_package) -->
          Java package for which java sources will be generated.
          By default the package is inferred from the directory where the BUILD file
          containing the rule is. You can specify a different package but this is
          highly discouraged since it can introduce classpath conflicts with other
          libraries that will only be detected at runtime.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("custom_package", STRING))
          /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(enable_data_binding) -->
          If true, this rule processes
          <a href="https://developer.android.com/topic/libraries/data-binding/index.html">data
          binding</a> expressions in layout resources included through the
          <a href="${link android_binary.resource_files}">resource_files</a> attribute. Without this
          setting, data binding expressions produce build failures.
          <p>
          To build an Android app with data binding, you must also do the following:
          <ol>
            <li>Set this attribute for all Android rules that transitively depend on this one.
              This is because dependers inherit the rule's data binding expressions through resource
              merging. So they also need to build with data binding to parse those expressions.
            <li>Add a <code>deps =</code> entry for the data binding runtime library to all targets
            that set this attribute. The location of this library depends on your depot setup.
          </ol>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("enable_data_binding", Type.BOOLEAN))
          // The javac annotation processor from Android's data binding library that turns
          // processed XML expressions into Java code.
          .add(
              attr(DataBinding.DATABINDING_ANNOTATION_PROCESSOR_ATTR, LABEL)
                  .cfg(HostTransition.createFactory())
                  .value(env.getToolsLabel("//tools/android:databinding_annotation_processor")))
          .add(
              attr(DataBinding.DATABINDING_EXEC_PROCESSOR_ATTR, LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:databinding_exec")))
          .advertiseSkylarkProvider(
              SkylarkProviderIdentifier.forKey(AndroidResourcesInfo.PROVIDER.getKey()))
          .advertiseSkylarkProvider(
              SkylarkProviderIdentifier.forKey(AndroidNativeLibsInfo.PROVIDER.getKey()))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("$android_resource_support")
          .type(RuleClassType.ABSTRACT)
          .ancestors(AndroidRuleClasses.AndroidBaseRule.class)
          .build();
    }
  }

  /** Base class for Android rule definitions. */
  public static final class AndroidBaseRule implements RuleDefinition {
    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
      return builder
          .add(
              attr(":android_sdk", LABEL)
                  .allowedRuleClasses("android_sdk")
                  .value(getAndroidSdkLabel(env.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
          /* <!-- #BLAZE_RULE($android_base).ATTRIBUTE(plugins) -->
          Java compiler plugins to run at compile-time.
          Every <code>java_plugin</code> specified in
          the plugins attribute will be run whenever
          this target is built.  Resources generated by
          the plugin will be included in the result jar of
          the target.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("plugins", LABEL_LIST)
                  .cfg(HostTransition.createFactory())
                  .allowedRuleClasses("java_plugin")
                  .legacyAllowAnyFileType())
          .add(
              attr(":java_plugins", LABEL_LIST)
                  .cfg(HostTransition.createFactory())
                  .allowedRuleClasses("java_plugin")
                  .silentRuleClassFilter()
                  .value(JavaSemantics.JAVA_PLUGINS))
          /* <!-- #BLAZE_RULE($android_base).ATTRIBUTE(javacopts) -->
          Extra compiler options for this target.
          Subject to <a href="${link make-variables}">"Make variable"</a> substitution and
          <a href="${link common-definitions#sh-tokenization}">Bourne shell tokenization</a>.
          <p>
          These compiler options are passed to javac after the global compiler options.</p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("javacopts", STRING_LIST))
          .add(
              attr("$idlclass", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:IdlClass")))
          .add(
              attr("$desugar_java8_extra_bootclasspath", LABEL)
                  .cfg(HostTransition.createFactory())
                  .value(env.getToolsLabel("//tools/android:desugar_java8_extra_bootclasspath")))
          .add(
              attr("$android_resources_busybox", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(DEFAULT_RESOURCES_BUSYBOX)))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("$android_base")
          .type(RuleClassType.ABSTRACT)
          .ancestors(BaseRuleClasses.RuleBase.class)
          .build();
    }
  }

  /** Base class for Android rule definitions that produce binaries. */
  public static final class AndroidBinaryBaseRule implements RuleDefinition {

    private final AndroidNeverlinkAspect androidNeverlinkAspect;
    private final DexArchiveAspect dexArchiveAspect;

    public AndroidBinaryBaseRule(
        AndroidNeverlinkAspect androidNeverlinkAspect, DexArchiveAspect dexArchiveAspect) {
      this.androidNeverlinkAspect = androidNeverlinkAspect;
      this.dexArchiveAspect = dexArchiveAspect;
    }

    @Override
    public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
      return builder
          .requiresConfigurationFragments(
              AndroidConfiguration.class, JavaConfiguration.class, CppConfiguration.class)
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(srcs) -->
          The list of source files that are processed to create the target.
          <p><code>srcs</code> files of type <code>.java</code> are compiled.
          <em>For readability's sake</em>, it is not good to put the name of a
          generated <code>.java</code> source file into the <code>srcs</code>.
          Instead, put the depended-on rule name in the <code>srcs</code>, as
          described below.
          </p>
          <p><code>srcs</code> files of type <code>.srcjar</code> are unpacked and
          compiled. (This is useful if you need to generate a set of .java files with
          a genrule or build extension.)
          </p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("srcs", LABEL_LIST)
                  .direct_compile_time_input()
                  .allowedFileTypes(JavaSemantics.JAVA_SOURCE, JavaSemantics.SOURCE_JAR))
          // manifest is required for android_binary to ensure that we have an Android package.
          .override(builder.copy("manifest").mandatory())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(deps) -->
          The list of other libraries to be linked in to the binary target.
          Permitted library types are: <code>android_library</code>,
          <code>java_library</code> with <code>android</code> constraint and
          <code>cc_library</code> wrapping or producing <code>.so</code> native libraries for the
          Android target platform.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .override(
              builder
                  .copy("deps")
                  .cfg(TransitionFactories.of(ANDROID_SPLIT_TRANSITION))
                  .allowedRuleClasses(ALLOWED_DEPENDENCIES)
                  .allowedFileTypes()
                  .mandatoryProviders(CONTAINS_CC_INFO_PARAMS)
                  .mandatoryProviders(JavaRuleClasses.CONTAINS_JAVA_PROVIDER)
                  .mandatoryProviders(
                      SkylarkProviderIdentifier.forKey(AndroidResourcesInfo.PROVIDER.getKey()),
                      SkylarkProviderIdentifier.forKey(AndroidAssetsInfo.PROVIDER.getKey()))
                  .aspect(androidNeverlinkAspect)
                  .aspect(dexArchiveAspect, DexArchiveAspect.PARAM_EXTRACTOR))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(debug_key) -->
          File containing the debug keystore to be used to sign the debug apk. Usually you do not
          want to use a key other than the default key, so this attribute should be omitted.
          <p><em class="harmful">WARNING: Do not use your production keys, they should be
          strictly safeguarded and not kept in your source tree</em>.</p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("debug_key", LABEL)
                  .cfg(HostTransition.createFactory())
                  .legacyAllowAnyFileType()
                  .value(env.getToolsLabel("//tools/android:debug_keystore")))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(nocompress_extensions) -->
          A list of file extension to leave uncompressed in apk.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("nocompress_extensions", STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(crunch_png) -->
          Do PNG crunching (or not). This is independent of nine-patch processing, which is always
          done. This is a deprecated workaround for an
          <a href="https://code.google.com/p/android/issues/detail?id=74334">aapt bug</a> which has
          been fixed in aapt2.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("crunch_png", BOOLEAN).value(true))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(resource_configuration_filters) -->
          A list of resource configuration filters, such 'en' that will limit the resources in the
          apk to only the ones in the 'en' configuration.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr(ResourceFilterFactory.RESOURCE_CONFIGURATION_FILTERS_NAME, STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(shrink_resources) -->
          Whether to perform resource shrinking. Resources that are not used by the binary will be
          removed from the APK. This is only supported for rules using local resources (i.e. the
          <code>manifest</code> and <code>resource_files</code> attributes) and requires ProGuard.
          It operates in mostly the same manner as the Gradle resource shrinker
          (https://developer.android.com/studio/build/shrink-code.html#shrink-resources).
          <p>Notable differences:
          <ul>
            <li>resources in <code>values/</code> will be removed as well as file based
                resources</li>
            <li>uses <code>strict mode</code> by default</li>
            <li>removing unused ID resources is only supported with aapt2</li>
          </ul>
          If resource shrinking is enabled, <code><var>name</var>_files/resource_shrinker.log</code>
          will also be generated, detailing the analysis and deletions performed.
          <p>Possible values:
          <ul>
            <li><code>shrink_resources = 1</code>: Turns on Android resource shrinking</li>
            <li><code>shrink_resources = 0</code>: Turns off Android resource shrinking</li>
            <li><code>shrink_resources = -1</code>: Shrinking is controlled by the
                <a href="../user-manual.html#flag--android_resource_shrinking">
                --android_resource_shrinking</a> flag.</li>
          </ul>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("shrink_resources", TRISTATE).value(TriState.AUTO))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(densities) -->
          Densities to filter for when building the apk.
          This will strip out raster drawable resources that would not be loaded by a device with
          the specified screen densities, to reduce APK size. A corresponding compatible-screens
          section will also be added to the manifest if it does not already contain a superset
          listing.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr(ResourceFilterFactory.DENSITIES_NAME, STRING_LIST))
          .add(
              attr("$build_incremental_dexmanifest", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(BUILD_INCREMENTAL_DEXMANIFEST_LABEL)))
          .add(
              attr("$stubify_manifest", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(STUBIFY_MANIFEST_LABEL)))
          .add(
              attr("$shuffle_jars", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:shuffle_jars")))
          .add(
              attr("$dexbuilder", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexbuilder")))
          .add(
              attr("$dexbuilder_after_proguard", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexbuilder_after_proguard")))
          .add(
              attr("$dexsharder", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexsharder")))
          .add(
              attr("$dexmerger", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexmerger")))
          .add(
              attr("$merge_dexzips", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:merge_dexzips")))
          .add(
              attr("$incremental_install", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(INCREMENTAL_INSTALL_LABEL)))
          .add(
              attr("$build_split_manifest", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(BUILD_SPLIT_MANIFEST_LABEL)))
          .add(
              attr("$strip_resources", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel(STRIP_RESOURCES_LABEL)))
          .add(
              attr("$incremental_stub_application", LABEL)
                  .value(env.getToolsLabel(DEFAULT_INCREMENTAL_STUB_APPLICATION))
                  .aspect(dexArchiveAspect, DexArchiveAspect.ONLY_DESUGAR_JAVA8))
          .add(
              attr("$incremental_split_stub_application", LABEL)
                  .value(env.getToolsLabel(DEFAULT_INCREMENTAL_SPLIT_STUB_APPLICATION))
                  .aspect(dexArchiveAspect, DexArchiveAspect.ONLY_DESUGAR_JAVA8))
          .add(
              attr("$desugar", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:desugar_java8")))
          .add(
              attr("$java8_legacy_dex", LABEL)
                  .value(env.getToolsLabel("//tools/android:java8_legacy_dex")))
          .add(
              attr("$build_java8_legacy_dex", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:build_java8_legacy_dex")))
          .add(
              attr("$desugared_java8_legacy_apis", LABEL)
                  .value(env.getToolsLabel("//tools/android:desugared_java8_legacy_apis")))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(dexopts) -->
          Additional command-line flags for the dx tool when generating classes.dex.
          Subject to <a href="${link make-variables}">"Make variable"</a> substitution and
          <a href="${link common-definitions#sh-tokenization}">Bourne shell tokenization</a>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("dexopts", STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(dex_shards) -->
          Number of shards dexing should be decomposed into.
          This is makes dexing much faster at the expense of app installation and startup time. The
          larger the binary, the more shards should be used. 25 is a good value to start
          experimenting with.
          <p>
          Note that each shard will result in at least one dex in the final app. For this reason,
          setting this to more than 1 is not recommended for release binaries.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("dex_shards", INTEGER).value(1))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(incremental_dexing) -->
          Force the target to be built with or without incremental dexing, overriding defaults
          and --incremental_dexing flag.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("incremental_dexing", TRISTATE)
                  // Read by DexArchiveAspect's attribute extractor
                  .nonconfigurable("AspectParameters don't support configurations."))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(multidex) -->
          Whether to split code into multiple dex files.<br/>
          Possible values:
          <ul>
            <li><code>native</code>: Split code into multiple dex files when the dex 64K index limit
              is exceeded. Assumes native platform support for loading multidex classes at runtime.
              <em class="harmful">This works with only Android L and newer</em>.</li>
            <li><code>legacy</code>: Split code into multiple dex files when the dex 64K index limit
              is exceeded. Assumes multidex classes are loaded through application code (i.e. no
              native platform support).</li>
            <li><code>manual_main_dex</code>: Split code into multiple dex files when the dex 64K
              index limit is exceeded. The content of the main dex file needs to be specified by
              providing a list of classes in a text file using the
              <a href="${link android_binary.main_dex_list}">main_dex_list</a> attribute.</li>
            <li><code>off</code>: Compile all code to a single dex file, even if it exceeds the
              index limit.</li>
          </ul>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("multidex", STRING)
                  .allowedValues(new AllowedValueSet(MultidexMode.getValidValues()))
                  .value(MultidexMode.OFF.getAttributeValue()))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_list_opts) -->
          Command line options to pass to the main dex list builder.
          Use this option to affect the classes included in the main dex list.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_list_opts", STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_list) -->

          A text file contains a list of class file names. Classes defined by those class files are
          put in the primary classes.dex. e.g.:<pre class="code">
          android/support/multidex/MultiDex$V19.class
          android/support/multidex/MultiDex.class
          android/support/multidex/MultiDexApplication.class
          com/google/common/base/Objects.class
                    </pre>
                    Must be used with <code>multidex="manual_main_dex"</code>.
                    <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_list", LABEL).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_proguard_specs) -->
          Files to be used as the Proguard specifications to determine classes that must be kept in
          the main dex.
          Only allowed if the <code>multidex</code> attribute is set to <code>legacy</code>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_proguard_specs", LABEL_LIST).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_specs) -->
          Files to be used as Proguard specification.
          This file will describe the set of specifications to be used by Proguard.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("proguard_specs", LABEL_LIST).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_generate_mapping) -->
          Whether to generate Proguard mapping file.
          The mapping file will be generated only if <code>proguard_specs</code> is
          specified. This file will list the mapping between the original and
          obfuscated class, method, and field names.
          <p><em class="harmful">WARNING: If this attribute is used, the Proguard
          specification should contain neither <code>-dontobfuscate</code> nor
          <code>-printmapping</code>.</em></p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("proguard_generate_mapping", BOOLEAN)
                  .value(false)
                  .nonconfigurable("value is referenced in an ImplicitOutputsFunction"))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_apply_mapping) -->
          File to be used as a mapping for proguard.
          A mapping file generated by <code>proguard_generate_mapping</code> to be
          re-used to apply the same mapping to a new build.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("proguard_apply_mapping", LABEL).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_apply_dictionary) -->
          File to be used as a mapping for proguard.
          A line separated file of "words" to pull from when renaming classes and members during
          obfuscation.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("proguard_apply_dictionary", LABEL).legacyAllowAnyFileType())
          .add(attr(":extra_proguard_specs", LABEL_LIST).value(JavaSemantics.EXTRA_PROGUARD_SPECS))
          .add(
              attr("$dex_list_obfuscator", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dex_list_obfuscator")))
          .add(
              attr(":bytecode_optimizer", LABEL)
                  .cfg(HostTransition.createFactory())
                  .value(JavaSemantics.BYTECODE_OPTIMIZER))
          // We need the C++ toolchain for every sub-configuration to get the correct linker.
          .add(
              attr("$cc_toolchain_split", LABEL)
                  .cfg(TransitionFactories.of(ANDROID_SPLIT_TRANSITION))
                  .value(env.getToolsLabel("//tools/cpp:current_cc_toolchain")))
          /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(manifest_values) -->
          A dictionary of values to be overridden in the manifest. Any instance of ${name} in the
          manifest will be replaced with the value corresponding to name in this dictionary.
          applicationId, versionCode, versionName, minSdkVersion, targetSdkVersion and
          maxSdkVersion will also override the corresponding attributes of the manifest and
          uses-sdk tags. packageName will be ignored and will be set from either applicationId if
          specified or the package in manifest. When manifest_merger is set to legacy, only
          applicationId, versionCode and versionName will have any effect.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("manifest_values", STRING_DICT))
          .add(
              attr(AndroidFeatureFlagSetProvider.FEATURE_FLAG_ATTR, LABEL_KEYED_STRING_DICT)
                  .undocumented("the feature flag feature has not yet been launched")
                  .allowedRuleClasses("config_feature_flag")
                  .allowedFileTypes()
                  .nonconfigurable("defines an aspect of configuration")
                  .mandatoryProviders(ImmutableList.of(ConfigFeatureFlagProvider.id())))
          .add(AndroidFeatureFlagSetProvider.getWhitelistAttribute(env))
          // The resource extractor is used at the binary level to extract java resources from the
          // deploy jar so that they can be added to the APK.
          .add(
              attr("$resource_extractor", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:resource_extractor")))
          /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(instruments) -->
          <p>The <code>android_binary</code> target to instrument.</p>
          <p>If this attribute is set, this <code>android_binary</code> will be treated as a test
          application for instrumentation tests. An <code>android_instrumentation_test</code>
          target can then specify this target in its
           <a href="${link android_instrumentation_test.test_app}">test_app</a> attribute.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("instruments", LABEL)
                  .allowedRuleClasses("android_binary")
                  .allowedFileTypes(NO_FILE))
          .add(
              attr("$instrumentation_test_check", LABEL)
                  .cfg(HostTransition.createFactory())
                  .value(
                      new Attribute.ComputedDefault() {
                        @Override
                        public Object getDefault(AttributeMap rule) {
                          return rule.isAttributeValueExplicitlySpecified("instruments")
                              ? env.getToolsLabel("//tools/android:instrumentation_test_check")
                              : null;
                        }
                      })
                  .exec())
          .add(
              attr("$zip_filter", LABEL)
                  .cfg(HostTransition.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:zip_filter")))
          .add(
              attr("application_resources", LABEL)
                  .mandatoryProviders(AndroidApplicationResourceInfo.PROVIDER.id())
                  .allowedFileTypes(NO_FILE)
                  .undocumented(
                      "Do not use this attribute. It's for the migration of "
                          + "Android resource processing to Starlark only."))
          // This comes from the --legacy_main_dex_list_generator flag.
          .add(
              attr(":legacy_main_dex_list_generator", LABEL)
                  .cfg(HostTransition.createFactory())
                  .value(LEGACY_MAIN_DEX_LIST_GENERATOR)
                  .exec())
          .removeAttribute("data")
          .advertiseSkylarkProvider(SkylarkProviderIdentifier.forKey(ApkInfo.PROVIDER.getKey()))
          .advertiseSkylarkProvider(SkylarkProviderIdentifier.forKey(JavaInfo.PROVIDER.getKey()))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("$android_binary_base")
          .type(RuleClassType.ABSTRACT)
          .ancestors(AndroidResourceSupportRule.class)
          .build();
    }
  }

  /** Semantic options for the dexer's multidex behavior. */
  public enum MultidexMode {
    // Build dexes with multidex, assuming native platform support for multidex.
    NATIVE,
    // Build dexes with multidex and implement support at the application level.
    LEGACY,
    // Build dexes with multidex, main dex list needs to be manually specified.
    MANUAL_MAIN_DEX,
    // Build all dex code into a single classes.dex file.
    OFF;

    /** Returns the attribute value that specifies this mode. */
    public String getAttributeValue() {
      return toString().toLowerCase();
    }

    /**
     * Returns the name of the output dex classes file. In multidex mode, this is an archive of
     * (possibly) multiple files.
     */
    public String getOutputDexFilename() {
      return this == OFF ? "classes.dex" : "classes.dex.zip";
    }

    /** Converts an attribute value to a corresponding mode. Returns null on no match. */
    public static MultidexMode fromValue(String value) {
      for (MultidexMode mode : values()) {
        if (mode.getAttributeValue().equals(value)) {
          return mode;
        }
      }
      return null;
    }

    /** Enumerates valid values for the "multidex" attribute. */
    public static List<String> getValidValues() {
      List<String> ans = Lists.newArrayList();
      for (MultidexMode mode : MultidexMode.values()) {
        ans.add(mode.getAttributeValue());
      }
      return ans;
    }
  }

  /** Definition of the {@code android_tools_defaults_jar} rule. */
  public static final class AndroidToolsDefaultsJarRule implements RuleDefinition {

    private final Label[] compatibleWithAndroidEnvironments;

    private final Class<? extends AndroidToolsDefaultsJar> factoryClass;

    public AndroidToolsDefaultsJarRule(
        Class<? extends AndroidToolsDefaultsJar> factoryClass,
        Label... compatibleWithAndroidEnvironments) {
      this.factoryClass = factoryClass;
      this.compatibleWithAndroidEnvironments = compatibleWithAndroidEnvironments;
    }

    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
      builder
          .setUndocumented()
          .add(
              attr(":android_sdk", LABEL)
                  .allowedRuleClasses("android_sdk")
                  .value(getAndroidSdkLabel(environment.getToolsLabel(DEFAULT_SDK))));
      if (compatibleWithAndroidEnvironments.length > 0) {
        builder.compatibleWith(compatibleWithAndroidEnvironments);
      }
      return builder.build();
    }

    @Override
    public Metadata getMetadata() {
      return Metadata.builder()
          .name("android_tools_defaults_jar")
          .ancestors(BaseRuleClasses.BaseRule.class)
          .factoryClass(factoryClass)
          .build();
    }
  }
}
