Roll back using labels rather than PathFragments for skylark loads.
RELNOTES:
--
MOS_MIGRATED_REVID=103606693
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
index 1303867..a7cd395 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
@@ -14,8 +14,10 @@
package com.google.devtools.build.lib.skyframe;
-import com.google.devtools.build.lib.cmdline.Label;
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.RuleClassProvider;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
@@ -30,95 +32,167 @@
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
/**
- * A SkyFunction for {@link ASTFileLookupValue}s. Given a Label referencing a Skylark file,
- * attempts to locate the file and load it as a syntax tree ({@link BuildFileAST}). If the file
- * (or the package containing it) doesn't exist, the function doesn't fail, but instead returns a
- * specific {@code NO_FILE} {@link ASTFileLookupValue}.
+ * A SkyFunction for {@link ASTFileLookupValue}s. Tries to locate a file and load it as a
+ * syntax tree and cache the resulting {@link BuildFileAST}. If the file doesn't exist
+ * the function doesn't fail but returns a specific NO_FILE ASTLookupValue.
*/
public class ASTFileLookupFunction implements SkyFunction {
+ private abstract static class FileLookupResult {
+ /** Returns whether the file lookup was successful. */
+ public abstract boolean lookupSuccessful();
+
+ /** If {@code lookupSuccessful()}, returns the {@link RootedPath} to the file. */
+ public abstract RootedPath rootedPath();
+
+ /** If {@code lookupSuccessful()}, returns the file's size, in bytes. */
+ public abstract long fileSize();
+
+ static FileLookupResult noFile() {
+ return UnsuccessfulFileResult.INSTANCE;
+ }
+
+ static FileLookupResult file(RootedPath rootedPath, long fileSize) {
+ return new SuccessfulFileResult(rootedPath, fileSize);
+ }
+
+ private static class SuccessfulFileResult extends FileLookupResult {
+ private final RootedPath rootedPath;
+ private final long fileSize;
+
+ private SuccessfulFileResult(RootedPath rootedPath, long fileSize) {
+ this.rootedPath = rootedPath;
+ this.fileSize = fileSize;
+ }
+
+ @Override
+ public boolean lookupSuccessful() {
+ return true;
+ }
+
+ @Override
+ public RootedPath rootedPath() {
+ return rootedPath;
+ }
+
+ @Override
+ public long fileSize() {
+ return fileSize;
+ }
+ }
+
+ private static class UnsuccessfulFileResult extends FileLookupResult {
+ private static final UnsuccessfulFileResult INSTANCE = new UnsuccessfulFileResult();
+ private UnsuccessfulFileResult() {
+ }
+
+ @Override
+ public boolean lookupSuccessful() {
+ return false;
+ }
+
+ @Override
+ public RootedPath rootedPath() {
+ throw new IllegalStateException("unsuccessful lookup");
+ }
+
+ @Override
+ public long fileSize() {
+ throw new IllegalStateException("unsuccessful lookup");
+ }
+ }
+ }
+
+ private final AtomicReference<PathPackageLocator> pkgLocator;
private final RuleClassProvider ruleClassProvider;
- public ASTFileLookupFunction(RuleClassProvider ruleClassProvider) {
+ public ASTFileLookupFunction(AtomicReference<PathPackageLocator> pkgLocator,
+ RuleClassProvider ruleClassProvider) {
+ this.pkgLocator = pkgLocator;
this.ruleClassProvider = ruleClassProvider;
}
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException,
InterruptedException {
- Label fileLabel = (Label) skyKey.argument();
- PathFragment filePathFragment = fileLabel.toPathFragment();
-
- /*
- * Determine whether the package designated by fileLabel exists.
- */
- SkyKey pkgSkyKey = PackageLookupValue.key(fileLabel.getPackageIdentifier());
- PackageLookupValue pkgLookupValue = null;
- pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
- if (pkgLookupValue == null) {
+ PackageIdentifier key = (PackageIdentifier) skyKey.argument();
+ PathFragment astFilePathFragment = key.getPackageFragment();
+ FileLookupResult lookupResult = getASTFile(env, key);
+ if (lookupResult == null) {
return null;
}
- if (!pkgLookupValue.packageExists()) {
- return ASTFileLookupValue.forBadPackage(fileLabel, pkgLookupValue.getErrorMsg());
+ if (!lookupResult.lookupSuccessful()) {
+ return ASTFileLookupValue.noFile();
}
-
- /*
- * Determine whether the file designated by fileLabel exists.
- */
- Path packageRoot = pkgLookupValue.getRoot();
- RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment);
- SkyKey fileSkyKey = FileValue.key(rootedPath);
- FileValue fileValue = null;
- try {
- fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class,
- FileSymlinkException.class, InconsistentFilesystemException.class);
- } catch (IOException | FileSymlinkException e) {
- throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
- e.getMessage()), Transience.PERSISTENT);
- } catch (InconsistentFilesystemException e) {
- throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
- }
- if (fileValue == null) {
- return null;
- }
- if (!fileValue.isFile()) {
- return ASTFileLookupValue.forBadFile(fileLabel);
- }
-
- /*
- * Both the package and the file exist; load the file and parse it as an AST.
- */
BuildFileAST ast = null;
- Path path = rootedPath.asPath();
- // Skylark files end with bzl
- boolean parseAsSkylark = filePathFragment.getPathString().endsWith(".bzl");
+ Path path = lookupResult.rootedPath().asPath();
+ long fileSize = lookupResult.fileSize();
+ // Skylark files end with bzl.
+ boolean parseAsSkylark = astFilePathFragment.getPathString().endsWith(".bzl");
try {
- long astFileSize = fileValue.getSize();
if (parseAsSkylark) {
try (Mutability mutability = Mutability.create("validate")) {
- ast = BuildFileAST.parseSkylarkFile(path, astFileSize, env.getListener(),
- new ValidationEnvironment(
- ruleClassProvider.createSkylarkRuleClassEnvironment(
- mutability,
- env.getListener(),
- // the two below don't matter for extracting the ValidationEnvironment:
- /*astFileContentHashCode=*/null,
- /*importMap=*/null)
- .setupDynamic(Runtime.PKG_NAME, Runtime.NONE)));
+ ast = BuildFileAST.parseSkylarkFile(path, fileSize, env.getListener(),
+ new ValidationEnvironment(
+ ruleClassProvider.createSkylarkRuleClassEnvironment(
+ mutability,
+ env.getListener(),
+ // the two below don't matter for extracting the ValidationEnvironment:
+ /*astFileContentHashCode=*/null,
+ /*importMap=*/null)
+ .setupDynamic(Runtime.PKG_NAME, Runtime.NONE)));
}
} else {
- ast = BuildFileAST.parseBuildFile(path, astFileSize, env.getListener(), false);
+ ast = BuildFileAST.parseBuildFile(path, fileSize, env.getListener(), false);
}
} catch (IOException e) {
- throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
- e.getMessage()), Transience.TRANSIENT);
+ throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
+ e.getMessage()), Transience.TRANSIENT);
+ }
+ return ASTFileLookupValue.withFile(ast);
+ }
+
+ private FileLookupResult getASTFile(Environment env, PackageIdentifier key)
+ throws ASTLookupFunctionException {
+ List<Path> candidateRoots;
+ if (!key.getRepository().isDefault()) {
+ RepositoryValue repository =
+ (RepositoryValue) env.getValue(RepositoryValue.key(key.getRepository()));
+ if (repository == null) {
+ return null;
+ }
+
+ candidateRoots = ImmutableList.of(repository.getPath());
+ } else {
+ candidateRoots = pkgLocator.get().getPathEntries();
}
- return ASTFileLookupValue.withFile(ast);
+ for (Path root : candidateRoots) {
+ RootedPath rootedPath = RootedPath.toRootedPath(root, key.getPackageFragment());
+ FileValue fileValue;
+ try {
+ fileValue = (FileValue) env.getValueOrThrow(FileValue.key(rootedPath),
+ IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
+ } catch (IOException | FileSymlinkException e) {
+ throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
+ e.getMessage()), Transience.PERSISTENT);
+ } catch (InconsistentFilesystemException e) {
+ throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
+ }
+ if (fileValue == null) {
+ return null;
+ }
+ if (fileValue.isFile()) {
+ return FileLookupResult.file(rootedPath, fileValue.getSize());
+ }
+ }
+ return FileLookupResult.noFile();
}
@Nullable