Optimize header compilation for direct-classpath actions

Add java_toolchain.header_compiler_direct for an optimized header compiler that
only supports direct-classpath, non-annotation processing header compilation
actions.

PiperOrigin-RevId: 210783139
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java
index 8cbe594..f3470f0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java
@@ -242,7 +242,6 @@
     builder.addOutput(outputJar);
     builder.addOutput(outputDepsProto);
 
-    builder.addTransitiveInputs(hostJavabase.javaBaseInputsMiddleman());
     builder.addTransitiveInputs(additionalInputs);
     builder.addInputs(bootclasspathEntries);
     builder.addInputs(sourceJars);
@@ -251,9 +250,12 @@
     // 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.
     FilesToRunProvider headerCompiler = javaToolchain.getHeaderCompiler();
-    if (!headerCompiler.getExecutable().getExtension().equals("jar")) {
+    if (!requiresAnnotationProcessing && javaToolchain.getHeaderCompilerDirect() != null) {
+      builder.setExecutable(javaToolchain.getHeaderCompilerDirect());
+    } else if (!headerCompiler.getExecutable().getExtension().equals("jar")) {
       builder.setExecutable(headerCompiler);
     } else {
+      builder.addTransitiveInputs(hostJavabase.javaBaseInputsMiddleman());
       builder.setJarExecutable(
           hostJavabase.javaBinaryExecPath(),
           headerCompiler.getExecutable(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
index 9347485..acd70642 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
@@ -67,6 +67,8 @@
         ruleContext.getExecutablePrerequisite("javabuilder", Mode.HOST);
     FilesToRunProvider headerCompiler =
         ruleContext.getExecutablePrerequisite("header_compiler", Mode.HOST);
+    FilesToRunProvider headerCompilerDirect =
+        ruleContext.getExecutablePrerequisite("header_compiler_direct", Mode.HOST);
     boolean forciblyDisableHeaderCompilation =
         ruleContext.attributes().get("forcibly_disable_header_compilation", Type.BOOLEAN);
     Artifact singleJar = ruleContext.getPrerequisiteArtifact("singlejar", Mode.HOST);
@@ -108,6 +110,7 @@
             tools,
             javabuilder,
             headerCompiler,
+            headerCompilerDirect,
             forciblyDisableHeaderCompilation,
             singleJar,
             oneVersion,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
index 2938c4e..ee300a5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
@@ -77,6 +77,7 @@
       NestedSet<Artifact> tools,
       FilesToRunProvider javaBuilder,
       @Nullable FilesToRunProvider headerCompiler,
+      @Nullable FilesToRunProvider headerCompilerDirect,
       boolean forciblyDisableHeaderCompilation,
       Artifact singleJar,
       @Nullable Artifact oneVersion,
@@ -96,6 +97,7 @@
         tools,
         javaBuilder,
         headerCompiler,
+        headerCompilerDirect,
         forciblyDisableHeaderCompilation,
         singleJar,
         oneVersion,
@@ -121,6 +123,7 @@
   private final NestedSet<Artifact> tools;
   private final FilesToRunProvider javaBuilder;
   @Nullable private final FilesToRunProvider headerCompiler;
+  @Nullable private final FilesToRunProvider headerCompilerDirect;
   private final boolean forciblyDisableHeaderCompilation;
   private final Artifact singleJar;
   @Nullable private final Artifact oneVersion;
@@ -145,6 +148,7 @@
       NestedSet<Artifact> tools,
       FilesToRunProvider javaBuilder,
       @Nullable FilesToRunProvider headerCompiler,
+      @Nullable FilesToRunProvider headerCompilerDirect,
       boolean forciblyDisableHeaderCompilation,
       Artifact singleJar,
       @Nullable Artifact oneVersion,
@@ -168,6 +172,7 @@
     this.tools = tools;
     this.javaBuilder = javaBuilder;
     this.headerCompiler = headerCompiler;
+    this.headerCompilerDirect = headerCompilerDirect;
     this.forciblyDisableHeaderCompilation = forciblyDisableHeaderCompilation;
     this.singleJar = singleJar;
     this.oneVersion = oneVersion;
@@ -221,6 +226,15 @@
   }
 
   /**
+   * Returns the {@link FilesToRunProvider} of the Header Compiler deploy jar for direct-classpath,
+   * non-annotation processing actions.
+   */
+  @Nullable
+  public FilesToRunProvider getHeaderCompilerDirect() {
+    return headerCompilerDirect;
+  }
+
+  /**
    * Returns {@code true} if header compilation should be forcibly disabled, overriding
    * --java_header_compilation.
    */
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
index f676b9c..288ceb6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
@@ -117,7 +117,10 @@
         /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(tools) -->
         Labels of tools available for label-expansion in jvm_opts.
         <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
-        .add(attr("tools", LABEL_LIST).cfg(HostTransition.INSTANCE).allowedFileTypes(FileTypeSet.ANY_FILE))
+        .add(
+            attr("tools", LABEL_LIST)
+                .cfg(HostTransition.INSTANCE)
+                .allowedFileTypes(FileTypeSet.ANY_FILE))
         /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(javabuilder) -->
         Label of the JavaBuilder deploy jar.
         <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
@@ -184,6 +187,17 @@
                 .singleArtifact()
                 .allowedFileTypes(FileTypeSet.ANY_FILE)
                 .exec())
+        /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(header_compiler_direct) -->
+        Optional label of the header compiler to use for direct classpath actions that do not
+        include any API-generating annotation processors.
+
+        <p>This tool does not support annotation processing.
+        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+        .add(
+            attr("header_compiler_direct", LABEL_LIST)
+                .cfg(HostTransition.INSTANCE)
+                .allowedFileTypes(FileTypeSet.ANY_FILE)
+                .exec())
         /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(oneversion) -->
         Label of the one-version enforcement binary.
         <!-- #END_BLAZE_RULE.ATTRIBUTE --> */