// 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.java;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType.UNQUOTED;
import static com.google.devtools.build.lib.rules.java.JavaCompileActionBuilder.UTF8_ENVIRONMENT;
import static java.nio.charset.StandardCharsets.ISO_8859_1;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.actions.AbstractAction;
import com.google.devtools.build.lib.actions.ActionEnvironment;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLines;
import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier;
import com.google.devtools.build.lib.actions.ExecutionRequirements;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.PathMapper;
import com.google.devtools.build.lib.actions.ResourceSetOrBuilder;
import com.google.devtools.build.lib.actions.RunfilesSupplier;
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.PathMappers;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.CoreOptionConverters.StrictDepsMode;
import com.google.devtools.build.lib.analysis.config.CoreOptions.OutputPathsMode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.rules.java.JavaCompileAction.ProgressMessage;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode;
import com.google.devtools.build.lib.rules.java.JavaPluginInfo.JavaPluginData;
import com.google.devtools.build.lib.util.OnDemandString;
import com.google.devtools.build.lib.view.proto.Deps;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import javax.annotation.Nullable;

/**
 * Action for Java header compilation, to be used if --java_header_compilation is enabled.
 *
 * <p>The header compiler consumes the inputs of a java compilation, and produces an interface jar
 * that can be used as a compile-time jar by upstream targets. The header interface jar is
 * equivalent to the output of ijar, but unlike ijar the header compiler operates directly on Java
 * source files instead post-processing the class outputs of the compilation. Compiling the
 * interface jar from source moves javac off the build's critical path.
 *
 * <p>The implementation of the header compiler tool can be found under {@code
 * //src/java_tools/buildjar/java/com/google/devtools/build/java/turbine}.
 */
public final class JavaHeaderCompileAction extends SpawnAction {

  private static final String DIRECT_CLASSPATH_MNEMONIC = "Turbine";

  private final boolean insertDependencies;
  private final NestedSet<Artifact> additionalArtifactsForPathMapping;

  private JavaHeaderCompileAction(
      ActionOwner owner,
      NestedSet<Artifact> tools,
      NestedSet<Artifact> inputs,
      Iterable<? extends Artifact> outputs,
      ResourceSetOrBuilder resourceSetOrBuilder,
      CommandLines commandLines,
      ActionEnvironment env,
      ImmutableMap<String, String> executionInfo,
      CharSequence progressMessage,
      RunfilesSupplier runfilesSupplier,
      String mnemonic,
      OutputPathsMode outputPathsMode,
      boolean insertDependencies,
      NestedSet<Artifact> additionalArtifactsForPathMapping) {
    super(
        owner,
        tools,
        inputs,
        outputs,
        resourceSetOrBuilder,
        commandLines,
        env,
        executionInfo,
        progressMessage,
        runfilesSupplier,
        mnemonic,
        outputPathsMode);
    this.insertDependencies = insertDependencies;
    this.additionalArtifactsForPathMapping = additionalArtifactsForPathMapping;
  }

  @Override
  public NestedSet<Artifact> getAdditionalArtifactsForPathMapping() {
    return additionalArtifactsForPathMapping;
  }

  @Override
  protected void afterExecute(
      ActionExecutionContext context, List<SpawnResult> spawnResults, PathMapper pathMapper) {
    SpawnResult spawnResult = Iterables.getOnlyElement(spawnResults);
    Artifact outputDepsProto = Iterables.get(getOutputs(), 1);
    try {
      Deps.Dependencies fullOutputDeps =
          JavaCompileAction.createFullOutputDeps(
              spawnResult,
              outputDepsProto,
              getInputs(),
              getAdditionalArtifactsForPathMapping(),
              context,
              pathMapper);
      JavaCompileActionContext javaContext = context.getContext(JavaCompileActionContext.class);
      if (insertDependencies && javaContext != null) {
        javaContext.insertDependencies(outputDepsProto, fullOutputDeps);
      }
    } catch (IOException e) {
      // Left empty. If we cannot read the .jdeps file now, we will read it later or throw an
      // appropriate error then.
    }
  }

  public static Builder newBuilder(RuleContext ruleContext) {
    return new Builder(ruleContext);
  }

  /** Builder for {@link JavaHeaderCompileAction}. */
  public static final class Builder {

    private static final ParamFileInfo PARAM_FILE_INFO =
        ParamFileInfo.builder(UNQUOTED).setCharset(ISO_8859_1).build();

