Implement 'output_groups' provider.

This behavior - that 'output_groups' is a provider available
on targets and aspects - has been accidental, but people already depend
on it. This CL keeps that behavior, while fixing the bug that
two aspects could not both provide output groups.

--
MOS_MIGRATED_REVID=139578378
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
index d11e309..51954c13 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.analysis;
 
+import static com.google.devtools.build.lib.syntax.EvalUtils.SKYLARK_COMPARATOR;
+
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedSet;
@@ -24,11 +26,15 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.EvalUtils;
+import com.google.devtools.build.lib.syntax.SkylarkIndexable;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-
 import javax.annotation.Nullable;
 
 /**
@@ -45,7 +51,9 @@
  * not mentioned on the output.
  */
 @Immutable
-public final class OutputGroupProvider implements TransitiveInfoProvider {
+public final class OutputGroupProvider implements
+    TransitiveInfoProvider, SkylarkIndexable, Iterable<String> {
+  public static String SKYLARK_NAME = "output_groups";
 
   /**
    * Prefix for output groups that are not reported to the user on the terminal output of Blaze when
@@ -185,4 +193,33 @@
 
     return ImmutableSortedSet.copyOf(current);
   }
+
+  @Override
+  public Object getIndex(Object key, Location loc) throws EvalException {
+    if (!(key instanceof String)) {
+      throw new EvalException(loc, String.format(
+          "Output grout names must be strings, got %s instead",
+          EvalUtils.getDataTypeName(key)));
+    }
+
+    NestedSet<Artifact> result = outputGroups.get(key);
+    if (result != null) {
+      return SkylarkNestedSet.of(Artifact.class, result);
+    } else {
+      throw new EvalException(loc, String.format(
+          "Output group %s not present", key
+      ));
+    }
+
+  }
+
+  @Override
+  public boolean containsKey(Object key, Location loc) throws EvalException {
+    return outputGroups.containsKey(key);
+  }
+
+  @Override
+  public Iterator<String> iterator() {
+    return SKYLARK_COMPARATOR.sortedCopy(outputGroups.keySet()).iterator();
+  }
 }