|  | // Copyright 2018 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.actions; | 
|  |  | 
|  | import com.google.common.base.Preconditions; | 
|  | import com.google.devtools.build.lib.vfs.FileSystem; | 
|  | import com.google.devtools.build.lib.vfs.Path; | 
|  | import com.google.devtools.build.lib.vfs.Root; | 
|  | import javax.annotation.Nullable; | 
|  |  | 
|  | /** | 
|  | * An indirection layer on Path resolution of {@link Artifact} and {@link Root}. | 
|  | * | 
|  | * <p>Serves as converter interface primarily for switching the {@link FileSystem} underlying the | 
|  | * values. | 
|  | */ | 
|  | public interface ArtifactPathResolver { | 
|  |  | 
|  | /** | 
|  | * @return a resolved Path corresponding to the given actionInput. | 
|  | */ | 
|  | Path toPath(ActionInput actionInput); | 
|  |  | 
|  | /** | 
|  | * @return a resolved Path corresponding to the given path. | 
|  | */ | 
|  | Path convertPath(Path path); | 
|  |  | 
|  | /** | 
|  | * @return a resolved Rooth corresponding to the given Root. | 
|  | */ | 
|  | Root transformRoot(Root root); | 
|  |  | 
|  | ArtifactPathResolver IDENTITY = new IdentityResolver(null); | 
|  |  | 
|  | static ArtifactPathResolver forExecRoot(Path execRoot) { | 
|  | return new IdentityResolver(execRoot); | 
|  | } | 
|  |  | 
|  | static ArtifactPathResolver withTransformedFileSystem(Path execRoot) { | 
|  | return new TransformResolver(execRoot); | 
|  | } | 
|  |  | 
|  | static ArtifactPathResolver createPathResolver(@Nullable FileSystem fileSystem, | 
|  | Path execRoot) { | 
|  | if (fileSystem == null) { | 
|  | return forExecRoot(execRoot); | 
|  | } else { | 
|  | return withTransformedFileSystem( | 
|  | fileSystem.getPath(execRoot.asFragment())); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Path resolution that uses an Artifact's path directly, or looks up the input execPath relative | 
|  | * to the given execRoot. | 
|  | */ | 
|  | class IdentityResolver implements ArtifactPathResolver { | 
|  | private final Path execRoot; | 
|  |  | 
|  | private IdentityResolver(Path execRoot) { | 
|  | this.execRoot = execRoot; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Path toPath(ActionInput actionInput) { | 
|  | if (actionInput instanceof Artifact) { | 
|  | return ((Artifact) actionInput).getPath(); | 
|  | } | 
|  | return execRoot.getRelative(actionInput.getExecPath()); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Root transformRoot(Root root) { | 
|  | return Preconditions.checkNotNull(root); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Path convertPath(Path path) { | 
|  | return path; | 
|  | } | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * A resolver that transforms all results to the same filesystem as the given execRoot. | 
|  | */ | 
|  | class TransformResolver implements ArtifactPathResolver { | 
|  | private final FileSystem fileSystem; | 
|  | private final Path execRoot; | 
|  |  | 
|  | private TransformResolver(Path execRoot) { | 
|  | this.execRoot = execRoot; | 
|  | this.fileSystem = Preconditions.checkNotNull(execRoot.getFileSystem()); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Path toPath(ActionInput input) { | 
|  | if (input instanceof Artifact) { | 
|  | return fileSystem.getPath(((Artifact) input).getPath().getPathString()); | 
|  | } | 
|  | return execRoot.getRelative(input.getExecPath()); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Root transformRoot(Root root) { | 
|  | return Root.toFileSystem(Preconditions.checkNotNull(root), fileSystem); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Path convertPath(Path path) { | 
|  | return fileSystem.getPath(path.asFragment()); | 
|  | } | 
|  | } | 
|  | } |