    private final RuleContext ruleContext;

    private Artifact outputJar;
    // Only non-null before set.
    private Artifact outputDepsProto;
    @Nullable private Artifact manifestOutput;
    @Nullable private Artifact gensrcOutputJar;
    @Nullable private Artifact resourceOutputJar;
    private ImmutableSet<Artifact> additionalOutputs = ImmutableSet.of();
    private ImmutableSet<Artifact> sourceFiles = ImmutableSet.of();
    private ImmutableList<Artifact> sourceJars = ImmutableList.of();
    private NestedSet<Artifact> classpathEntries =
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
    private NestedSet<Artifact> bootclasspathEntries =
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
    @Nullable private Label targetLabel;
    @Nullable private String injectingRuleKind;
    private StrictDepsMode strictJavaDeps = StrictDepsMode.OFF;
    private NestedSet<Artifact> directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
    private NestedSet<Artifact> compileTimeDependencyArtifacts =
        NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    private ImmutableList<String> javacOpts = ImmutableList.of();
    private boolean addTurbineHjarJavacOpt = false;
    private JavaPluginData plugins = JavaPluginData.empty();

    private ImmutableList<Artifact> additionalInputs = ImmutableList.of();
    private NestedSet<Artifact> toolsJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);

    private boolean enableHeaderCompilerDirect = true;

    private boolean enableDirectClasspath = true;

    private Builder(RuleContext ruleContext) {
      this.ruleContext = ruleContext;
    }

