// Copyright 2016 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 com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.ActionConflictException;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.ExecutionRequirements;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.android.databinding.DataBinding;
import com.google.devtools.build.lib.rules.android.databinding.DataBindingV2Provider;
import com.google.devtools.build.lib.rules.java.ImportDepsCheckActionBuilder;
import com.google.devtools.build.lib.rules.java.JavaCommon;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaCompilationArtifacts;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.ImportDepsCheckingLevel;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.JavaOutput;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaToolchainProvider;
import com.google.devtools.build.lib.rules.java.ProguardLibrary;
import com.google.devtools.build.lib.rules.java.ProguardSpecProvider;
import com.google.devtools.build.lib.starlarkbuildapi.android.DataBindingV2ProviderApi;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * An implementation for the aar_import rule.
 *
 * <p>AAR files are zip archives that contain an Android Manifest, JARs, resources, assets, native
 * libraries, Proguard configuration and lint jars. Currently the aar_import rule supports AARs with
 * an AndroidManifest.xml, classes.jar, libs/, res/ and jni/. Assets are not yet supported.
 *
 * @see <a href="http://tools.android.com/tech-docs/new-build-system/aar-format">AAR Format</a>
 */
public class AarImport implements RuleConfiguredTargetFactory {
  private static final String ANDROID_MANIFEST = "AndroidManifest.xml";
  private static final String MERGED_JAR = "classes_and_libs_merged.jar";
  private static final String PROGUARD_SPEC = "proguard.txt";

  private static final ParamFileInfo WORKERS_FORCED_PARAM_FILE_INFO =
      ParamFileInfo.builder(ParameterFile.ParameterFileType.UNQUOTED).setUseAlways(true).build();

  private final JavaSemantics javaSemantics;
  private final AndroidSemantics androidSemantics;

  protected AarImport(JavaSemantics javaSemantics, AndroidSemantics androidSemantics) {
    this.javaSemantics = javaSemantics;
    this.androidSemantics = androidSemantics;
  }

