diff options
author | Han-Wen Nienhuys <hanwen@google.com> | 2015-02-25 16:45:20 +0100 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-02-25 16:45:20 +0100 |
commit | d08b27fa9701fecfdb69e1b0d1ac2459efc2129b (patch) | |
tree | 5d50963026239ca5aebfb47ea5b8db7e814e57c8 /src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java |
Update from Google.
--
MOE_MIGRATED_REVID=85702957
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java new file mode 100644 index 0000000000..c877d38263 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java @@ -0,0 +1,249 @@ +// Copyright 2014 Google Inc. 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.skyframe; + +import com.google.common.base.Preconditions; +import com.google.devtools.build.lib.packages.PackageIdentifier; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +/** + * A value that represents a package lookup result. + * + * <p>Package lookups will always produce a value. On success, the {@code #getRoot} returns the + * package path root under which the package resides and the package's BUILD file is guaranteed to + * exist; on failure, {@code #getErrorReason} and {@code #getErrorMsg} describe why the package + * doesn't exist. + * + * <p>Implementation detail: we use inheritance here to optimize for memory usage. + */ +abstract class PackageLookupValue implements SkyValue { + + enum ErrorReason { + // There is no BUILD file. + NO_BUILD_FILE, + + // The package name is invalid. + INVALID_PACKAGE_NAME, + + // The package is considered deleted because of --deleted_packages. + DELETED_PACKAGE, + + // The //external package could not be loaded, either because the WORKSPACE file could not be + // parsed or the packages it references cannot be loaded. + NO_EXTERNAL_PACKAGE + } + + protected PackageLookupValue() { + } + + public static PackageLookupValue success(Path root) { + return new SuccessfulPackageLookupValue(root); + } + + public static PackageLookupValue noBuildFile() { + return NoBuildFilePackageLookupValue.INSTANCE; + } + + public static PackageLookupValue noExternalPackage() { + return NoExternalPackageLookupValue.INSTANCE; + } + + public static PackageLookupValue invalidPackageName(String errorMsg) { + return new InvalidNamePackageLookupValue(errorMsg); + } + + public static PackageLookupValue deletedPackage() { + return DeletedPackageLookupValue.INSTANCE; + } + + /** + * For a successful package lookup, returns the root (package path entry) that the package + * resides in. + */ + public abstract Path getRoot(); + + /** + * Returns whether the package lookup was successful. + */ + public abstract boolean packageExists(); + + /** + * For an unsuccessful package lookup, gets the reason why {@link #packageExists} returns + * {@code false}. + */ + abstract ErrorReason getErrorReason(); + + /** + * For an unsuccessful package lookup, gets a detailed error message for {@link #getErrorReason} + * that is suitable for reporting to a user. + */ + abstract String getErrorMsg(); + + static SkyKey key(PathFragment directory) { + Preconditions.checkArgument(!directory.isAbsolute(), directory); + return key(PackageIdentifier.createInDefaultRepo(directory)); + } + + static SkyKey key(PackageIdentifier pkgIdentifier) { + return new SkyKey(SkyFunctions.PACKAGE_LOOKUP, pkgIdentifier); + } + + private static class SuccessfulPackageLookupValue extends PackageLookupValue { + + private final Path root; + + private SuccessfulPackageLookupValue(Path root) { + this.root = root; + } + + @Override + public boolean packageExists() { + return true; + } + + @Override + public Path getRoot() { + return root; + } + + @Override + ErrorReason getErrorReason() { + throw new IllegalStateException(); + } + + @Override + String getErrorMsg() { + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof SuccessfulPackageLookupValue)) { + return false; + } + SuccessfulPackageLookupValue other = (SuccessfulPackageLookupValue) obj; + return root.equals(other.root); + } + + @Override + public int hashCode() { + return root.hashCode(); + } + } + + private abstract static class UnsuccessfulPackageLookupValue extends PackageLookupValue { + + @Override + public boolean packageExists() { + return false; + } + + @Override + public Path getRoot() { + throw new IllegalStateException(); + } + } + + private static class NoBuildFilePackageLookupValue extends UnsuccessfulPackageLookupValue { + + public static final NoBuildFilePackageLookupValue INSTANCE = + new NoBuildFilePackageLookupValue(); + + private NoBuildFilePackageLookupValue() { + } + + @Override + ErrorReason getErrorReason() { + return ErrorReason.NO_BUILD_FILE; + } + + @Override + String getErrorMsg() { + return "BUILD file not found on package path"; + } + } + + private static class NoExternalPackageLookupValue extends UnsuccessfulPackageLookupValue { + + public static final NoExternalPackageLookupValue INSTANCE = + new NoExternalPackageLookupValue(); + + private NoExternalPackageLookupValue() { + } + + @Override + ErrorReason getErrorReason() { + return ErrorReason.NO_EXTERNAL_PACKAGE; + } + + @Override + String getErrorMsg() { + return "Error loading the //external package"; + } + } + + private static class InvalidNamePackageLookupValue extends UnsuccessfulPackageLookupValue { + + private final String errorMsg; + + private InvalidNamePackageLookupValue(String errorMsg) { + this.errorMsg = errorMsg; + } + + @Override + ErrorReason getErrorReason() { + return ErrorReason.INVALID_PACKAGE_NAME; + } + + @Override + String getErrorMsg() { + return errorMsg; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof InvalidNamePackageLookupValue)) { + return false; + } + InvalidNamePackageLookupValue other = (InvalidNamePackageLookupValue) obj; + return errorMsg.equals(other.errorMsg); + } + + @Override + public int hashCode() { + return errorMsg.hashCode(); + } + } + + private static class DeletedPackageLookupValue extends UnsuccessfulPackageLookupValue { + + public static final DeletedPackageLookupValue INSTANCE = new DeletedPackageLookupValue(); + + private DeletedPackageLookupValue() { + } + + @Override + ErrorReason getErrorReason() { + return ErrorReason.DELETED_PACKAGE; + } + + @Override + String getErrorMsg() { + return "Package is considered deleted due to --deleted_packages"; + } + } +} |