// 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.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.INTEGER;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import static com.google.devtools.build.lib.syntax.Type.STRING_DICT;
import static com.google.devtools.build.lib.syntax.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.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.rules.android.AndroidConfiguration.AndroidAaptVersion;
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.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.rules.java.ProguardHelper;
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.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.syntax.Type;
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_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_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_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";

  /** 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();

  /** 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 List<BuildOptions> split(BuildOptions buildOptions) {

      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 ImmutableList.of(buildOptions);

        } else {

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

      } else {

        ImmutableList.Builder<BuildOptions> result = ImmutableList.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.add(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(SkylarkPrinter 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);

          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(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")))
          .add(
              attr("feature_of", LABEL)
                  .allowedRuleClasses("android_binary")
                  .allowedFileTypes()
                  .undocumented("experimental, see b/36226333"))
          .add(
              attr("feature_after", LABEL)
                  .allowedRuleClasses("android_binary")
                  .allowedFileTypes()
                  .undocumented("experimental, see b/36226333"))
          /* <!-- #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. Currently only supported for local resources (not android_resources).
          <!-- #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_optimizers", LABEL_LIST)
                  .cfg(HostTransition.createFactory())
                  .value(JavaSemantics.BYTECODE_OPTIMIZERS))
          // 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))
          /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(aapt_version) -->
          Select the version of aapt for this rule.<br/>
          Possible values:
          <ul>
              <li><code>aapt_version = "aapt"</code>: Use aapt (deprecated).</li>
              <li><code>aapt_version = "aapt2"</code>: Use aapt2. This provides improved
                incremental resource processing, smaller apks and more.</li>
          </ul>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("aapt_version", STRING)
                  .allowedValues(new AllowedValueSet(AndroidAaptVersion.getAttributeValues()))
                  .value(AndroidAaptVersion.getRuleAttributeDefault()))
          .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")))
          .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();
    }
  }
}