  @Override
  @Nullable
  public ConfiguredTarget create(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException, ActionConflictException {
    androidSemantics.checkForMigrationTag(ruleContext);
    AndroidSdkProvider.verifyPresence(ruleContext);

    RuleConfiguredTargetBuilder ruleBuilder = new RuleConfiguredTargetBuilder(ruleContext);
    Artifact aar = ruleContext.getPrerequisiteArtifact("aar");

    Artifact allAarJars = createAarTreeArtifact(ruleContext, "jars");
    Artifact jarMergingParams = createAarArtifact(ruleContext, "jar_merging_params");
    ruleContext.registerAction(
        createAarEmbeddedJarsExtractorActions(ruleContext, aar, allAarJars, jarMergingParams));
    Artifact mergedJar = createAarArtifact(ruleContext, MERGED_JAR);
    ruleContext.registerAction(
        createAarJarsMergingActions(ruleContext, allAarJars, mergedJar, jarMergingParams));

    // AndroidManifest.xml is required in every AAR.
    Artifact androidManifestArtifact = createAarArtifact(ruleContext, ANDROID_MANIFEST);

    SpecialArtifact resources = createAarTreeArtifact(ruleContext, "resources");
    SpecialArtifact assets = createAarTreeArtifact(ruleContext, "assets");
    SpecialArtifact databindingBrFiles = createAarTreeArtifact(ruleContext, "data-binding-br");
    SpecialArtifact databindingSetterStoreFiles =
        createAarTreeArtifact(ruleContext, "data-binding-setter_store");
    ruleContext.registerAction(
        createAarResourcesExtractorActions(
            ruleContext, aar, resources, assets, databindingBrFiles, databindingSetterStoreFiles));

    AndroidDataContext dataContext = androidSemantics.makeContextForNative(ruleContext);
    StampedAndroidManifest manifest = AndroidManifest.forAarImport(androidManifestArtifact);

    boolean neverlink = JavaCommon.isNeverLink(ruleContext);

    ValidatedAndroidResources validatedResources =
        AndroidResources.forAarImport(resources)
            .process(
                ruleContext,
                dataContext,
                manifest,
                DataBinding.contextFrom(ruleContext, dataContext.getAndroidConfig()),
                neverlink);

    MergedAndroidAssets mergedAssets =
        AndroidAssets.forAarImport(assets)
            .process(dataContext, AssetDependencies.fromRuleDeps(ruleContext, neverlink));

    ResourceApk resourceApk = ResourceApk.of(validatedResources, mergedAssets, null, null);

    // There isn't really any use case for building an aar_import target on its own, so the files to
    // build could be empty. The R class JAR and merged JARs are added here as a check for Bazel
    // developers so that `bazel build java/com/my_aar_import` will fail if the resource processing
    // or JAR merging steps fail.
    NestedSet<Artifact> filesToBuild =
        NestedSetBuilder.<Artifact>stableOrder()
            .add(resourceApk.getValidatedResources().getJavaClassJar())
            .add(mergedJar)
            .build();

    Artifact nativeLibs = createAarArtifact(ruleContext, "native_libs.zip");
    ruleContext.registerAction(createAarNativeLibsFilterActions(ruleContext, aar, nativeLibs));

    JavaRuleOutputJarsProvider.Builder jarProviderBuilder =
        new JavaRuleOutputJarsProvider.Builder()
            .addJavaOutput(JavaOutput.builder().setClassJar(mergedJar).build());

    ImmutableList<TransitiveInfoCollection> targets =
        ImmutableList.<TransitiveInfoCollection>builder()
            .addAll(ruleContext.getPrerequisites("exports"))
            .addAll(ruleContext.getPrerequisites("deps"))
            .build();
    JavaCommon common =
        new JavaCommon(
            ruleContext,
            javaSemantics,
            /* sources = */ ImmutableList.of(),
            /* compileDeps = */ targets,
            /* runtimeDeps = */ targets,
            /* bothDeps = */ targets);
    androidSemantics.checkRule(ruleContext, common);

    JavaConfiguration javaConfig = ruleContext.getFragment(JavaConfiguration.class);
    JavaCompilationArtifacts.Builder javaCompilationArtifactsBuilder =
        new JavaCompilationArtifacts.Builder();

    javaCompilationArtifactsBuilder
        .addRuntimeJar(mergedJar)
        .addCompileTimeJarAsFullJar(mergedJar)
        // Allow direct dependents to compile against un-merged R classes
        .addCompileTimeJarAsFullJar(
            ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR));

    Artifact jdepsArtifact = null;
    // Don't register import deps checking actions if the level is off. Since it's off, the
    // check isn't useful anyway, so don't waste resources running it.
    if (javaConfig.getImportDepsCheckingLevel() != ImportDepsCheckingLevel.OFF) {
      jdepsArtifact = createAarArtifact(ruleContext, "jdeps.proto");
      javaCompilationArtifactsBuilder.setCompileTimeDependencies(jdepsArtifact);
      ImportDepsCheckActionBuilder.newBuilder()
          .bootclasspath(getBootclasspath(ruleContext))
          .declareDeps(getCompileTimeJarsFromCollection(targets, /*isDirect=*/ true))
          .transitiveDeps(getCompileTimeJarsFromCollection(targets, /*isDirect=*/ false))
          .checkJars(NestedSetBuilder.<Artifact>stableOrder().add(mergedJar).build())
          .importDepsCheckingLevel(javaConfig.getImportDepsCheckingLevel())
          .jdepsOutputArtifact(jdepsArtifact)
          .ruleLabel(ruleContext.getLabel())
          .buildAndRegister(ruleContext);
    }

    common.setJavaCompilationArtifacts(javaCompilationArtifactsBuilder.build());

    // We pass jdepsArtifact to create the action of extracting ANDROID_MANIFEST. Note that
    // this action does not need jdepsArtifact. The only reason is that we need to check the
    // dependencies of this aar_import, and we need to put its result on the build graph so that the
    // dependency checking action is called.
    ruleContext.registerAction(
        createSingleFileExtractorActions(
            ruleContext, aar, ANDROID_MANIFEST, jdepsArtifact, androidManifestArtifact));

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        common.collectJavaCompilationArgs(/* isNeverLink= */ JavaCommon.isNeverLink(ruleContext));

    // Wire up the source jar for the current target and transitive source jars from dependencies.
    ImmutableList<Artifact> srcJars = ImmutableList.of();
    Artifact srcJar = ruleContext.getPrerequisiteArtifact("srcjar");
    NestedSetBuilder<Artifact> transitiveJavaSourceJarBuilder = NestedSetBuilder.stableOrder();
    if (srcJar != null) {
      srcJars = ImmutableList.of(srcJar);
      transitiveJavaSourceJarBuilder.add(srcJar);
    }
    for (TransitiveInfoCollection target : ruleContext.getPrerequisites("exports")) {
      transitiveJavaSourceJarBuilder.addTransitive(JavaInfo.transitiveSourceJars(target));
    }
    NestedSet<Artifact> transitiveJavaSourceJars = transitiveJavaSourceJarBuilder.build();
    JavaSourceJarsProvider javaSourceJarsProvider =
        JavaSourceJarsProvider.create(transitiveJavaSourceJars, srcJars);

    JavaInfo.Builder javaInfoBuilder =
        JavaInfo.Builder.create()
            .setRuntimeJars(ImmutableList.of(mergedJar))
            .setJavaConstraints(ImmutableList.of("android"))
            .setNeverlink(JavaCommon.isNeverLink(ruleContext))
            .javaCompilationArgs(javaCompilationArgsProvider)
            .javaSourceJars(javaSourceJarsProvider)
            .javaRuleOutputs(jarProviderBuilder.build());

    common.addTransitiveInfoProviders(
        ruleBuilder, javaInfoBuilder, filesToBuild, /*classJar=*/ null);

    DataBindingV2Provider dataBindingV2Provider =
        createDatabindingProvider(ruleContext, databindingBrFiles, databindingSetterStoreFiles);

    resourceApk.addToConfiguredTargetBuilder(
        ruleBuilder,
        ruleContext.getLabel(),
        /* includeStarlarkApiProvider = */ false,
        /* isLibrary = */ true);

    ruleBuilder
        .setFilesToBuild(filesToBuild)
        .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
        .addNativeDeclaredProvider(dataBindingV2Provider)
        .addNativeDeclaredProvider(new ProguardSpecProvider(extractProguardSpecs(ruleContext, aar)))
        .addNativeDeclaredProvider(
            new AndroidNativeLibsInfo(
                AndroidCommon.collectTransitiveNativeLibs(ruleContext).add(nativeLibs).build()))
        .addStarlarkDeclaredProvider(javaInfoBuilder.build());
    if (jdepsArtifact != null) {
      // Add the deps check result so that we can unit test it.
      ruleBuilder.addOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL, jdepsArtifact);
    }
    return ruleBuilder.build();
  }

  private static NestedSet<Artifact> getCompileTimeJarsFromCollection(
      ImmutableList<TransitiveInfoCollection> deps, boolean isDirect) throws RuleErrorException {
    JavaCompilationArgsProvider provider = JavaCompilationArgsProvider.legacyFromTargets(deps);
    return isDirect ? provider.getDirectCompileTimeJars() : provider.getTransitiveCompileTimeJars();
  }

  /**
   * Collect Proguard Specs from transitives and proguard.txt if it exists in the AAR file. In the
   * case the proguard.txt file does exists, we need to extract it from the AAR file
   */
  private NestedSet<Artifact> extractProguardSpecs(RuleContext ruleContext, Artifact aar)
      throws RuleErrorException {

    NestedSet<Artifact> proguardSpecs =
        new ProguardLibrary(ruleContext).collectProguardSpecs(ImmutableSet.of("deps", "exports"));

    Artifact proguardSpecArtifact = createAarArtifact(ruleContext, PROGUARD_SPEC);

    ruleContext.registerAction(
        createAarEmbeddedProguardExtractorActions(ruleContext, aar, proguardSpecArtifact));

    NestedSetBuilder<Artifact> builder = NestedSetBuilder.naiveLinkOrder();
    return builder.addTransitive(proguardSpecs).add(proguardSpecArtifact).build();
  }

  private static boolean isPersistentAarExtractor(RuleContext ruleContext) {
    AndroidConfiguration androidConfig =
        ruleContext.getConfiguration().getFragment(AndroidConfiguration.class);
    return androidConfig.persistentAarExtractor();
  }

  /**
   * Returns either the worker param file or null depending on whether persistent worker mode is on.
   */
  @Nullable
  private static ParamFileInfo getParamFileInfo(RuleContext ruleContext) {
    return isPersistentAarExtractor(ruleContext) ? WORKERS_FORCED_PARAM_FILE_INFO : null;
  }

  /** Adds worker-related execution requirements if worker mode enabled. */
  private static void modifyExecutionInfo(
      RuleContext ruleContext, SpawnAction.Builder actionBuilder) {
    if (isPersistentAarExtractor(ruleContext)) {
      ImmutableMap.Builder<String, String> executionInfo = ImmutableMap.builder();
      executionInfo.putAll(ExecutionRequirements.WORKER_MODE_ENABLED);
      executionInfo.put(ExecutionRequirements.REQUIRES_WORKER_PROTOCOL, "json");
      actionBuilder.setExecutionInfo(executionInfo.buildOrThrow());
    }
  }

  /**
   * Creates action to extract embedded Proguard.txt from an AAR. If the file is not found, an empty
   * file will be created
   */
  private static SpawnAction createAarEmbeddedProguardExtractorActions(
      RuleContext ruleContext, Artifact aar, Artifact proguardSpecArtifact) {
    SpawnAction.Builder actionBuilder = new SpawnAction.Builder();
    ParamFileInfo paramFileInfo = getParamFileInfo(ruleContext);
    modifyExecutionInfo(ruleContext, actionBuilder);
    return actionBuilder
        .useDefaultShellEnvironment()
        .setExecutable(
            ruleContext.getExecutablePrerequisite(AarImportBaseRule.AAR_EMBEDDED_PROGUARD_EXTACTOR))
        .setMnemonic("AarEmbeddedProguardExtractor")
        .setProgressMessage("Extracting proguard.txt from %s", aar.getFilename())
        .addInput(aar)
        .addOutput(proguardSpecArtifact)
        .addCommandLine(
            CustomCommandLine.builder()
                .addExecPath("--input_aar", aar)
                .addExecPath("--output_proguard_file", proguardSpecArtifact)
                .build(),
            paramFileInfo)
        .build(ruleContext);
  }

  private NestedSet<Artifact> getBootclasspath(RuleContext ruleContext) throws RuleErrorException {
    if (AndroidCommon.getAndroidConfig(ruleContext).desugarJava8()) {
      return NestedSetBuilder.<Artifact>stableOrder()
          .addTransitive(
              ruleContext
                  .getPrerequisite("$desugar_java8_extra_bootclasspath")
                  .getProvider(FileProvider.class)
                  .getFilesToBuild())
          .add(AndroidSdkProvider.fromRuleContext(ruleContext).getAndroidJar())
          .build();
    } else {
      return NestedSetBuilder.<Artifact>stableOrder()
          .add(AndroidSdkProvider.fromRuleContext(ruleContext).getAndroidJar())
          .build();
    }
  }

  /**
   * Creates an action to extract a file (specified by the parameter filename) from an AAR file.
   * Note that the parameter jdepsOutputArtifact is not necessary for this action. Conversely, the
   * action of checking dependencies for aar_import needs this action instead. Therefore we add the
   * output artifact of import_deps_checker to this extraction action as input. Therefore, the
   * dependency checking will run each time.
   */
  private static SpawnAction createSingleFileExtractorActions(
      RuleContext ruleContext,
      Artifact aar,
      String filename,
      @Nullable Artifact jdepsOutputArtifact,
      Artifact outputArtifact) {
    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .useDefaultShellEnvironment()
            .setExecutable(ruleContext.getExecutablePrerequisite(AarImportBaseRule.ZIPPER))
            .setMnemonic("AarFileExtractor")
            .setProgressMessage("Extracting %s from %s", filename, aar.getFilename())
            .addInput(aar)
            .addOutput(outputArtifact)
            .addCommandLine(
                CustomCommandLine.builder()
                    .addExecPath("x", aar)
                    .addPath("-d", outputArtifact.getExecPath().getParentDirectory())
                    .addDynamicString(filename)
                    .build());
    if (jdepsOutputArtifact != null) {
      builder.addInput(jdepsOutputArtifact);
    }
    return builder.build(ruleContext);
  }

  private static SpawnAction createAarResourcesExtractorActions(
      RuleContext ruleContext,
      Artifact aar,
      Artifact resourcesDir,
      Artifact assetsDir,
      Artifact databindingBrFiles,
      Artifact databindingSetterStoreFiles) {

    SpawnAction.Builder actionBuilder = new SpawnAction.Builder();
    ParamFileInfo paramFileInfo = getParamFileInfo(ruleContext);
    modifyExecutionInfo(ruleContext, actionBuilder);
    return actionBuilder
        .useDefaultShellEnvironment()
        .setExecutable(
            ruleContext.getExecutablePrerequisite(AarImportBaseRule.AAR_RESOURCES_EXTRACTOR))
        .setMnemonic("AarResourcesExtractor")
        .setProgressMessage("Extracting AAR Resources for %{label}")
        .addInput(aar)
        .addOutput(resourcesDir)
        .addOutput(assetsDir)
        .addOutput(databindingBrFiles)
        .addOutput(databindingSetterStoreFiles)
        .addCommandLine(
            CustomCommandLine.builder()
                .addExecPath("--input_aar", aar)
                .addExecPath("--output_res_dir", resourcesDir)
                .addExecPath("--output_assets_dir", assetsDir)
                .addExecPath("--output_databinding_br_dir", databindingBrFiles)
                .addExecPath("--output_databinding_setter_store_dir", databindingSetterStoreFiles)
                .build(),
            paramFileInfo)
        .build(ruleContext);
  }

  private static SpawnAction createAarEmbeddedJarsExtractorActions(
      RuleContext ruleContext,
      Artifact aar,
      Artifact jarsTreeArtifact,
      Artifact singleJarParamFile) {
    SpawnAction.Builder actionBuilder = new SpawnAction.Builder();
    ParamFileInfo paramFileInfo = getParamFileInfo(ruleContext);
    modifyExecutionInfo(ruleContext, actionBuilder);
    return actionBuilder
        .useDefaultShellEnvironment()
        .setExecutable(
            ruleContext.getExecutablePrerequisite(AarImportBaseRule.AAR_EMBEDDED_JARS_EXTACTOR))
        .setMnemonic("AarEmbeddedJarsExtractor")
        .setProgressMessage("Extracting classes.jar and libs/*.jar from %s", aar.getFilename())
        .addInput(aar)
        .addOutput(jarsTreeArtifact)
        .addOutput(singleJarParamFile)
        .addCommandLine(
            CustomCommandLine.builder()
                .addExecPath("--input_aar", aar)
                .addExecPath("--output_dir", jarsTreeArtifact)
                .addExecPath("--output_singlejar_param_file", singleJarParamFile)
                .build(),
            paramFileInfo)
        .build(ruleContext);
  }

  private static SpawnAction createAarJarsMergingActions(
      RuleContext ruleContext, Artifact jarsTreeArtifact, Artifact mergedJar, Artifact paramFile)
      throws RuleErrorException {
    SpawnAction.Builder builder = new SpawnAction.Builder().useDefaultShellEnvironment();
    FilesToRunProvider singleJar = JavaToolchainProvider.from(ruleContext).getSingleJar();
    return builder
        .setExecutable(singleJar)
        .setMnemonic("AarJarsMerger")
        .setProgressMessage("Merging AAR embedded jars for %{label}")
        .addInput(jarsTreeArtifact)
        .addOutput(mergedJar)
        .addInput(paramFile)
        .addCommandLine(
            CustomCommandLine.builder()
                .addExecPath("--output", mergedJar)
                .add("--dont_change_compression")
                .add("--normalize")
                .addPrefixedExecPath("@", paramFile)
                .build())
        .build(ruleContext);
  }

  private static SpawnAction createAarNativeLibsFilterActions(
      RuleContext ruleContext, Artifact aar, Artifact outputZip) throws RuleErrorException {

    String cpu = null;
      // Maps a CPU name as used in an AAR to the corresponding CPU constraint.
      ImmutableMap<String, ConstraintValueInfo> aarCpuToConstraint =
          ImmutableMap.of(
              "arm64-v8a",
                  ruleContext.getPrerequisite("$constraint_arm64", ConstraintValueInfo.PROVIDER),
              "armeabi-v7a",
                  ruleContext.getPrerequisite("$constraint_armv7", ConstraintValueInfo.PROVIDER),
              "x86", ruleContext.getPrerequisite("$constraint_x86", ConstraintValueInfo.PROVIDER),
              "x86_64",
                  ruleContext.getPrerequisite("$constraint_x86_64", ConstraintValueInfo.PROVIDER));

      for (Map.Entry<String, ConstraintValueInfo> e : aarCpuToConstraint.entrySet()) {
        if (ruleContext.targetPlatformHasConstraint(e.getValue())) {
          cpu = e.getKey();
          break;
        }
      }

      if (cpu == null) {
        throw ruleContext.throwWithRuleError(
            String.format(
                "Target platform %s does not match one of the applicable CPU constraints for"
                    + " aar_import %s. Applicable CPU constraints are listed in"
                    + " https://blog.bazel.build/2023/11/15/android-platforms.html",
                ruleContext.getToolchainContexts().getTargetPlatform().label(),
                ruleContext.getLabel()));
      }

    SpawnAction.Builder actionBuilder = new SpawnAction.Builder();
    ParamFileInfo paramFileInfo = getParamFileInfo(ruleContext);
    modifyExecutionInfo(ruleContext, actionBuilder);
    return actionBuilder
        .useDefaultShellEnvironment()
        .setExecutable(
            ruleContext.getExecutablePrerequisite(AarImportBaseRule.AAR_NATIVE_LIBS_ZIP_CREATOR))
        .setMnemonic("AarNativeLibsFilter")
        .setProgressMessage("Filtering AAR native libs by architecture for %{label}")
        .addInput(aar)
        .addOutput(outputZip)
        .addCommandLine(
            CustomCommandLine.builder()
                .addExecPath("--input_aar", aar)
                .add("--cpu", cpu)
                .addExecPath("--output_zip", outputZip)
                .build(),
            paramFileInfo)
        .build(ruleContext);
  }

  private static DataBindingV2Provider createDatabindingProvider(
      RuleContext ruleContext,
      SpecialArtifact databindingBrFiles,
      SpecialArtifact databindingSetterStoreFiles) {

    List<? extends DataBindingV2ProviderApi<Artifact>> databindingProvidersFromDeps =
        ruleContext.getPrerequisites("deps", DataBindingV2Provider.PROVIDER);

    Iterable<? extends DataBindingV2ProviderApi<Artifact>> databindingProvidersFromExports =
        ruleContext.getPrerequisites("exports", DataBindingV2Provider.PROVIDER);

    DataBindingV2Provider dataBindingV2Provider =
        DataBindingV2Provider.createProvider(
            databindingSetterStoreFiles,
            /* classInfoFile= */ null,
            databindingBrFiles,
            ruleContext.getRule().getLabel().toString(),
            // TODO: The aar's Java package isn't available during analysis (it's in the manifest
            // inside the aar, or can maybe be inferred elsewhere). This is mostly used for
            // constructing  a nice error message if multiple android_library rules try to generate
            // databinding conflicting classes into the same Java package, so it's not as important
            // for aars.
            /* javaPackage= */ null,
            databindingProvidersFromDeps,
            databindingProvidersFromExports);

    return dataBindingV2Provider;
  }

  private static Artifact createAarArtifact(RuleContext ruleContext, String name) {
    return ruleContext.getUniqueDirectoryArtifact(
        "_aar", name, ruleContext.getBinOrGenfilesDirectory());
  }

  private static SpecialArtifact createAarTreeArtifact(RuleContext ruleContext, String name) {
    PathFragment rootRelativePath = ruleContext.getUniqueDirectory("_aar/unzipped/" + name);
    return ruleContext.getTreeArtifact(rootRelativePath, ruleContext.getBinOrGenfilesDirectory());
  }
}
