aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/query2
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/query2')
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java282
2 files changed, 5 insertions, 292 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
index 9272e1d285..e8247c540a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
@@ -21,8 +21,8 @@ import com.google.common.collect.Sets;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.Node;
-import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.PackageSerializer;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -40,7 +40,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -450,10 +449,6 @@ public abstract class OutputFormatter implements Serializable {
* non-configured attributes, this is a single value. For configurable attributes, this
* may be multiple values.
*
- * <p>This is needed because the visibility attribute is replaced with an empty list
- * during package loading if it is public or private in order not to visit
- * the package called 'visibility'.
- *
* @return a pair, where the first value is the set of possible values and the
* second is an enum that tells where the values come from (declared on the
* rule, declared as a package level default or a
@@ -461,11 +456,9 @@ public abstract class OutputFormatter implements Serializable {
*/
protected static Pair<Iterable<Object>, AttributeValueSource> getAttributeValues(
Rule rule, Attribute attr) {
- List<Object> values = new LinkedList<>(); // Not an ImmutableList: may host null values.
AttributeValueSource source;
if (attr.getName().equals("visibility")) {
- values.add(rule.getVisibility().getDeclaredLabels());
if (rule.isVisibilitySpecified()) {
source = AttributeValueSource.RULE;
} else if (rule.getPackage().isDefaultVisibilitySet()) {
@@ -474,15 +467,11 @@ public abstract class OutputFormatter implements Serializable {
source = AttributeValueSource.DEFAULT;
}
} else {
- for (Object o :
- AggregatingAttributeMapper.of(rule).visitAttribute(attr.getName(), attr.getType())) {
- values.add(o);
- }
source = rule.isAttributeValueExplicitlySpecified(attr)
? AttributeValueSource.RULE : AttributeValueSource.DEFAULT;
}
- return Pair.of((Iterable<Object>) values, source);
+ return Pair.of(PackageSerializer.getAttributeValues(rule, attr), source);
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
index 0e22559d38..29f07ec804 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
@@ -13,57 +13,29 @@
// limitations under the License.
package com.google.devtools.build.lib.query2.output;
-import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
-import static com.google.devtools.build.lib.packages.Type.DISTRIBUTIONS;
-import static com.google.devtools.build.lib.packages.Type.FILESET_ENTRY_LIST;
-import static com.google.devtools.build.lib.packages.Type.INTEGER;
-import static com.google.devtools.build.lib.packages.Type.INTEGER_LIST;
-import static com.google.devtools.build.lib.packages.Type.LABEL;
-import static com.google.devtools.build.lib.packages.Type.LABEL_LIST;
-import static com.google.devtools.build.lib.packages.Type.LABEL_LIST_DICT;
-import static com.google.devtools.build.lib.packages.Type.LICENSE;
-import static com.google.devtools.build.lib.packages.Type.NODEP_LABEL;
-import static com.google.devtools.build.lib.packages.Type.NODEP_LABEL_LIST;
-import static com.google.devtools.build.lib.packages.Type.OUTPUT;
-import static com.google.devtools.build.lib.packages.Type.OUTPUT_LIST;
-import static com.google.devtools.build.lib.packages.Type.STRING;
-import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
-import static com.google.devtools.build.lib.packages.Type.STRING_DICT_UNARY;
-import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
-import static com.google.devtools.build.lib.packages.Type.STRING_LIST_DICT;
-import static com.google.devtools.build.lib.packages.Type.TRISTATE;
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.GENERATED_FILE;
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.PACKAGE_GROUP;
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.RULE;
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.SOURCE_FILE;
-import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.InputFile;
-import com.google.devtools.build.lib.packages.License;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.PackageGroup;
+import com.google.devtools.build.lib.packages.PackageSerializer;
import com.google.devtools.build.lib.packages.ProtoUtils;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
-import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.query2.FakeSubincludeTarget;
import com.google.devtools.build.lib.query2.output.OutputFormatter.UnorderedFormatter;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
-import com.google.devtools.build.lib.syntax.FilesetEntry;
-import com.google.devtools.build.lib.syntax.GlobCriteria;
-import com.google.devtools.build.lib.syntax.GlobList;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
import com.google.devtools.build.lib.util.BinaryPredicate;
import java.io.IOException;
import java.io.PrintStream;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
/**
* An output formatter that outputs a protocol buffer representation
@@ -136,7 +108,8 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
.setLocation(location);
for (Attribute attr : rule.getAttributes()) {
- addAttributeToProto(rulePb, attr, getAttributeValues(rule, attr).first, null,
+ PackageSerializer.addAttributeToProto(rulePb, attr,
+ PackageSerializer.getAttributeValues(rule, attr), null,
rule.isAttributeValueExplicitlySpecified(attr), false);
}
@@ -242,253 +215,4 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
return targetPb.build();
}
-
- /**
- * Adds the serialized version of the specified attribute to the specified message.
- *
- * @param rulePb the message to amend
- * @param attr the attribute to add
- * @param value the possible values of the attribute (can be a multi-value list for
- * configurable attributes)
- * @param location the location of the attribute in the source file
- * @param explicitlySpecified whether the attribute was explicitly specified or not
- * @param includeGlobs add glob expression for attributes that contain them
- */
- @SuppressWarnings("unchecked")
- public static void addAttributeToProto(
- Build.Rule.Builder rulePb, Attribute attr, Iterable<Object> values,
- Location location, Boolean explicitlySpecified, boolean includeGlobs) {
- // Get the attribute type. We need to convert and add appropriately
- com.google.devtools.build.lib.packages.Type<?> type = attr.getType();
-
- Build.Attribute.Builder attrPb = Build.Attribute.newBuilder();
-
- // Set the type, name and source
- attrPb.setName(attr.getName());
- attrPb.setType(ProtoUtils.getDiscriminatorFromType(type));
-
- if (location != null) {
- attrPb.setParseableLocation(serialize(location));
- }
-
- if (explicitlySpecified != null) {
- attrPb.setExplicitlySpecified(explicitlySpecified);
- }
-
- // Convenience binding for single-value attributes. Because those attributes can only
- // have a single value, when we encounter configurable versions of them we need to
- // react somehow to having multiple possible values to report. We currently just
- // refrain from setting *any* value in that scenario. This variable is set to null
- // to indicate that scenario.
- Object singleAttributeValue = Iterables.size(values) == 1
- ? Iterables.getOnlyElement(values)
- : null;
-
- /*
- * Set the appropriate type and value. Since string and string list store
- * values for multiple types, use the toString() method on the objects
- * instead of casting them. Note that Boolean and TriState attributes have
- * both an integer and string representation.
- */
- if (type == INTEGER) {
- if (singleAttributeValue != null) {
- attrPb.setIntValue((Integer) singleAttributeValue);
- }
- } else if (type == STRING || type == LABEL || type == NODEP_LABEL || type == OUTPUT) {
- if (singleAttributeValue != null) {
- attrPb.setStringValue(singleAttributeValue.toString());
- }
- } else if (type == STRING_LIST || type == LABEL_LIST || type == NODEP_LABEL_LIST
- || type == OUTPUT_LIST || type == DISTRIBUTIONS) {
- for (Object value : values) {
- for (Object entry : (Collection<?>) value) {
- attrPb.addStringListValue(entry.toString());
- }
- }
- } else if (type == INTEGER_LIST) {
- for (Object value : values) {
- for (Integer entry : (Collection<Integer>) value) {
- attrPb.addIntListValue(entry);
- }
- }
- } else if (type == BOOLEAN) {
- if (singleAttributeValue != null) {
- if ((Boolean) singleAttributeValue) {
- attrPb.setStringValue("true");
- attrPb.setBooleanValue(true);
- } else {
- attrPb.setStringValue("false");
- attrPb.setBooleanValue(false);
- }
- // This maintains partial backward compatibility for external users of the
- // protobuf that were expecting an integer field and not a true boolean.
- attrPb.setIntValue((Boolean) singleAttributeValue ? 1 : 0);
- }
- } else if (type == TRISTATE) {
- if (singleAttributeValue != null) {
- switch ((TriState) singleAttributeValue) {
- case AUTO:
- attrPb.setIntValue(-1);
- attrPb.setStringValue("auto");
- attrPb.setTristateValue(Build.Attribute.Tristate.AUTO);
- break;
- case NO:
- attrPb.setIntValue(0);
- attrPb.setStringValue("no");
- attrPb.setTristateValue(Build.Attribute.Tristate.NO);
- break;
- case YES:
- attrPb.setIntValue(1);
- attrPb.setStringValue("yes");
- attrPb.setTristateValue(Build.Attribute.Tristate.YES);
- break;
- default:
- throw new IllegalStateException("Execpted AUTO/NO/YES to cover all possible cases");
- }
- }
- } else if (type == LICENSE) {
- if (singleAttributeValue != null) {
- License license = (License) singleAttributeValue;
- Build.License.Builder licensePb = Build.License.newBuilder();
- for (License.LicenseType licenseType : license.getLicenseTypes()) {
- licensePb.addLicenseType(licenseType.toString());
- }
- for (Label exception : license.getExceptions()) {
- licensePb.addException(exception.toString());
- }
- attrPb.setLicense(licensePb);
- }
- } else if (type == STRING_DICT) {
- // TODO(bazel-team): support better de-duping here and in other dictionaries.
- for (Object value : values) {
- Map<String, String> dict = (Map<String, String>) value;
- for (Map.Entry<String, String> keyValueList : dict.entrySet()) {
- Build.StringDictEntry entry = Build.StringDictEntry.newBuilder()
- .setKey(keyValueList.getKey())
- .setValue(keyValueList.getValue())
- .build();
- attrPb.addStringDictValue(entry);
- }
- }
- } else if (type == STRING_DICT_UNARY) {
- for (Object value : values) {
- Map<String, String> dict = (Map<String, String>) value;
- for (Map.Entry<String, String> dictEntry : dict.entrySet()) {
- Build.StringDictUnaryEntry entry = Build.StringDictUnaryEntry.newBuilder()
- .setKey(dictEntry.getKey())
- .setValue(dictEntry.getValue())
- .build();
- attrPb.addStringDictUnaryValue(entry);
- }
- }
- } else if (type == STRING_LIST_DICT) {
- for (Object value : values) {
- Map<String, List<String>> dict = (Map<String, List<String>>) value;
- for (Map.Entry<String, List<String>> dictEntry : dict.entrySet()) {
- Build.StringListDictEntry.Builder entry = Build.StringListDictEntry.newBuilder()
- .setKey(dictEntry.getKey());
- for (Object dictEntryValue : dictEntry.getValue()) {
- entry.addValue(dictEntryValue.toString());
- }
- attrPb.addStringListDictValue(entry);
- }
- }
- } else if (type == LABEL_LIST_DICT) {
- for (Object value : values) {
- Map<String, List<Label>> dict = (Map<String, List<Label>>) value;
- for (Map.Entry<String, List<Label>> dictEntry : dict.entrySet()) {
- Build.LabelListDictEntry.Builder entry = Build.LabelListDictEntry.newBuilder()
- .setKey(dictEntry.getKey());
- for (Object dictEntryValue : dictEntry.getValue()) {
- entry.addValue(dictEntryValue.toString());
- }
- attrPb.addLabelListDictValue(entry);
- }
- }
- } else if (type == FILESET_ENTRY_LIST) {
- for (Object value : values) {
- List<FilesetEntry> filesetEntries = (List<FilesetEntry>) value;
- for (FilesetEntry filesetEntry : filesetEntries) {
- Build.FilesetEntry.Builder filesetEntryPb = Build.FilesetEntry.newBuilder()
- .setSource(filesetEntry.getSrcLabel().toString())
- .setDestinationDirectory(filesetEntry.getDestDir().getPathString())
- .setSymlinkBehavior(symlinkBehaviorToPb(filesetEntry.getSymlinkBehavior()))
- .setStripPrefix(filesetEntry.getStripPrefix())
- .setFilesPresent(filesetEntry.getFiles() != null);
-
- if (filesetEntry.getFiles() != null) {
- for (Label file : filesetEntry.getFiles()) {
- filesetEntryPb.addFile(file.toString());
- }
- }
-
- if (filesetEntry.getExcludes() != null) {
- for (String exclude : filesetEntry.getExcludes()) {
- filesetEntryPb.addExclude(exclude);
- }
- }
-
- attrPb.addFilesetListValue(filesetEntryPb);
- }
- }
- } else {
- throw new IllegalStateException("Unknown type: " + type);
- }
-
- if (includeGlobs) {
- for (Object value : values) {
- if (value instanceof GlobList<?>) {
- GlobList<?> globList = (GlobList<?>) value;
-
- for (GlobCriteria criteria : globList.getCriteria()) {
- Build.GlobCriteria.Builder criteriaPb = Build.GlobCriteria.newBuilder()
- .setGlob(criteria.isGlob());
- for (String include : criteria.getIncludePatterns()) {
- criteriaPb.addInclude(include);
- }
- for (String exclude : criteria.getExcludePatterns()) {
- criteriaPb.addExclude(exclude);
- }
-
- attrPb.addGlobCriteria(criteriaPb);
- }
- }
- }
- }
-
- rulePb.addAttribute(attrPb);
- }
-
- // This is needed because I do not want to use the SymlinkBehavior from the
- // protocol buffer all over the place, so there are two classes that do
- // essentially the same thing.
- private static Build.FilesetEntry.SymlinkBehavior symlinkBehaviorToPb(
- FilesetEntry.SymlinkBehavior symlinkBehavior) {
- switch (symlinkBehavior) {
- case COPY:
- return Build.FilesetEntry.SymlinkBehavior.COPY;
- case DEREFERENCE:
- return Build.FilesetEntry.SymlinkBehavior.DEREFERENCE;
- default:
- throw new AssertionError("Unhandled FilesetEntry.SymlinkBehavior");
- }
- }
-
- private static Build.Location serialize(Location location) {
- Build.Location.Builder result = Build.Location.newBuilder();
-
- result.setStartOffset(location.getStartOffset());
- if (location.getStartLineAndColumn() != null) {
- result.setStartLine(location.getStartLineAndColumn().getLine());
- result.setStartColumn(location.getStartLineAndColumn().getColumn());
- }
-
- result.setEndOffset(location.getEndOffset());
- if (location.getEndLineAndColumn() != null) {
- result.setEndLine(location.getEndLineAndColumn().getLine());
- result.setEndColumn(location.getEndLineAndColumn().getColumn());
- }
-
- return result.build();
- }
}