bazel query --output=xml: avoid iterating over all possible values for
attr = select({"a": LABEL_LIST, "b": LABEL_LIST, ...}). This can be
exponential (w.r.t. the # of select conditions) and produce OOMs.

--
MOS_MIGRATED_REVID=137200979
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
index ae48fc4..2d9e4d4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
@@ -153,14 +153,13 @@
   }
 
   /**
-   * Returns all labels reachable via the given attribute. If a label is listed multiple times, each
-   * instance appears in the returned list.
+   * Returns all labels reachable via the given attribute, with duplicate instances removed.
    *
    * @param includeSelectKeys whether to include config_setting keys for configurable attributes
    */
-  public List<Label> getReachableLabels(String attributeName, boolean includeSelectKeys)
+  public Set<Label> getReachableLabels(String attributeName, boolean includeSelectKeys)
       throws InterruptedException {
-    final ImmutableList.Builder<Label> builder = ImmutableList.builder();
+    final ImmutableSet.Builder<Label> builder = ImmutableSet.<Label>builder();
     visitLabels(getAttributeDefinition(attributeName), includeSelectKeys,
         new AcceptsLabelAttribute() {
           @Override
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
index 2d7348f..fe1b706 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
@@ -16,6 +16,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.EnvironmentGroup;
@@ -131,8 +132,26 @@
       elem = doc.createElement("rule");
       elem.setAttribute("class", rule.getRuleClass());
       for (Attribute attr : rule.getAttributes()) {
-        Pair<Iterable<Object>, AttributeValueSource> values =
-            getPossibleAttributeValuesAndSources(rule, attr);
+        Pair<Iterable<Object>, AttributeValueSource> values;
+        if (attr.getType().equals(BuildType.LABEL_LIST)) {
+          // Avoid iterating over all possible values for a configurable label list, since all we
+          // care about are the raw labels. This avoids potential memory overruns. For example,
+          // given select({":c": ["//a:one", "//a:two"], ":d": ["//a:two"]]}), all we really need is
+          // ["//a:one", "//a:two"]. We don't care how exactly what combination of labels gets
+          // selected.
+
+          // TODO(gregce): Expand this to all collection types (we don't do this for scalars because
+          // there's currently no syntax for expressing multiple scalar values). This unfortunately
+          // isn't trivial because Bazel's label visitation logic includes special methods built
+          // directly into Type.
+          values = Pair.<Iterable<Object>, AttributeValueSource>of(
+              ImmutableList.<Object>of(
+                  AggregatingAttributeMapper.of(rule)
+                      .getReachableLabels(attr.getName(), /*includeSelectKeys=*/false)),
+              AttributeValueSource.RULE);
+        } else {
+          values = getPossibleAttributeValuesAndSources(rule, attr);
+        }
         if (values.second == AttributeValueSource.RULE || options.xmlShowDefaultValues) {
           Element attrElem = createValueElement(doc, attr.getType(), values.first);
           attrElem.setAttribute("name", attr.getName());