| // 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()); | |
| } | |
| } | |
| } |