Expose RuleContext methods in ActionConstructionContext

- Common methods for creating artifacts
- Convenience method for registering action

Also, create a new getUniqueDirectoryArtifact method that doesn't require a
root directory to be passed in - every call I've seen to
getUniqueDirectoryArtifact always uses RuleContext#getBinOrGenfilesDirectory
ffor this value.

RELNOTES: none
PiperOrigin-RevId: 196993195
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index bea1cd3..d33cd17 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -635,29 +635,12 @@
     return getAnalysisEnvironment().getDerivedArtifact(rootRelativePath, root);
   }
 
-  /**
-   * Creates an artifact in a directory that is unique to the package that contains the rule, thus
-   * guaranteeing that it never clashes with artifacts created by rules in other packages.
-   */
+  @Override
   public Artifact getPackageRelativeArtifact(PathFragment relative, ArtifactRoot root) {
     return getDerivedArtifact(getPackageDirectory().getRelative(relative), root);
   }
 
-  /**
-   * Returns the root-relative path fragment under which output artifacts of this rule should go.
-   *
-   * <p>Note that:
-   *
-   * <ul>
-   *   <li>This doesn't guarantee that there are no clashes with rules in the same package.
-   *   <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, ArtifactRoot)} should be
-   *       used instead of this method.
-   * </ul>
-   *
-   * Ideally, user-visible artifacts should all have corresponding output file targets, all others
-   * should go into a rule-specific directory. {@link #getUniqueDirectoryArtifact(String,
-   * PathFragment, ArtifactRoot)}) ensures that this is the case.
-   */
+  @Override
   public PathFragment getPackageDirectory() {
     return getLabel().getPackageIdentifier().getSourceRoot();
   }
@@ -708,6 +691,11 @@
     return getUniqueDirectoryArtifact(uniqueDirectory, PathFragment.create(relative), root);
   }
 
+  @Override
+  public Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, String relative) {
+    return getUniqueDirectoryArtifact(uniqueDirectorySuffix, relative, getBinOrGenfilesDirectory());
+  }
+
   /**
    * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
    * clashes with artifacts created by other rules.
@@ -1256,10 +1244,7 @@
     return label;
   }
 
-  /**
-   * Returns the implicit output artifact for a given template function. If multiple or no artifacts
-   * can be found as a result of the template, an exception is thrown.
-   */
+  @Override
   public Artifact getImplicitOutputArtifact(ImplicitOutputsFunction function)
       throws InterruptedException {
     Iterable<String> result;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
index 1eefb53..4025c22 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ActionConstructionContext.java
@@ -13,12 +13,14 @@
 // limitations under the License.
 package com.google.devtools.build.lib.analysis.actions;
 
+import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
 import com.google.devtools.build.lib.actions.ActionOwner;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import javax.annotation.Nullable;
 
@@ -43,6 +45,8 @@
   /** The current analysis environment. */
   AnalysisEnvironment getAnalysisEnvironment();
 
+  void registerAction(ActionAnalysisMetadata... actions);
+
   /**
    * Creates an artifact under a given root with the given root-relative path.
    *
@@ -52,6 +56,43 @@
    */
   Artifact getDerivedArtifact(PathFragment rootRelativePath, ArtifactRoot root);
 
+  /**
+   * Returns the implicit output artifact for a given template function. If multiple or no artifacts
+   * can be found as a result of the template, an exception is thrown.
+   */
+  Artifact getImplicitOutputArtifact(ImplicitOutputsFunction function) throws InterruptedException;
+
+  /**
+   * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
+   * clashes with artifacts created by other rules.
+   *
+   * @param uniqueDirectorySuffix suffix of the directory - it will be prepended
+   */
+  Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, String relative);
+
+  /**
+   * Returns the root-relative path fragment under which output artifacts of this rule should go.
+   *
+   * <p>Note that:
+   *
+   * <ul>
+   *   <li>This doesn't guarantee that there are no clashes with rules in the same package.
+   *   <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, ArtifactRoot)} should be
+   *       used instead of this method.
+   * </ul>
+   *
+   * Ideally, user-visible artifacts should all have corresponding output file targets, all others
+   * should go into a rule-specific directory. {@link #getUniqueDirectoryArtifact(String, String)})
+   * ensures that this is the case.
+   */
+  PathFragment getPackageDirectory();
+
+  /**
+   * Creates an artifact in a directory that is unique to the package that contains the rule, thus
+   * guaranteeing that it never clashes with artifacts created by rules in other packages.
+   */
+  Artifact getPackageRelativeArtifact(PathFragment relative, ArtifactRoot root);
+
   /** Returns the {@link PlatformInfo} describing the execution platform this action should use. */
   @Nullable
   PlatformInfo getExecutionPlatform();