// 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.Types.STRING_DICT;
import static com.google.devtools.build.lib.packages.Types.STRING_LIST;
import static com.google.devtools.build.lib.util.FileTypeSet.NO_FILE;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
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.StarlarkProviderIdentifier;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.packages.Type;
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.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaPluginInfo;
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.SerializationConstant;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.List;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkInt;

/** 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 =
      fromTemplates("lib%{name}-src.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 =
      fromTemplates("lib%{name}.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_V4_SIGNATURE =
      fromTemplates("%{name}.apk.idsig");
  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<StarlarkProviderIdentifier> CONTAINS_CC_INFO_PARAMS =
      ImmutableList.of(StarlarkProviderIdentifier.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());
  }
  
  @SerializationConstant
  static final LabelLateBoundDefault<AndroidConfiguration> LEGACY_MAIN_DEX_LIST_GENERATOR =
      LabelLateBoundDefault.fromTargetConfiguration(
          AndroidConfiguration.class,
          null,
          (rule, attributes, androidConfig) -> androidConfig.getLegacyMainDexListGenerator());

  @SerializationConstant
  static final LabelLateBoundDefault<AndroidConfiguration> OPTIMIZING_DEXER =
      LabelLateBoundDefault.fromTargetConfiguration(
          AndroidConfiguration.class,
          null,
          (rule, attributes, androidConfig) -> androidConfig.getOptimizingDexer());

  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(AndroidSemantics.ANDROID_BINARY_PROGUARD_CONFIG);
            if (ProguardHelper.genProguardMapping(rule)) {
              functions.add(AndroidSemantics.ANDROID_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="${link build-ref#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(ExecutionTransitionFactory.createFactory())
                  .value(env.getToolsLabel("//tools/android:databinding_annotation_processor")))
          .add(
              attr(DataBinding.DATABINDING_EXEC_PROCESSOR_ATTR, LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:databinding_exec")))
          .advertiseStarlarkProvider(
              StarlarkProviderIdentifier.forKey(AndroidResourcesInfo.PROVIDER.getKey()))
          .advertiseStarlarkProvider(
              StarlarkProviderIdentifier.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(ExecutionTransitionFactory.createFactory())
                  .mandatoryProviders(JavaPluginInfo.PROVIDER.id())
                  .legacyAllowAnyFileType())
          .add(
              attr(":java_plugins", LABEL_LIST)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .mandatoryProviders(JavaPluginInfo.PROVIDER.id())
                  .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(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:IdlClass")))
          .add(
              attr("$desugar_java8_extra_bootclasspath", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .value(env.getToolsLabel("//tools/android:desugar_java8_extra_bootclasspath")))
          .add(
              attr("$android_resources_busybox", LABEL)
                  .cfg(ExecutionTransitionFactory.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.NativeActionCreatingRule.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(AndroidSplitTransition.FACTORY)
                  .allowedRuleClasses(ALLOWED_DEPENDENCIES)
                  .allowedFileTypes()
                  .mandatoryProviders(CONTAINS_CC_INFO_PARAMS)
                  .mandatoryProviders(JavaRuleClasses.CONTAINS_JAVA_PROVIDER)
                  .mandatoryProviders(
                      StarlarkProviderIdentifier.forKey(AndroidResourcesInfo.PROVIDER.getKey()),
                      StarlarkProviderIdentifier.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(ExecutionTransitionFactory.createFactory())
                  .legacyAllowAnyFileType()
                  .value(env.getToolsLabel("//tools/android:debug_keystore")))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(debug_signing_keys) -->
          List of files, debug keystores to be used to sign the debug apk. Usually you do not
          want to use keys 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_signing_keys", LABEL_LIST)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(debug_signing_lineage_file) -->
          File containing the signing lineage for the debug_signing_keys. Usually you do not
          want to use keys 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_signing_lineage_file", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(key_rotation_min_sdk) -->
          Sets the minimum Android platform version (API Level) for which an APK's rotated signing
          key should be used to produce the APK's signature. The original signing key for the APK
          will be used for all previous platform versions.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("key_rotation_min_sdk", STRING))
          /* <!-- #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. To enable pseudolocalization, include the
          <code>en_XA</code> and/or <code>ar_XB</code> pseudo-locales.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr(ResourceFilterFactory.RESOURCE_CONFIGURATION_FILTERS_NAME, STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(min_sdk_version) -->
          The minSdkVersion. This must match the minSdkVersion specified in the AndroidManifest.xml.
          If set, will be used for dex/desugaring.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("min_sdk_version", INTEGER)
                  .undocumented("experimental")
                  .value(StarlarkInt.of(0))
                  .nonconfigurable("AspectParameters don't support configurations."))
          /* <!-- #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="${link user-manual#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(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel(BUILD_INCREMENTAL_DEXMANIFEST_LABEL)))
          .add(
              attr("$stubify_manifest", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel(STUBIFY_MANIFEST_LABEL)))
          .add(
              attr("$shuffle_jars", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:shuffle_jars")))
          .add(
              attr("$dexbuilder", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexbuilder")))
          .add(
              attr("$dexbuilder_after_proguard", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexbuilder_after_proguard")))
          .add(
              attr("$dexsharder", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexsharder")))
          .add(
              attr("$dexmerger", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexmerger")))
          .add(
              attr("$merge_dexzips", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:merge_dexzips")))
          .add(
              attr("$incremental_install", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel(INCREMENTAL_INSTALL_LABEL)))
          .add(
              attr("$build_split_manifest", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel(BUILD_SPLIT_MANIFEST_LABEL)))
          .add(
              attr("$strip_resources", LABEL)
                  .cfg(ExecutionTransitionFactory.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(ExecutionTransitionFactory.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(ExecutionTransitionFactory.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")))
          .add(
              attr("$merge_proguard_maps", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:merge_proguard_maps")))
          /* <!-- #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(StarlarkInt.of(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.NATIVE.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("$dex_list_obfuscator", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dex_list_obfuscator")))
          .add(
              attr(":bytecode_optimizer", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .value(AndroidSemantics.BYTECODE_OPTIMIZER))
          // We need the C++ toolchain for every sub-configuration to get the correct linker.
          .add(
              attr("$cc_toolchain_split", LABEL)
                  .cfg(AndroidSplitTransition.FACTORY)
                  .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.
          <p>
          Any instance of <code>${name}</code> in the manifest will be replaced with the value
          corresponding to name in this dictionary.
          <p>
          <code>applicationId</code>, <code>versionCode</code>, <code>versionName</code>,
          <code>minSdkVersion</code>, <code>targetSdkVersion</code> and
          <code>maxSdkVersion</code> will also override the corresponding attributes in the manifest
          and <code>uses-sdk</code> tags.
          <p>
          <code>packageName</code> will be ignored and will be set from either
          <code>applicationId</code> if specified or the package in manifest.
          <p>
          When <code>manifest_merger</code> is set to <code>legacy</code>, only
          <code>applicationId</code>, <code>versionCode</code> and <code>versionName</code> 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.getAllowlistAttribute(env))
          .addAllowlistChecker(AndroidFeatureFlagSetProvider.CHECK_ALLOWLIST_IF_TRIGGERED)
          // 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(ExecutionTransitionFactory.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
           <code>test_app</code> attribute.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("instruments", LABEL)
                  .allowedRuleClasses("android_binary")
                  .allowedFileTypes(NO_FILE))
          .add(
              attr("$instrumentation_test_check", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .value(
                      new Attribute.ComputedDefault() {
                        @Override
                        @Nullable
                        public Object getDefault(AttributeMap rule) {
                          return rule.isAttributeValueExplicitlySpecified("instruments")
                              ? env.getToolsLabel("//tools/android:instrumentation_test_check")
                              : null;
                        }
                      })
                  .exec())
          .add(
              attr("$zip_filter", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .exec()
                  .value(env.getToolsLabel("//tools/android:zip_filter")))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(package_id) -->
          Package ID to be assigned to resources in this binary.
          <p>See AAPT2's <code>--package-id</code> argument for more information. This can (and
          should) typically be left unset, resulting in the default value of 127
          (<code>0x7F</code>).
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          // This is only implemented in Starlark, but is present here for doc generation.
          .add(attr("package_id", INTEGER))
          .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.")
                  .aspect(androidNeverlinkAspect)
                  .aspect(dexArchiveAspect, DexArchiveAspect.PARAM_EXTRACTOR))
          // Nothing in the native rule reads this. This is only for facilitating the Starlark
          // migration of the android rules.
          .add(attr("stamp", TRISTATE).value(TriState.AUTO))
          // This comes from the --legacy_main_dex_list_generator flag.
          .add(
              attr(":legacy_main_dex_list_generator", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .value(LEGACY_MAIN_DEX_LIST_GENERATOR)
                  .exec())
          // This comes from the --optimizing_dexer flag.
          .add(
              attr(":optimizing_dexer", LABEL)
                  .cfg(ExecutionTransitionFactory.createFactory())
                  .value(OPTIMIZING_DEXER)
                  .exec())
          .removeAttribute("data")
          .advertiseStarlarkProvider(StarlarkProviderIdentifier.forKey(ApkInfo.PROVIDER.getKey()))
          .advertiseStarlarkProvider(StarlarkProviderIdentifier.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;

    /** 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 "classes.dex.zip";
    }

    /** Converts an attribute value to a corresponding mode. Returns null on no match. */
    @Nullable
    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 AndroidBaseToolsDefaultsJarRule implements RuleDefinition {

    @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))));
      return builder.build();
    }

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