blob: 7104882520e5def1728c7d13e77b8abe81ff8661 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.skyframe;
16
tomlua155b532017-11-08 20:12:47 +010017import com.google.common.base.Preconditions;
janakr5fb2a482018-03-02 17:48:57 -080018import com.google.common.collect.Interner;
John Fielda97e17f2015-11-13 02:19:52 +000019import com.google.devtools.build.lib.cmdline.Label;
janakr5fb2a482018-03-02 17:48:57 -080020import com.google.devtools.build.lib.concurrent.BlazeInterners;
21import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
Googler66d099e2019-09-26 08:07:06 -070022import com.google.devtools.build.lib.syntax.StarlarkFile;
janakr5fb2a482018-03-02 17:48:57 -080023import com.google.devtools.build.skyframe.AbstractSkyKey;
nharmata82cfb552018-03-28 10:43:48 -070024import com.google.devtools.build.skyframe.NotComparableSkyValue;
janakr5fb2a482018-03-02 17:48:57 -080025import com.google.devtools.build.skyframe.SkyFunctionName;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027/**
Janak Ramakrishnand7d951d2017-02-15 05:41:19 +000028 * A value that represents an AST file lookup result. There are two subclasses: one for the case
29 * where the file is found, and another for the case where the file is missing (but there are no
30 * other errors).
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031 */
nharmata82cfb552018-03-28 10:43:48 -070032// In practice, if a ASTFileLookupValue is re-computed (i.e. not changed pruned), then it will
33// almost certainly be unequal to the previous value. This is because of (i) the change-pruning
34// semantics of the PackageLookupValue dep and the FileValue dep; consider the latter: if the
35// FileValue for the bzl file has changed, then the contents of the bzl file probably changed and
Googler66d099e2019-09-26 08:07:06 -070036// (ii) we don't currently have skylark-semantic-equality in StarlarkFile, so two StarlarkFile
nharmata82cfb552018-03-28 10:43:48 -070037// instances representing two different contents of a bzl file will be different.
38// TODO(bazel-team): Consider doing better here. As a pre-req, we would need
Googler66d099e2019-09-26 08:07:06 -070039// skylark-semantic-equality in StarlarkFile, rather than equality naively based on the contents of
nharmata82cfb552018-03-28 10:43:48 -070040// the bzl file. For a concrete example, the contents of comment lines do not currently impact
41// skylark semantics.
42public abstract class ASTFileLookupValue implements NotComparableSkyValue {
John Fielda97e17f2015-11-13 02:19:52 +000043 public abstract boolean lookupSuccessful();
Googler66d099e2019-09-26 08:07:06 -070044
45 public abstract StarlarkFile getAST();
46
John Fielda97e17f2015-11-13 02:19:52 +000047 public abstract String getErrorMsg();
janakr5fb2a482018-03-02 17:48:57 -080048
John Fielda97e17f2015-11-13 02:19:52 +000049 /** If the file is found, this class encapsulates the parsed AST. */
shahan3827f0a2018-04-09 11:37:30 -070050 @AutoCodec.VisibleForSerialization
51 public static class ASTLookupWithFile extends ASTFileLookupValue {
Googler66d099e2019-09-26 08:07:06 -070052 private final StarlarkFile ast;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010053
Googler66d099e2019-09-26 08:07:06 -070054 private ASTLookupWithFile(StarlarkFile ast) {
John Fielda97e17f2015-11-13 02:19:52 +000055 Preconditions.checkNotNull(ast);
56 this.ast = ast;
Michajlo Matijkiw2a7c8022015-09-22 02:22:12 +000057 }
John Fielda97e17f2015-11-13 02:19:52 +000058
59 @Override
60 public boolean lookupSuccessful() {
61 return true;
62 }
63
64 @Override
Googler66d099e2019-09-26 08:07:06 -070065 public StarlarkFile getAST() {
John Fielda97e17f2015-11-13 02:19:52 +000066 return this.ast;
67 }
68
69 @Override
70 public String getErrorMsg() {
71 throw new IllegalStateException(
72 "attempted to retrieve unsuccessful lookup reason for successful lookup");
73 }
74 }
janakr5fb2a482018-03-02 17:48:57 -080075
John Fielda97e17f2015-11-13 02:19:52 +000076 /** If the file isn't found, this class encapsulates a message with the reason. */
shahan3827f0a2018-04-09 11:37:30 -070077 @AutoCodec.VisibleForSerialization
78 public static class ASTLookupNoFile extends ASTFileLookupValue {
John Fielda97e17f2015-11-13 02:19:52 +000079 private final String errorMsg;
80
81 private ASTLookupNoFile(String errorMsg) {
82 this.errorMsg = Preconditions.checkNotNull(errorMsg);
83 }
84
85 @Override
86 public boolean lookupSuccessful() {
87 return false;
88 }
89
90 @Override
Googler66d099e2019-09-26 08:07:06 -070091 public StarlarkFile getAST() {
John Fielda97e17f2015-11-13 02:19:52 +000092 throw new IllegalStateException("attempted to retrieve AST from an unsuccessful lookup");
93 }
94
95 @Override
96 public String getErrorMsg() {
97 return this.errorMsg;
98 }
99 }
100
101 static ASTFileLookupValue forBadPackage(Label fileLabel, String reason) {
102 return new ASTLookupNoFile(
103 String.format("Unable to load package for '%s': %s", fileLabel, reason));
104 }
janakr5fb2a482018-03-02 17:48:57 -0800105
laurentlbc0bd2102018-10-17 07:05:25 -0700106 static ASTFileLookupValue forMissingFile(Label fileLabel) {
107 return new ASTLookupNoFile(
108 String.format("Unable to load file '%s': file doesn't exist", fileLabel));
109 }
110
John Fielda97e17f2015-11-13 02:19:52 +0000111 static ASTFileLookupValue forBadFile(Label fileLabel) {
112 return new ASTLookupNoFile(
laurentlbc0bd2102018-10-17 07:05:25 -0700113 String.format("Unable to load file '%s': it isn't a regular file", fileLabel));
John Fielda97e17f2015-11-13 02:19:52 +0000114 }
janakr5fb2a482018-03-02 17:48:57 -0800115
Googler66d099e2019-09-26 08:07:06 -0700116 public static ASTFileLookupValue withFile(StarlarkFile ast) {
John Fielda97e17f2015-11-13 02:19:52 +0000117 return new ASTLookupWithFile(ast);
118 }
119
janakr5fb2a482018-03-02 17:48:57 -0800120 public static Key key(Label astFileLabel) {
121 return ASTFileLookupValue.Key.create(astFileLabel);
122 }
123
124 @AutoCodec.VisibleForSerialization
125 @AutoCodec
126 static class Key extends AbstractSkyKey<Label> {
127 private static final Interner<Key> interner = BlazeInterners.newWeakInterner();
128
129 private Key(Label arg) {
130 super(arg);
131 }
132
133 @AutoCodec.VisibleForSerialization
134 @AutoCodec.Instantiator
135 static Key create(Label arg) {
136 return interner.intern(new Key(arg));
137 }
138
139 @Override
140 public SkyFunctionName functionName() {
141 return SkyFunctions.AST_FILE_LOOKUP;
142 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100143 }
144}