blob: 06b2dccec84fae0b6e11b098da39ad9e92c4ec4a [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.
14package com.google.devtools.build.lib.skyframe;
15
janakr6cf00a02018-11-09 12:26:30 -080016import com.google.common.base.MoreObjects;
tomlua155b532017-11-08 20:12:47 +010017import com.google.common.base.Preconditions;
janakr5fb2a482018-03-02 17:48:57 -080018import com.google.common.collect.Interner;
nharmatad86b5092018-10-16 15:50:21 -070019import com.google.devtools.build.lib.cmdline.Label;
Kristina Chodorow73fa2032015-08-28 17:57:46 +000020import com.google.devtools.build.lib.cmdline.PackageIdentifier;
janakr5fb2a482018-03-02 17:48:57 -080021import com.google.devtools.build.lib.concurrent.BlazeInterners;
shahanbbbf3dc2018-02-23 15:41:52 -080022import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
nharmatad86b5092018-10-16 15:50:21 -070023import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080024import com.google.devtools.build.lib.vfs.Root;
janakr5fb2a482018-03-02 17:48:57 -080025import com.google.devtools.build.skyframe.AbstractSkyKey;
26import com.google.devtools.build.skyframe.SkyFunctionName;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027import com.google.devtools.build.skyframe.SkyValue;
Googler06eb1bb2019-02-26 15:33:15 -080028import javax.annotation.Nonnull;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010029
30/**
31 * A value that represents the result of looking for the existence of a package that owns a
32 * specific directory path. Compare with {@link PackageLookupValue}, which deals with existence of
33 * a specific package.
34 */
35public abstract class ContainingPackageLookupValue implements SkyValue {
Michajlo Matijkiw11184592015-10-16 19:00:45 +000036
shahan1fe23122018-02-28 09:18:36 -080037 @AutoCodec public static final NoContainingPackage NONE = new NoContainingPackage();
Michajlo Matijkiw11184592015-10-16 19:00:45 +000038
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010039 /** Returns whether there is a containing package. */
40 public abstract boolean hasContainingPackage();
41
42 /** If there is a containing package, returns its name. */
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +000043 public abstract PackageIdentifier getContainingPackageName();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010044
45 /** If there is a containing package, returns its package root */
tomluee6a6862018-01-17 14:36:26 -080046 public abstract Root getContainingPackageRoot();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010047
Googler06eb1bb2019-02-26 15:33:15 -080048 /**
49 * If there is not a containing package, returns a reason why (this is usually the reason the
50 * outer-most directory isn't a package).
51 */
52 public String getReasonForNoContainingPackage() {
53 throw new IllegalStateException();
54 }
55
janakr5fb2a482018-03-02 17:48:57 -080056 public static Key key(PackageIdentifier id) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010057 Preconditions.checkArgument(!id.getPackageFragment().isAbsolute(), id);
Brian Silvermand7d6d622016-03-17 09:53:39 +000058 Preconditions.checkArgument(!id.getRepository().isDefault(), id);
janakr5fb2a482018-03-02 17:48:57 -080059 return Key.create(id);
60 }
61
nharmatad86b5092018-10-16 15:50:21 -070062 static String getErrorMessageForLabelCrossingPackageBoundary(
63 Root pkgRoot,
64 Label label,
65 ContainingPackageLookupValue containingPkgLookupValue) {
66 PackageIdentifier containingPkg = containingPkgLookupValue.getContainingPackageName();
67 boolean crossesPackageBoundaryBelow =
68 containingPkg.getSourceRoot().startsWith(label.getPackageIdentifier().getSourceRoot());
69 PathFragment labelNameFragment = PathFragment.create(label.getName());
laurentlbaf489f22019-07-29 08:19:03 -070070 String message;
71 if (crossesPackageBoundaryBelow) {
72 message =
73 String.format("Label '%s' is invalid because '%s' is a subpackage", label, containingPkg);
74 } else {
75 message =
76 String.format(
77 "Label '%s' is invalid because '%s' is not a package", label, label.getPackageName());
78 }
79
nharmatad86b5092018-10-16 15:50:21 -070080 Root containingRoot = containingPkgLookupValue.getContainingPackageRoot();
81 if (pkgRoot.equals(containingRoot)) {
82 PathFragment containingPkgFragment = containingPkg.getPackageFragment();
83 PathFragment labelNameInContainingPackage =
84 crossesPackageBoundaryBelow
85 ? labelNameFragment.subFragment(
86 containingPkgFragment.segmentCount()
87 - label.getPackageFragment().segmentCount(),
88 labelNameFragment.segmentCount())
89 : label.toPathFragment().relativeTo(containingPkgFragment);
laurentlbaf489f22019-07-29 08:19:03 -070090 message += "; perhaps you meant to put the colon here: '";
nharmatad86b5092018-10-16 15:50:21 -070091 if (containingPkg.getRepository().isDefault() || containingPkg.getRepository().isMain()) {
92 message += "//";
93 }
laurentlbaf489f22019-07-29 08:19:03 -070094 message += containingPkg + ":" + labelNameInContainingPackage + "'?";
nharmatad86b5092018-10-16 15:50:21 -070095 } else {
laurentlbaf489f22019-07-29 08:19:03 -070096 message +=
97 "; have you deleted "
98 + containingPkg
99 + "/BUILD? "
100 + "If so, use the --deleted_packages="
101 + containingPkg
102 + " option";
nharmatad86b5092018-10-16 15:50:21 -0700103 }
104 return message;
105 }
106
jcaterc52cfa42020-05-18 06:16:02 -0700107 /** {@link com.google.devtools.build.skyframe.SkyKey} for {@code ContainingPackageLookupValue}. */
janakr5fb2a482018-03-02 17:48:57 -0800108 @AutoCodec
janakr43c642d2018-10-18 09:05:08 -0700109 public static class Key extends AbstractSkyKey<PackageIdentifier> {
janakr5fb2a482018-03-02 17:48:57 -0800110 private static final Interner<Key> interner = BlazeInterners.newWeakInterner();
111
112 private Key(PackageIdentifier arg) {
113 super(arg);
114 }
115
116 @AutoCodec.VisibleForSerialization
117 @AutoCodec.Instantiator
118 static Key create(PackageIdentifier arg) {
119 return interner.intern(new Key(arg));
120 }
121
122 @Override
123 public SkyFunctionName functionName() {
124 return SkyFunctions.CONTAINING_PACKAGE_LOOKUP;
125 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100126 }
127
tomluee6a6862018-01-17 14:36:26 -0800128 public static ContainingPackage withContainingPackage(PackageIdentifier pkgId, Root root) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100129 return new ContainingPackage(pkgId, root);
130 }
131
Michajlo Matijkiw11184592015-10-16 19:00:45 +0000132 /** Value indicating there is no containing package. */
133 public static class NoContainingPackage extends ContainingPackageLookupValue {
Googler06eb1bb2019-02-26 15:33:15 -0800134 private final String reason;
135
136 private NoContainingPackage() {
137 this.reason = null;
138 }
139
140 NoContainingPackage(@Nonnull String reason) {
141 this.reason = reason;
142 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100143
144 @Override
145 public boolean hasContainingPackage() {
146 return false;
147 }
148
149 @Override
150 public PackageIdentifier getContainingPackageName() {
151 throw new IllegalStateException();
152 }
153
154 @Override
tomluee6a6862018-01-17 14:36:26 -0800155 public Root getContainingPackageRoot() {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100156 throw new IllegalStateException();
157 }
janakr6cf00a02018-11-09 12:26:30 -0800158
159 @Override
160 public String toString() {
161 return getClass().getName();
162 }
Googler06eb1bb2019-02-26 15:33:15 -0800163
164 @Override
165 public String getReasonForNoContainingPackage() {
166 return reason;
167 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 }
169
Michajlo Matijkiw11184592015-10-16 19:00:45 +0000170 /** A successful lookup value. */
shahanbbbf3dc2018-02-23 15:41:52 -0800171 @AutoCodec
Michajlo Matijkiw11184592015-10-16 19:00:45 +0000172 public static class ContainingPackage extends ContainingPackageLookupValue {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100173 private final PackageIdentifier containingPackage;
tomluee6a6862018-01-17 14:36:26 -0800174 private final Root containingPackageRoot;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100175
shahanbbbf3dc2018-02-23 15:41:52 -0800176 @AutoCodec.Instantiator
177 @AutoCodec.VisibleForSerialization
178 ContainingPackage(PackageIdentifier containingPackage, Root containingPackageRoot) {
179 this.containingPackage = containingPackage;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100180 this.containingPackageRoot = containingPackageRoot;
181 }
182
183 @Override
184 public boolean hasContainingPackage() {
185 return true;
186 }
187
188 @Override
189 public PackageIdentifier getContainingPackageName() {
190 return containingPackage;
191 }
192
193 @Override
tomluee6a6862018-01-17 14:36:26 -0800194 public Root getContainingPackageRoot() {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100195 return containingPackageRoot;
196 }
197
198 @Override
199 public boolean equals(Object obj) {
200 if (this == obj) {
201 return true;
202 }
203 if (!(obj instanceof ContainingPackage)) {
204 return false;
205 }
206 ContainingPackage other = (ContainingPackage) obj;
207 return containingPackage.equals(other.containingPackage)
208 && containingPackageRoot.equals(other.containingPackageRoot);
209 }
210
211 @Override
212 public int hashCode() {
213 return containingPackage.hashCode();
214 }
janakr6cf00a02018-11-09 12:26:30 -0800215
216 @Override
217 public String toString() {
218 return MoreObjects.toStringHelper(this)
219 .add("containingPackage", containingPackage)
220 .add("containingPackageRoot", containingPackageRoot)
221 .toString();
222 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100223 }
224}