Add a SkyQueryEnvironment which runs queries by examining the Skyframe graph.

This environment eagerly preloads the transitive closure of a specified query "universe", and so may not be as efficient as the standard query for limited-scope queries. It is activated when the universe is specified and ordered results are not requested (since it is currently unable to order results).

Tests were modified/added to exercise this environment where deemed interesting. Some ugly hacks were done to add coverage in AbstractQueryTest and friends, because currently even if the full depot is loaded (using //...), individual target patterns most likely won't be present in the graph. A better way to deal with this situation, suggested by felly, is probably to extract target pattern resolution logic to an auxiliary function so that query is able to resolve target patterns without mutating the graph, and then call into the read-only graph with the resolved patterns. That may be done in a follow-up, in which case the "scope" of every query could be //... .

--
MOS_MIGRATED_REVID=87257028
diff --git a/src/main/java/com/google/devtools/build/lib/query2/AbstractBlazeQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/AbstractBlazeQueryEnvironment.java
index de56c1b..96e8509 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/AbstractBlazeQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/AbstractBlazeQueryEnvironment.java
@@ -34,6 +34,7 @@
 import com.google.devtools.build.lib.query2.engine.QueryExpression;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.util.BinaryPredicate;
+import com.google.devtools.build.skyframe.WalkableGraph.WalkableGraphFactory;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -48,7 +49,6 @@
  */
 public abstract class AbstractBlazeQueryEnvironment<T> implements QueryEnvironment<T> {
   protected final ErrorSensingEventHandler eventHandler;
-  private final TargetPatternEvaluator targetPatternEvaluator;
   private final Map<String, Set<T>> letBindings = new HashMap<>();
   protected final Map<String, ResolvedTargets<Target>> resolvedTargetPatterns = new HashMap<>();
   protected final boolean keepGoing;
@@ -60,15 +60,13 @@
   private final Set<Setting> settings;
   private final List<QueryFunction> extraFunctions;
 
-  protected AbstractBlazeQueryEnvironment(TargetPatternEvaluator targetPatternEvaluator,
-      boolean keepGoing,
+  protected AbstractBlazeQueryEnvironment(boolean keepGoing,
       boolean strictScope,
       Predicate<Label> labelFilter,
       EventHandler eventHandler,
       Set<Setting> settings,
       Iterable<QueryFunction> extraFunctions) {
     this.eventHandler = new ErrorSensingEventHandler(eventHandler);
-    this.targetPatternEvaluator = targetPatternEvaluator;
     this.keepGoing = keepGoing;
     this.strictScope = strictScope;
     this.dependencyFilter = constructDependencyFilter(settings);
@@ -90,23 +88,31 @@
   }
 
   public static AbstractBlazeQueryEnvironment<Target> newQueryEnvironment(
-      TransitivePackageLoader transitivePackageLoader, PackageProvider packageProvider,
+      TransitivePackageLoader transitivePackageLoader, WalkableGraphFactory graphFactory,
+      PackageProvider packageProvider,
       TargetPatternEvaluator targetPatternEvaluator, boolean keepGoing, boolean orderedResults,
-      int loadingPhaseThreads,
+      List<String> universeScope, int loadingPhaseThreads,
       EventHandler eventHandler, Set<Setting> settings, Iterable<QueryFunction> functions) {
-    return newQueryEnvironment(transitivePackageLoader, packageProvider,
+    return newQueryEnvironment(transitivePackageLoader, graphFactory, packageProvider,
         targetPatternEvaluator, keepGoing, /*strictScope=*/true, orderedResults,
-        loadingPhaseThreads, Rule.ALL_LABELS, eventHandler, settings, functions);
+        universeScope, loadingPhaseThreads, Rule.ALL_LABELS, eventHandler, settings, functions);
   }
 
   public static AbstractBlazeQueryEnvironment<Target> newQueryEnvironment(
-      TransitivePackageLoader transitivePackageLoader, PackageProvider packageProvider,
+      TransitivePackageLoader transitivePackageLoader, WalkableGraphFactory graphFactory,
+      PackageProvider packageProvider,
       TargetPatternEvaluator targetPatternEvaluator, boolean keepGoing, boolean strictScope,
-      boolean orderedResults, int loadingPhaseThreads, Predicate<Label> labelFilter,
+      boolean orderedResults, List<String> universeScope, int loadingPhaseThreads,
+      Predicate<Label> labelFilter,
       EventHandler eventHandler, Set<Setting> settings, Iterable<QueryFunction> functions) {
-    return new BlazeQueryEnvironment(transitivePackageLoader, packageProvider,
+    Preconditions.checkNotNull(universeScope);
+    return orderedResults || universeScope.isEmpty()
+        ? new BlazeQueryEnvironment(transitivePackageLoader, packageProvider,
         targetPatternEvaluator, keepGoing, strictScope, loadingPhaseThreads,
-        labelFilter, eventHandler, settings, functions);
+        labelFilter, eventHandler, settings, functions)
+        : new SkyQueryEnvironment(
+            keepGoing, strictScope, loadingPhaseThreads, labelFilter, eventHandler, settings,
+            functions, targetPatternEvaluator.getOffset(), graphFactory, universeScope);
   }
 
   /**
@@ -119,9 +125,6 @@
    *   effect
    */
   public QueryEvalResult<T> evaluateQuery(QueryExpression expr) throws QueryException {
-    // Some errors are reported as QueryExceptions and others as ERROR events
-    // (if --keep_going).
-    eventHandler.resetErrors();
     resolvedTargetPatterns.clear();
 
     // In the --nokeep_going case, errors are reported in the order in which the patterns are
@@ -210,18 +213,8 @@
     return getTargetsMatchingPattern(caller, pattern);
   }
 
-  private Map<String, ResolvedTargets<Target>> preloadOrThrow(Collection<String> patterns)
-      throws TargetParsingException {
-    try {
-      // Note that this may throw a RuntimeException if deps are missing in Skyframe and this is
-      // being called from within a SkyFunction.
-      return targetPatternEvaluator.preloadTargetPatterns(
-          eventHandler, patterns, keepGoing);
-    } catch (InterruptedException e) {
-      // TODO(bazel-team): Propagate the InterruptedException from here [skyframe-loading].
-      throw new TargetParsingException("interrupted");
-    }
-  }
+  protected abstract Map<String, ResolvedTargets<Target>> preloadOrThrow(
+      Collection<String> patterns) throws QueryException, TargetParsingException;
 
   @Override
   public boolean isSettingEnabled(Setting setting) {
@@ -235,5 +228,4 @@
     builder.addAll(extraFunctions);
     return builder.build();
   }
-
 }