    /** Sets the output jdeps file. */
    @CanIgnoreReturnValue
    public Builder setOutputDepsProto(Artifact outputDepsProto) {
      this.outputDepsProto = checkNotNull(outputDepsProto);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder setManifestOutput(@Nullable Artifact manifestOutput) {
      this.manifestOutput = manifestOutput;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder setGensrcOutputJar(@Nullable Artifact gensrcOutputJar) {
      this.gensrcOutputJar = gensrcOutputJar;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder setResourceOutputJar(@Nullable Artifact resourceOutputJar) {
      this.resourceOutputJar = resourceOutputJar;
      return this;
    }

    /** Sets the direct dependency artifacts. */
    @CanIgnoreReturnValue
    public Builder setDirectJars(NestedSet<Artifact> directJars) {
      checkNotNull(directJars, "directJars must not be null");
      this.directJars = directJars;
      return this;
    }

    /** Sets the .jdeps artifacts for direct dependencies. */
    @CanIgnoreReturnValue
    public Builder setCompileTimeDependencyArtifacts(NestedSet<Artifact> dependencyArtifacts) {
      checkNotNull(dependencyArtifacts, "dependencyArtifacts must not be null");
      this.compileTimeDependencyArtifacts = dependencyArtifacts;
      return this;
    }

    /** Sets Java compiler flags. */
    @CanIgnoreReturnValue
    public Builder setJavacOpts(ImmutableList<String> javacOpts) {
      this.javacOpts = checkNotNull(javacOpts);
      return this;
    }

    /**
     * Adds {@code -Aexperimental_turbine_hjar} to Java compiler flags without creating an entirely
     * new list.
     */
    @CanIgnoreReturnValue
    public Builder addTurbineHjarJavacOpt() {
      this.addTurbineHjarJavacOpt = true;
      return this;
    }

    /** Sets the output jar. */
    @CanIgnoreReturnValue
    public Builder setOutputJar(Artifact outputJar) {
      checkNotNull(outputJar, "outputJar must not be null");
      this.outputJar = outputJar;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder setAdditionalOutputs(ImmutableSet<Artifact> outputs) {
      checkNotNull(outputs, "outputs must not be null");
      this.additionalOutputs = outputs;
      return this;
    }

    /** Adds Java source files to compile. */
    @CanIgnoreReturnValue
    public Builder setSourceFiles(ImmutableSet<Artifact> sourceFiles) {
      checkNotNull(sourceFiles, "sourceFiles must not be null");
      this.sourceFiles = sourceFiles;
      return this;
    }

    /** Adds a jar archive of Java sources to compile. */
    @CanIgnoreReturnValue
    public Builder setSourceJars(ImmutableList<Artifact> sourceJars) {
      checkNotNull(sourceJars, "sourceJars must not be null");
      this.sourceJars = sourceJars;
      return this;
    }

    /** Sets the compilation classpath entries. */
    @CanIgnoreReturnValue
    public Builder setClasspathEntries(NestedSet<Artifact> classpathEntries) {
      checkNotNull(classpathEntries, "classpathEntries must not be null");
      this.classpathEntries = classpathEntries;
      return this;
    }

    /** Sets the compilation bootclasspath entries. */
    @CanIgnoreReturnValue
    public Builder setBootclasspathEntries(NestedSet<Artifact> bootclasspathEntries) {
      checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
      this.bootclasspathEntries = bootclasspathEntries;
      return this;
    }

    /** Sets the annotation processors classpath entries. */
    @CanIgnoreReturnValue
    public Builder setPlugins(JavaPluginData plugins) {
      checkNotNull(plugins, "plugins must not be null");
      checkState(this.plugins.isEmpty());
      this.plugins = plugins;
      return this;
    }

    /** Sets the label of the target being compiled. */
    @CanIgnoreReturnValue
    public Builder setTargetLabel(@Nullable Label targetLabel) {
      this.targetLabel = targetLabel;
      return this;
    }

    /** Sets the injecting rule kind of the target being compiled. */
    @CanIgnoreReturnValue
    public Builder setInjectingRuleKind(@Nullable String injectingRuleKind) {
      this.injectingRuleKind = injectingRuleKind;
      return this;
    }

    /** Sets the Strict Java Deps mode. */
    @CanIgnoreReturnValue
    public Builder setStrictJavaDeps(StrictDepsMode strictJavaDeps) {
      checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
      this.strictJavaDeps = strictJavaDeps;
      return this;
    }

    /** Sets additional inputs, e.g. for databinding support. */
    @CanIgnoreReturnValue
    public Builder setAdditionalInputs(ImmutableList<Artifact> additionalInputs) {
      checkNotNull(additionalInputs, "additionalInputs must not be null");
      this.additionalInputs = additionalInputs;
      return this;
    }

    /** Sets the tools jars. */
    @CanIgnoreReturnValue
    public Builder setToolsJars(NestedSet<Artifact> toolsJars) {
      checkNotNull(toolsJars, "toolsJars must not be null");
      this.toolsJars = toolsJars;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder enableHeaderCompilerDirect(boolean enableHeaderCompilerDirect) {
      this.enableHeaderCompilerDirect = enableHeaderCompilerDirect;
      return this;
    }

    @CanIgnoreReturnValue
    public Builder enableDirectClasspath(boolean enableDirectClasspath) {
      this.enableDirectClasspath = enableDirectClasspath;
      return this;
    }

    /** Builds and registers the action for a header compilation. */
    public void build(JavaToolchainProvider javaToolchain) throws RuleErrorException {
      checkNotNull(outputDepsProto, "outputDepsProto must not be null");
      checkNotNull(sourceFiles, "sourceFiles must not be null");
      checkNotNull(sourceJars, "sourceJars must not be null");
      checkNotNull(classpathEntries, "classpathEntries must not be null");
      checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
      checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
      checkNotNull(directJars, "directJars must not be null");
      checkNotNull(
          compileTimeDependencyArtifacts, "compileTimeDependencyArtifacts must not be null");

      // Invariant: if strictJavaDeps is OFF, then directJars and
      // dependencyArtifacts are ignored
      if (strictJavaDeps == StrictDepsMode.OFF) {
        directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
        compileTimeDependencyArtifacts = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
      }

      // Enable the direct classpath optimization if there are no annotation processors.
      // N.B. we only check if the processor classes are empty, we don't care if there is plugin
      // data or dependencies if there are no annotation processors to run. This differs from
      // javac where java_plugin may be used with processor_class unset to declare Error Prone
      // plugins.
      boolean useDirectClasspath = enableDirectClasspath && plugins.processorClasses().isEmpty();

      // Use the optimized 'direct' implementation if it is available, and either there are no
      // annotation processors or they are built in to the tool and listed in
      // java_toolchain.header_compiler_direct_processors.
      ImmutableSet<String> processorClasses = plugins.processorClasses().toSet();
      boolean useHeaderCompilerDirect =
          enableHeaderCompilerDirect
              && javaToolchain.getHeaderCompilerDirect() != null
              && javaToolchain.getHeaderCompilerBuiltinProcessors().containsAll(processorClasses);
      JavaConfiguration javaConfiguration =
          ruleContext.getConfiguration().getFragment(JavaConfiguration.class);
      JavaClasspathMode classpathMode = javaConfiguration.getReduceJavaClasspath();
      if (!Collections.disjoint(
          processorClasses, javaToolchain.getReducedClasspathIncompatibleProcessors())) {
        classpathMode = JavaClasspathMode.OFF;
      }

      ActionEnvironment actionEnvironment =
          ruleContext
              .getConfiguration()
              .getActionEnvironment()
              .withAdditionalFixedVariables(UTF8_ENVIRONMENT);

      OnDemandString progressMessage =
          new ProgressMessage(
              /* prefix= */ "Compiling Java headers",
              /* output= */ outputJar,
              /* sourceFiles= */ sourceFiles,
              /* sourceJars= */ sourceJars,
              /* plugins= */ plugins);

      ImmutableSet.Builder<Artifact> outputs =
          ImmutableSet.<Artifact>builder()
              .add(outputJar)
              .add(outputDepsProto)
              .addAll(additionalOutputs);
      Stream.of(gensrcOutputJar, resourceOutputJar, manifestOutput)
          .filter(Objects::nonNull)
          .forEachOrdered(outputs::add);

      NestedSetBuilder<Artifact> mandatoryInputsBuilder =
          NestedSetBuilder.<Artifact>stableOrder()
              .addAll(additionalInputs)
              .addTransitive(bootclasspathEntries)
              .addAll(sourceJars)
              .addAll(sourceFiles)
              .addTransitive(toolsJars);

      JavaToolchainTool headerCompiler =
          useHeaderCompilerDirect
              ? javaToolchain.getHeaderCompilerDirect()
              : javaToolchain.getHeaderCompiler();
      // The header compiler is either a jar file that needs to be executed using
      // `java -jar <path>`, or an executable that can be run directly.
      headerCompiler.addInputs(javaToolchain, mandatoryInputsBuilder);
      CustomCommandLine.Builder commandLine =
          CustomCommandLine.builder()
              .addExecPath("--output", outputJar)
              .addExecPath("--gensrc_output", gensrcOutputJar)
              .addExecPath("--resource_output", resourceOutputJar)
              .addExecPath("--output_manifest_proto", manifestOutput)
              .addExecPath("--output_deps", outputDepsProto)
              .addExecPaths("--bootclasspath", bootclasspathEntries)
              .addExecPaths("--sources", sourceFiles)
              .addExecPaths("--source_jars", sourceJars)
              .add("--injecting_rule_kind", injectingRuleKind);

      if (!javacOpts.isEmpty() || addTurbineHjarJavacOpt) {
        commandLine.add("--javacopts");
        if (!javacOpts.isEmpty()) {
          commandLine.addObject(javacOpts);
        }
        if (addTurbineHjarJavacOpt) {
          commandLine.add("-Aexperimental_turbine_hjar");
        }
        // terminate --javacopts with `--` to support javac flags that start with `--`
        commandLine.add("--");
      }

      if (targetLabel != null) {
        commandLine.add("--target_label");
        if (targetLabel.getRepository().isMain()) {
          commandLine.addLabel(targetLabel);
        } else {
          // @-prefixed strings will be assumed to be params filenames and expanded,
          // so add an extra @ to escape it.
          commandLine.addPrefixedLabel("@", targetLabel);
        }
      }

      ImmutableMap.Builder<String, String> executionInfo = ImmutableMap.builder();
      executionInfo.putAll(
          ruleContext
              .getConfiguration()
              .modifiedExecutionInfo(
                  ImmutableMap.of(ExecutionRequirements.SUPPORTS_PATH_MAPPING, "1"),
                  JavaCompileActionBuilder.MNEMONIC));
      executionInfo.putAll(
          TargetUtils.getExecutionInfo(
              ruleContext.getRule(), ruleContext.isAllowTagsPropagation()));
      if (javaConfiguration.inmemoryJdepsFiles()) {
        executionInfo.put(
            ExecutionRequirements.REMOTE_EXECUTION_INLINE_OUTPUTS,
            outputDepsProto.getExecPathString());
      }

      if (useDirectClasspath) {
        NestedSet<Artifact> classpath;
        NestedSet<Artifact> additionalArtifactsForPathMapping;
        if (!directJars.isEmpty() || classpathEntries.isEmpty()) {
          classpath = directJars;
          // When using the direct classpath optimization, Turbine generates .jdeps entries based on
          // the transitive dependency information packages into META-INF/TRANSITIVE. When path
          // mapping is used, these entries may have been subject to it when they were generated.
          // Since the contents of that directory are not unmapped, we need to instead unmap the
          // paths emitted in the .jdeps file, which requires knowing the full list of artifact
          // paths even if they aren't inputs to the current action.
          // https://github.com/google/turbine/commit/f9f2decee04a3c651671f7488a7c9d7952df88c8
          additionalArtifactsForPathMapping = classpathEntries;
        } else {
          classpath = classpathEntries;
          additionalArtifactsForPathMapping = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
        }
        mandatoryInputsBuilder.addTransitive(classpath);

        commandLine.addExecPaths("--classpath", classpath);
        commandLine.add("--reduce_classpath_mode", "NONE");

        NestedSet<Artifact> allInputs = mandatoryInputsBuilder.build();
        CustomCommandLine executableLine = headerCompiler.getCommandLine(javaToolchain);

        ruleContext.registerAction(
            new JavaHeaderCompileAction(
                /* owner= */ ruleContext.getActionOwner(),
                /* tools= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
                /* inputs= */ allInputs,
                /* outputs= */ outputs.build(),
                /* resourceSetOrBuilder= */ AbstractAction.DEFAULT_RESOURCE_SET,
                /* commandLines= */ CommandLines.builder()
                    .addCommandLine(executableLine)
                    .addCommandLine(commandLine.build(), PARAM_FILE_INFO)
                    .build(),
                /* env= */ actionEnvironment,
                /* executionInfo= */ ruleContext
                    .getConfiguration()
                    .modifiedExecutionInfo(
                        executionInfo.buildKeepingLast(), DIRECT_CLASSPATH_MNEMONIC),
                /* progressMessage= */ progressMessage,
                /* runfilesSupplier= */ EmptyRunfilesSupplier.INSTANCE,

                /* mnemonic= */ DIRECT_CLASSPATH_MNEMONIC,
                /* outputPathsMode= */ PathMappers.getOutputPathsMode(
                    ruleContext.getConfiguration()),
                // If classPathMode == BAZEL, also make sure to inject the dependencies to be
                // available to downstream actions. Else just do enough work to locally create the
                // full .jdeps from the .stripped .jdeps produced on the executor.
                /* insertDependencies= */ classpathMode == JavaClasspathMode.BAZEL,
                additionalArtifactsForPathMapping));
        return;
      }

      // If we get here the action requires annotation processing, so add additional inputs and
      // flags needed for the javac-based header compiler implementations that supports
      // annotation processing.

      if (!useHeaderCompilerDirect) {
        mandatoryInputsBuilder.addTransitive(plugins.processorClasspath());
        mandatoryInputsBuilder.addTransitive(plugins.data());
      }

      commandLine.addAll(
          "--builtin_processors",
          Sets.intersection(
              plugins.processorClasses().toSet(),
              javaToolchain.getHeaderCompilerBuiltinProcessors()));
      commandLine.addAll("--processors", plugins.processorClasses());
      if (!useHeaderCompilerDirect) {
        commandLine.addExecPaths("--processorpath", plugins.processorClasspath());
      }
      if (strictJavaDeps != StrictDepsMode.OFF) {
        commandLine.addExecPaths("--direct_dependencies", directJars);
      }

      NestedSet<Artifact> mandatoryInputs = mandatoryInputsBuilder.build();

      CustomCommandLine executableLine = headerCompiler.getCommandLine(javaToolchain);

      ruleContext.registerAction(
          new JavaCompileAction(
              /* compilationType= */ JavaCompileAction.CompilationType.TURBINE,
              /* owner= */ ruleContext.getActionOwner(),
              /* tools= */ toolsJars,
              /* progressMessage= */ progressMessage,
              /* mandatoryInputs= */ mandatoryInputs,
              /* transitiveInputs= */ classpathEntries,
              /* directJars= */ directJars,
              /* outputs= */ outputs.build(),
              /* executionInfo= */ executionInfo.buildKeepingLast(),
              /* extraActionInfoSupplier= */ null,
              /* executableLine= */ executableLine,
              /* flagLine= */ commandLine.build(),
              /* configuration= */ ruleContext.getConfiguration(),
              /* dependencyArtifacts= */ compileTimeDependencyArtifacts,
              /* outputDepsProto= */ outputDepsProto,
              /* classpathMode= */ classpathMode));
    }
  }
}
