Stream TargetPattern#eval implementations' results to a callback rather than returning a ResolvedTargets set.

This is the second step in a series to allow processing large sets of targets in query target patterns via streaming batches rather than all at once. This should also be a functional no-op.

--
MOS_MIGRATED_REVID=111611858
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
index 6051597..6a23a64 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
@@ -148,7 +148,16 @@
    */
   public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver)
       throws TargetParsingException, InterruptedException {
-    return eval(resolver, ImmutableSet.<String>of());
+    final Set<T> results = CompactHashSet.create();
+    BatchCallback<T, RuntimeException> callback =
+        new BatchCallback<T, RuntimeException>() {
+          @Override
+          public void process(Iterable<T> partialResult) {
+            Iterables.addAll(results, partialResult);
+          }
+        };
+    eval(resolver, ImmutableSet.<String>of(), callback);
+    return ResolvedTargets.<T>builder().addAll(results).build();
   }
 
   /**
@@ -158,9 +167,11 @@
    * @throws IllegalArgumentException if {@code excludedSubdirectories} is nonempty and this
    *      pattern does not have type {@code Type.TARGETS_BELOW_DIRECTORY}.
    */
-  public abstract <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
-      ImmutableSet<String> excludedSubdirectories)
-      throws TargetParsingException, InterruptedException;
+  public abstract <T, E extends Exception> void eval(
+      TargetPatternResolver<T> resolver,
+      ImmutableSet<String> excludedSubdirectories,
+      BatchCallback<T, E> callback)
+      throws TargetParsingException, E, InterruptedException;
 
   /**
    * Returns {@code true} iff this pattern has type {@code Type.TARGETS_BELOW_DIRECTORY} and
@@ -208,13 +219,15 @@
     }
 
     @Override
-    public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
-        ImmutableSet<String> excludedSubdirectories)
-        throws TargetParsingException, InterruptedException {
+    public <T, E extends Exception> void eval(
+        TargetPatternResolver<T> resolver,
+        ImmutableSet<String> excludedSubdirectories,
+        BatchCallback<T, E> callback)
+        throws TargetParsingException, E, InterruptedException {
       Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
           "Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
           getOriginalPattern(), getType(), excludedSubdirectories);
-      return resolver.getExplicitTarget(label(targetName));
+      callback.process(resolver.getExplicitTarget(label(targetName)).getTargets());
     }
 
     @Override
@@ -260,30 +273,37 @@
     }
 
     @Override
-    public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
-        ImmutableSet<String> excludedSubdirectories)
-        throws TargetParsingException, InterruptedException {
+    public <T, E extends Exception> void eval(
+        TargetPatternResolver<T> resolver,
+        ImmutableSet<String> excludedSubdirectories,
+        BatchCallback<T, E> callback)
+        throws TargetParsingException, E, InterruptedException {
       Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
           "Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
           getOriginalPattern(), getType(), excludedSubdirectories);
       if (resolver.isPackage(PackageIdentifier.createInDefaultRepo(path))) {
         // User has specified a package name. lookout for default target.
-        return resolver.getExplicitTarget(label("//" + path));
-      }
+        callback.process(resolver.getExplicitTarget(label("//" + path)).getTargets());
+      } else {
 
-      List<String> pieces = SLASH_SPLITTER.splitToList(path);
+        List<String> pieces = SLASH_SPLITTER.splitToList(path);
 
-      // Interprets the label as a file target.  This loop stops as soon as the
-      // first BUILD file is found (i.e. longest prefix match).
-      for (int i = pieces.size() - 1; i > 0; i--) {
-        String packageName = SLASH_JOINER.join(pieces.subList(0, i));
-        if (resolver.isPackage(PackageIdentifier.createInDefaultRepo(packageName))) {
-          String targetName = SLASH_JOINER.join(pieces.subList(i, pieces.size()));
-          return resolver.getExplicitTarget(label("//" + packageName + ":" + targetName));
+        // Interprets the label as a file target.  This loop stops as soon as the
+        // first BUILD file is found (i.e. longest prefix match).
+        for (int i = pieces.size() - 1; i > 0; i--) {
+          String packageName = SLASH_JOINER.join(pieces.subList(0, i));
+          if (resolver.isPackage(PackageIdentifier.createInDefaultRepo(packageName))) {
+            String targetName = SLASH_JOINER.join(pieces.subList(i, pieces.size()));
+            callback.process(
+                resolver
+                    .getExplicitTarget(label("//" + packageName + ":" + targetName))
+                    .getTargets());
+            return;
+          }
         }
-      }
 
-      throw new TargetParsingException("couldn't determine target from filename '" + path + "'");
+        throw new TargetParsingException("couldn't determine target from filename '" + path + "'");
+      }
     }
 
     @Override
@@ -342,20 +362,26 @@
     }
 
     @Override
-    public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
-        ImmutableSet<String> excludedSubdirectories)
-        throws TargetParsingException, InterruptedException {
+    public <T, E extends Exception> void eval(
+        TargetPatternResolver<T> resolver,
+        ImmutableSet<String> excludedSubdirectories,
+        BatchCallback<T, E> callback)
+        throws TargetParsingException, E, InterruptedException {
       Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
           "Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
           getOriginalPattern(), getType(), excludedSubdirectories);
       if (checkWildcardConflict) {
         ResolvedTargets<T> targets = getWildcardConflict(resolver);
         if (targets != null) {
-          return targets;
+          callback.process(targets.getTargets());
+          return;
         }
       }
 
-      return resolver.getTargetsInPackage(getOriginalPattern(), packageIdentifier, rulesOnly);
+      callback.process(
+          resolver
+              .getTargetsInPackage(getOriginalPattern(), packageIdentifier, rulesOnly)
+              .getTargets());
     }
 
     @Override
@@ -446,17 +472,11 @@
     }
 
     @Override
-    public <T> ResolvedTargets<T> eval(TargetPatternResolver<T> resolver,
-        ImmutableSet<String> excludedSubdirectories)
-        throws TargetParsingException, InterruptedException {
-      final Set<T> results = CompactHashSet.create();
-      BatchCallback<T, RuntimeException> callback =
-          new BatchCallback<T, RuntimeException>() {
-            @Override
-            public void process(Iterable<T> partialResult) {
-              Iterables.addAll(results, partialResult);
-            }
-          };
+    public <T, E extends Exception> void eval(
+        TargetPatternResolver<T> resolver,
+        ImmutableSet<String> excludedSubdirectories,
+        BatchCallback<T, E> callback)
+        throws TargetParsingException, E, InterruptedException {
       resolver.findTargetsBeneathDirectory(
           directory.getRepository(),
           getOriginalPattern(),
@@ -464,7 +484,6 @@
           rulesOnly,
           excludedSubdirectories,
           callback);
-      return ResolvedTargets.<T>builder().addAll(results).build();
     }
 
     @Override