Refactor Query code a bit. Get rid of separate SkyframeQueryEnvironment, move some utility methods to utility class.

The real goal of this CL is to make sure all users of BlazeQueryEnvironment are constructing one through EvaluableBlazeQueryEnvironment#newQueryEnvironment, and not directly. This ensures that alternate implementations of EvaluableBlazeQueryEnvironment will be automatically injected via #newQueryEnvironment.

--
MOS_MIGRATED_REVID=86112439
diff --git a/src/main/java/com/google/devtools/build/lib/query2/BlazeQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/BlazeQueryEnvironment.java
index 0cc6da0..ede8ece 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/BlazeQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/BlazeQueryEnvironment.java
@@ -15,6 +15,7 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.graph.Digraph;
@@ -29,6 +30,7 @@
 import com.google.devtools.build.lib.pkgcache.TargetEdgeObserver;
 import com.google.devtools.build.lib.pkgcache.TargetPatternEvaluator;
 import com.google.devtools.build.lib.pkgcache.TargetProvider;
+import com.google.devtools.build.lib.pkgcache.TransitivePackageLoader;
 import com.google.devtools.build.lib.query2.engine.BlazeQueryEvalResult;
 import com.google.devtools.build.lib.query2.engine.QueryEvalResult;
 import com.google.devtools.build.lib.query2.engine.QueryException;
@@ -47,6 +49,9 @@
  * The environment of a Blaze query. Not thread-safe.
  */
 public class BlazeQueryEnvironment extends AbstractBlazeQueryEnvironment<Target> {
+
+  private static final int MAX_DEPTH_FULL_SCAN_LIMIT = 20;
+  private final TransitivePackageLoader transitivePackageLoader;
   private final TargetProvider targetProvider;
   private final Digraph<Target> graph = new Digraph<>();
   private final ErrorPrintingTargetEdgeErrorObserver errorObserver;
@@ -66,7 +71,8 @@
    *     the query execution is stopped with an error message.
    * @param settings a set of enabled settings
    */
-  public BlazeQueryEnvironment(PackageProvider packageProvider,
+  BlazeQueryEnvironment(TransitivePackageLoader transitivePackageLoader,
+      PackageProvider packageProvider,
       TargetPatternEvaluator targetPatternEvaluator,
       boolean keepGoing,
       boolean strictScope,
@@ -78,30 +84,13 @@
     super(targetPatternEvaluator, keepGoing, strictScope, labelFilter, eventHandler, settings,
         extraFunctions
     );
+    this.transitivePackageLoader = transitivePackageLoader;
     this.targetProvider = packageProvider;
     this.errorObserver = new ErrorPrintingTargetEdgeErrorObserver(this.eventHandler);
     this.loadingPhaseThreads = loadingPhaseThreads;
     this.labelVisitor = new LabelVisitor(packageProvider, dependencyFilter);
   }
 
-  /**
-   * Note that the correct operation of this class critically depends on the Reporter being a
-   * singleton object, shared by all cooperating classes contributing to Query.
-   * @param loadingPhaseThreads the number of threads to use during loading
-   *     the packages for the query.
-   * @param settings a set of enabled settings
-   */
-  public BlazeQueryEnvironment(PackageProvider packageProvider,
-      TargetPatternEvaluator targetPatternEvaluator,
-      boolean keepGoing,
-      int loadingPhaseThreads,
-      EventHandler eventHandler,
-      Set<Setting> settings,
-      Iterable<QueryFunction> extraFunctions) {
-    this(packageProvider, targetPatternEvaluator, keepGoing, /*strictScope=*/true,
-        loadingPhaseThreads, Rule.ALL_LABELS, eventHandler, settings, extraFunctions);
-  }
-
   @Override
   public BlazeQueryEvalResult<Target> evaluateQuery(QueryExpression expr) throws QueryException {
     QueryEvalResult<Target> queryEvalResult = super.evaluateQuery(expr);
@@ -234,9 +223,6 @@
         targetNode);
   }
 
-  protected void preloadTransitiveClosure(Set<Target> targets, int maxDepth) throws QueryException {
-  }
-
   @Override
   public void buildTransitiveClosure(QueryExpression caller,
                                      Set<Target> targetNodes,
@@ -261,6 +247,19 @@
     return getTargetsFromNodes(graph.getShortestPath(getNode(from), getNode(to)));
   }
 
+  private void preloadTransitiveClosure(Set<Target> targets, int maxDepth) throws QueryException {
+    if (maxDepth >= MAX_DEPTH_FULL_SCAN_LIMIT && transitivePackageLoader != null) {
+      // Only do the full visitation if "maxDepth" is large enough. Otherwise, the benefits of
+      // preloading will be outweighed by the cost of doing more work than necessary.
+      try {
+        transitivePackageLoader.sync(eventHandler, targets, ImmutableSet.<Label>of(), keepGoing,
+            loadingPhaseThreads, -1);
+      } catch (InterruptedException e) {
+        throw new QueryException("interrupted");
+      }
+    }
+  }
+
   /**
    * It suffices to synchronize the modifications of this.graph from within the
    * GraphBuildingObserver, because that's the only concurrent part.