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

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

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

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

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

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

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

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

  public static final String NOCOMPRESS_EXTENSIONS_ATTR = "nocompress_extensions";

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

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

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

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

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

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

      androidOptions.configurationDistinguisher = ConfigurationDistinguisher.ANDROID;
    }

    @Override
    public Map<String, 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 ImmutableMap.of(buildOptions.get(CoreOptions.class).cpu, buildOptions);

        } else {

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

      } else {

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

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

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

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

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

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

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

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

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

  public static final SafeImplicitOutputsFunction ANDROID_BINARY_IMPLICIT_OUTPUTS =
      new SafeImplicitOutputsFunction() {

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

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

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

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

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

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

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

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

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

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

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

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

    private final AndroidNeverlinkAspect androidNeverlinkAspect;
    private final DexArchiveAspect dexArchiveAspect;

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

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

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

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

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

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

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

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

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

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

    private final Label[] compatibleWithAndroidEnvironments;

    private final Class<? extends AndroidToolsDefaultsJar> factoryClass;

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

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

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