Convert ToolchainCollection to use AutoValue.
Also Break the subclass relationship between ExecGroupCollection and ToolchainCollection.
This adds toString, hashCode, and equals implementations for both classes.
PiperOrigin-RevId: 314338648
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index de3bbfe..026d10d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -1024,6 +1024,7 @@
deps = [
":toolchain_context",
"//src/main/java/com/google/devtools/build/lib/cmdline",
+ "//third_party:auto_value",
"//third_party:guava",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ExecGroupCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/ExecGroupCollection.java
index a7f8545..db8af35 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ExecGroupCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ExecGroupCollection.java
@@ -13,6 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.analysis;
+import static com.google.devtools.build.lib.analysis.ToolchainCollection.DEFAULT_EXEC_GROUP_NAME;
+
+import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.skylarkbuildapi.platform.ExecGroupCollectionApi;
@@ -29,16 +32,20 @@
* A {@link StarlarkIndexable} collection of resolved toolchain contexts that can be exposed to
* starlark.
*/
-public class ExecGroupCollection extends ToolchainCollection<ResolvedToolchainContext>
- implements ExecGroupCollectionApi {
+@AutoValue
+public abstract class ExecGroupCollection implements ExecGroupCollectionApi {
- public ExecGroupCollection(ToolchainCollection<ResolvedToolchainContext> toolchainCollection) {
- super(toolchainCollection);
+ /** Returns a new {@link ExecGroupCollection} backed by the given {@code toolchainCollection}. */
+ public static ExecGroupCollection create(
+ ToolchainCollection<ResolvedToolchainContext> toolchainCollection) {
+ return new AutoValue_ExecGroupCollection(toolchainCollection);
}
+ protected abstract ToolchainCollection<ResolvedToolchainContext> toolchainCollection();
+
@VisibleForTesting
public ImmutableMap<String, ResolvedToolchainContext> getToolchainCollectionForTesting() {
- return getContextMap();
+ return toolchainCollection().getContextMap();
}
public static boolean isValidGroupName(String execGroupName) {
@@ -48,7 +55,8 @@
@Override
public boolean containsKey(StarlarkSemantics semantics, Object key) throws EvalException {
String group = castGroupName(key);
- return !DEFAULT_EXEC_GROUP_NAME.equals(group) && getExecGroups().contains(group);
+ return !DEFAULT_EXEC_GROUP_NAME.equals(group)
+ && toolchainCollection().getExecGroups().contains(group);
}
/**
@@ -62,11 +70,11 @@
if (!containsKey(semantics, key)) {
throw Starlark.errorf(
"In %s, unrecognized exec group '%s' requested. Available exec groups: [%s]",
- getDefaultToolchainContext().targetDescription(),
+ toolchainCollection().getDefaultToolchainContext().targetDescription(),
execGroup,
String.join(", ", getScrubbedExecGroups()));
}
- return new ExecGroupContext(getToolchainContext(execGroup));
+ return new ExecGroupContext(toolchainCollection().getToolchainContext(execGroup));
}
private static String castGroupName(Object key) throws EvalException {
@@ -87,7 +95,7 @@
}
private List<String> getScrubbedExecGroups() {
- return getExecGroups().stream()
+ return toolchainCollection().getExecGroups().stream()
.filter(group -> !DEFAULT_EXEC_GROUP_NAME.equals(group))
.sorted()
.collect(Collectors.toList());
@@ -105,7 +113,7 @@
}
@Override
- public ResolvedToolchainContext toolchains() throws EvalException {
+ public ResolvedToolchainContext toolchains() {
return resolvedToolchainContext;
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 9d96691..79e1f75 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -1856,7 +1856,7 @@
this.toolchainContexts == null,
"toolchainContexts has already been set for this Builder");
this.toolchainContexts =
- new ToolchainCollection.Builder<ResolvedToolchainContext>()
+ ToolchainCollection.<ResolvedToolchainContext>builder()
.addDefaultContext(toolchainContext)
.build();
return this;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
index 206a8d6..4991889 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
@@ -15,6 +15,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
@@ -29,30 +30,56 @@
* @param <T> any class that extends ToolchainContext. This generic allows ToolchainCollection to be
* used, e.g., both before and after toolchain resolution.
*/
-public class ToolchainCollection<T extends ToolchainContext> {
+@AutoValue
+public abstract class ToolchainCollection<T extends ToolchainContext> {
// This is intentionally a string that would fail {@code Identifier.isValid} so that
// users can't create a group with the same name.
@VisibleForTesting public static final String DEFAULT_EXEC_GROUP_NAME = "default-exec-group";
/** A map of execution group names to toolchain contexts. */
- private final ImmutableMap<String, T> toolchainContexts;
+ public abstract ImmutableMap<String, T> getContextMap();
- private ToolchainCollection(Map<String, T> contexts) {
- Preconditions.checkArgument(contexts.containsKey(DEFAULT_EXEC_GROUP_NAME));
- toolchainContexts = ImmutableMap.copyOf(contexts);
+ T getDefaultToolchainContext() {
+ return getContextMap().get(DEFAULT_EXEC_GROUP_NAME);
}
- ToolchainCollection(ToolchainCollection<T> toCopy) {
- toolchainContexts = ImmutableMap.copyOf(toCopy.getContextMap());
+ boolean hasToolchainContext(String execGroup) {
+ return getContextMap().containsKey(execGroup);
+ }
+
+ public T getToolchainContext(String execGroup) {
+ return getContextMap().get(execGroup);
+ }
+
+ public ImmutableSet<Label> getResolvedToolchains() {
+ return getContextMap().values().stream()
+ .flatMap(c -> c.resolvedToolchainLabels().stream())
+ .collect(toImmutableSet());
+ }
+
+ ImmutableSet<String> getExecGroups() {
+ return getContextMap().keySet();
+ }
+
+ @SuppressWarnings("unchecked")
+ public ToolchainCollection<ToolchainContext> asToolchainContexts() {
+ return (ToolchainCollection<ToolchainContext>) this;
+ }
+
+ /** Returns a new builder for {@link ToolchainCollection} instances. */
+ public static <T extends ToolchainContext> Builder<T> builder() {
+ return new Builder<T>();
}
/** Builder for ToolchainCollection. */
- public static class Builder<T extends ToolchainContext> {
+ public static final class Builder<T extends ToolchainContext> {
+ // This is not immutable so that we can check for duplicate keys easily.
private final Map<String, T> toolchainContexts = new HashMap<>();
public ToolchainCollection<T> build() {
- return new ToolchainCollection<>(toolchainContexts);
+ Preconditions.checkArgument(toolchainContexts.containsKey(DEFAULT_EXEC_GROUP_NAME));
+ return new AutoValue_ToolchainCollection<T>(ImmutableMap.copyOf(toolchainContexts));
}
public void addContext(String execGroup, T context) {
@@ -68,34 +95,4 @@
return this;
}
}
-
- T getDefaultToolchainContext() {
- return toolchainContexts.get(DEFAULT_EXEC_GROUP_NAME);
- }
-
- boolean hasToolchainContext(String execGroup) {
- return toolchainContexts.containsKey(execGroup);
- }
-
- public T getToolchainContext(String execGroup) {
- return toolchainContexts.get(execGroup);
- }
-
- public ImmutableSet<Label> getResolvedToolchains() {
- return toolchainContexts.values().stream()
- .flatMap(c -> c.resolvedToolchainLabels().stream())
- .collect(toImmutableSet());
- }
-
- ImmutableSet<String> getExecGroups() {
- return toolchainContexts.keySet();
- }
-
- public ToolchainCollection<ToolchainContext> asToolchainContexts() {
- return new ToolchainCollection<>(ImmutableMap.copyOf(toolchainContexts));
- }
-
- public ImmutableMap<String, T> getContextMap() {
- return toolchainContexts;
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleContext.java
index 25eae40..5910713 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleContext.java
@@ -709,7 +709,8 @@
@Override
public ExecGroupCollection execGroups() {
- return new ExecGroupCollection(ruleContext.getToolchainContexts());
+ // Create a thin wrapper around the toolchain collection, to expose the Starlark API.
+ return ExecGroupCollection.create(ruleContext.getToolchainContexts());
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetAccessor.java b/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetAccessor.java
index e8a91d3..c8fe5d0 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetAccessor.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetAccessor.java
@@ -223,7 +223,7 @@
ImmutableMap<String, ExecGroup> execGroups = rule.getRuleClassObject().getExecGroups();
ToolchainCollection.Builder<UnloadedToolchainContext> toolchainContexts =
- new ToolchainCollection.Builder<>();
+ ToolchainCollection.builder();
try {
for (Map.Entry<String, ExecGroup> group : execGroups.entrySet()) {
ExecGroup execGroup = group.getValue();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 5601f39..627d206 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -421,7 +421,7 @@
configConditions,
unloadedToolchainContext == null
? null
- : new ToolchainCollection.Builder<>()
+ : ToolchainCollection.builder()
.addDefaultContext(unloadedToolchainContext)
.build(),
ruleClassProvider,
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index ef001ad..685c86f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -325,7 +325,7 @@
if (unloadedToolchainContexts != null) {
String targetDescription = target.toString();
ToolchainCollection.Builder<ResolvedToolchainContext> contextsBuilder =
- new ToolchainCollection.Builder<>();
+ ToolchainCollection.builder();
for (Map.Entry<String, UnloadedToolchainContext> unloadedContext :
unloadedToolchainContexts.getContextMap().entrySet()) {
contextsBuilder.addContext(
@@ -514,7 +514,7 @@
boolean valuesMissing = env.valuesMissing();
ToolchainCollection.Builder<UnloadedToolchainContext> toolchainContexts =
- valuesMissing ? null : new ToolchainCollection.Builder<>();
+ valuesMissing ? null : ToolchainCollection.builder();
for (Map.Entry<String, ToolchainContextKey> unloadedToolchainContextKey :
toolchainContextKeys.entrySet()) {
UnloadedToolchainContext unloadedToolchainContext =