Substitution: handle NestedSet separately from List
I'm getting close to making NestedSet not implement Iterable, which
requires that we use two separate classes here.
@@ -24,7 +24,6 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
/**
* A pair of a string to be substituted and a string to substitute it with. For simplicity, these
@@ -102,6 +101,24 @@ public abstract class Substitution {
return new ListSubstitution(key, value);
}
+ /**
+ * Returns an immutable Substitution instance for the key and list of values. The values will be
+ * joined by the given string before substitution.
+ */
+ public static Substitution ofJoinedShortPaths(
+ String key, ImmutableList<Artifact> artifacts, String joinStr) {
+ return new JoinedArtifactListShortPathSubstitution(key, artifacts, joinStr);
+ }
+
+ /**
+ * Returns an immutable Substitution instance for the key and list of values. The values will be
+ * joined by the given string before substitution.
+ */
+ public static Substitution ofJoinedShortPaths(
+ String key, NestedSet<Artifact> artifacts, String joinStr) {
+ return new JoinedArtifactNestedSetShortPathSubstitution(key, artifacts, joinStr);
+ }
+
@Override
public boolean equals(Object object) {
if (this == object) {
@@ -195,23 +212,40 @@ public abstract class Substitution {
* <p>This is much more memory efficient than eagerly joining them into a string.
*/
@AutoCodec
- public static final class JoinedArtifactShortPathSubstitution extends ComputedSubstitution {
- private final Iterable<Artifact> artifacts;
+ public static final class JoinedArtifactListShortPathSubstitution extends ComputedSubstitution {
+ private final ImmutableList<Artifact> artifacts;
private final String joinStr;
- public JoinedArtifactShortPathSubstitution(
+ @AutoCodec.Instantiator
+ public JoinedArtifactListShortPathSubstitution(
String key, ImmutableList<Artifact> artifacts, String joinStr) {
- this(key, (Iterable<Artifact>) artifacts, joinStr);
+ super(key);
+ this.artifacts = artifacts;
+ this.joinStr = joinStr;
}
- public JoinedArtifactShortPathSubstitution(
- String key, NestedSet<Artifact> artifacts, String joinStr) {
- this(key, (Iterable<Artifact>) artifacts, joinStr);
+ @Override
+ public String getValue() {
+ return artifacts.stream()
+ .map(artifact -> artifact.getRootRelativePath().getPathString())
+ .collect(Collectors.joining(joinStr));
+ }
}
- @AutoCodec.VisibleForSerialization
+ /**
+ * Expands a collection of artifacts to their short (root relative paths).
+ *
+ * <p>This is much more memory efficient than eagerly joining them into a string.
+ */
+ @AutoCodec
+ public static final class JoinedArtifactNestedSetShortPathSubstitution
+ extends ComputedSubstitution {
+ private final NestedSet<Artifact> artifacts;
+ private final String joinStr;
+
@AutoCodec.Instantiator
- JoinedArtifactShortPathSubstitution(String key, Iterable<Artifact> artifacts, String joinStr) {
+ public JoinedArtifactNestedSetShortPathSubstitution(
+ String key, NestedSet<Artifact> artifacts, String joinStr) {
super(key);
this.artifacts = artifacts;
this.joinStr = joinStr;
@@ -219,7 +253,7 @@ public abstract class Substitution {
@Override
public String getValue() {
- return StreamSupport.stream(artifacts.spliterator(), false)
+ return artifacts.toList().stream()
.map(artifact -> artifact.getRootRelativePath().getPathString())
.collect(Collectors.joining(joinStr));
}
