Unify path resolution codepaths.

RELNOTES: None
PiperOrigin-RevId: 199880252
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
index 1db7c23..2aff663 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
@@ -59,6 +59,8 @@
 
   @Nullable private ImmutableList<FilesetOutputSymlink> outputSymlinks;
 
+  private final ArtifactPathResolver pathResolver;
+
   private ActionExecutionContext(
       Executor executor,
       MetadataProvider actionInputFileCache,
@@ -82,6 +84,9 @@
     this.artifactExpander = artifactExpander;
     this.env = env;
     this.actionFileSystem = actionFileSystem;
+    this.pathResolver = createPathResolver(actionFileSystem,
+        // executor is only ever null in testing.
+        executor == null ? null : executor.getExecRoot());
   }
 
   public ActionExecutionContext(
@@ -168,22 +173,25 @@
    * {@link Artifact.getRoot}.
    */
   public Path getInputPath(ActionInput input) {
-    if (input instanceof Artifact) {
-      Artifact artifact = (Artifact) input;
-      if (actionFileSystem != null) {
-        return actionFileSystem.getPath(artifact.getPath().getPathString());
-      }
-      return artifact.getPath();
-    }
-    return getExecRoot().getRelative(input.getExecPath());
+    return pathResolver.toPath(input);
   }
 
   public Root getRoot(Artifact artifact) {
-    if (actionFileSystem != null) {
-      return Root.fromPath(
-          actionFileSystem.getPath(artifact.getRoot().getRoot().asPath().getPathString()));
+    return pathResolver.transformRoot(artifact.getRoot().getRoot());
+  }
+
+  private static ArtifactPathResolver createPathResolver(FileSystem actionFileSystem,
+      Path execRoot) {
+    if (actionFileSystem == null) {
+      return ArtifactPathResolver.forExecRoot(execRoot);
+    } else {
+      return ArtifactPathResolver.withTransformedFileSystem(
+          actionFileSystem.getPath(execRoot.asFragment()));
     }
-    return artifact.getRoot().getRoot();
+  }
+
+  public ArtifactPathResolver getPathResolver() {
+    return pathResolver;
   }
 
   /**