Move QueryFunctions and InfoItems to ServerBuilder.

Initialize these from BlazeModule.serverInit instead of on-the-fly.

--
MOS_MIGRATED_REVID=131564738
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
index 4a48760..7304a26 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
@@ -28,12 +28,8 @@
 import com.google.devtools.build.lib.packages.Package;
 import com.google.devtools.build.lib.packages.PackageFactory;
 import com.google.devtools.build.lib.packages.RuleClassProvider;
-import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
-import com.google.devtools.build.lib.query2.QueryEnvironmentFactory;
-import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
 import com.google.devtools.build.lib.query2.output.OutputFormatter;
 import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory;
-import com.google.devtools.build.lib.runtime.commands.InfoItem;
 import com.google.devtools.build.lib.util.AbruptExitException;
 import com.google.devtools.build.lib.util.Clock;
 import com.google.devtools.build.lib.vfs.FileSystem;
@@ -227,26 +223,6 @@
   }
 
   /**
-   * Returns the additional information this module provides to "blaze info".
-   *
-   * <p>This method will be called at the beginning of each "blaze info" command (after
-   * #beforeCommand).
-   */
-  public Iterable<InfoItem> getInfoItems() {
-    return ImmutableList.of();
-  }
-
-  /**
-   * Returns the list of query functions this module provides to "blaze query".
-   *
-   * <p>This method will be called at the beginning of each "blaze query" command (after
-   * #beforeCommand).
-   */
-  public Iterable<QueryFunction> getQueryFunctions() {
-    return ImmutableList.of();
-  }
-
-  /**
    * Returns the action context providers the module contributes to Blaze, if any.
    *
    * <p>This method will be called at the beginning of the execution phase, e.g. of the
@@ -311,15 +287,6 @@
   }
 
   /**
-   * Returns a factory for creating {@link AbstractBlazeQueryEnvironment} objects.
-   * If the module does not provide any {@link QueryEnvironmentFactory}, it should return null. Note
-   * that only one factory per Bazel/Blaze runtime is allowed.
-   */
-  public QueryEnvironmentFactory getQueryEnvironmentFactory() {
-    return null;
-  }
-
-  /**
    * Optionally returns a provider for project files that can be used to bundle targets and
    * command-line options.
    */
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index 8087596..d8a07d2 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -17,6 +17,7 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.eventbus.SubscriberExceptionContext;
 import com.google.common.eventbus.SubscriberExceptionHandler;
@@ -43,9 +44,11 @@
 import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
 import com.google.devtools.build.lib.query2.QueryEnvironmentFactory;
+import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
 import com.google.devtools.build.lib.query2.output.OutputFormatter;
 import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory;
 import com.google.devtools.build.lib.runtime.BlazeCommandDispatcher.LockingMode;
+import com.google.devtools.build.lib.runtime.commands.InfoItem;
 import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
 import com.google.devtools.build.lib.server.AfUnixServer;
 import com.google.devtools.build.lib.server.RPCServer;
@@ -121,6 +124,11 @@
   private final PackageFactory packageFactory;
   private final ConfigurationFactory configurationFactory;
   private final ConfiguredRuleClassProvider ruleClassProvider;
+  // For bazel info.
+  private final ImmutableMap<String, InfoItem> infoItems;
+  // For bazel query.
+  private final QueryEnvironmentFactory queryEnvironmentFactory;
+  private final ImmutableList<QueryFunction> queryFunctions;
 
   private final AtomicInteger storedExitCode = new AtomicInteger();
 
@@ -131,7 +139,6 @@
   @Nullable
   private final InvocationPolicy invocationPolicy;
   private final String defaultsPackageContent;
-  private final QueryEnvironmentFactory queryEnvironmentFactory;
   private final SubscriberExceptionHandler eventBusExceptionHandler;
   private final String productName;
 
@@ -140,12 +147,18 @@
 
   private BlazeRuntime(
       QueryEnvironmentFactory queryEnvironmentFactory,
-      PackageFactory pkgFactory, ConfiguredRuleClassProvider ruleClassProvider,
-      ConfigurationFactory configurationFactory, Clock clock,
-      OptionsProvider startupOptionsProvider, Iterable<BlazeModule> blazeModules,
+      ImmutableList<QueryFunction> queryFunctions,
+      PackageFactory pkgFactory,
+      ConfiguredRuleClassProvider ruleClassProvider,
+      ConfigurationFactory configurationFactory,
+      ImmutableMap<String, InfoItem> infoItems,
+      Clock clock,
+      OptionsProvider startupOptionsProvider,
+      Iterable<BlazeModule> blazeModules,
       SubscriberExceptionHandler eventBusExceptionHandler,
       ProjectFile.Provider projectFileProvider,
-      InvocationPolicy invocationPolicy, Iterable<BlazeCommand> commands,
+      InvocationPolicy invocationPolicy,
+      Iterable<BlazeCommand> commands,
       String productName) {
     // Server state
     this.blazeModules = blazeModules;
@@ -157,9 +170,11 @@
 
     this.ruleClassProvider = ruleClassProvider;
     this.configurationFactory = configurationFactory;
+    this.infoItems = infoItems;
     this.clock = clock;
     this.startupOptionsProvider = startupOptionsProvider;
     this.queryEnvironmentFactory = queryEnvironmentFactory;
+    this.queryFunctions = queryFunctions;
     this.eventBusExceptionHandler = eventBusExceptionHandler;
 
     this.defaultsPackageContent =
@@ -280,6 +295,10 @@
     return queryEnvironmentFactory;
   }
 
+  public ImmutableList<QueryFunction> getQueryFunctions() {
+    return queryFunctions;
+  }
+
   /**
    * Returns the package factory.
    */
@@ -304,6 +323,10 @@
     return ruleClassProvider;
   }
 
+  public ImmutableMap<String, InfoItem> getInfoItems() {
+    return infoItems;
+  }
+
   public Iterable<BlazeModule> getBlazeModules() {
     return blazeModules;
   }
@@ -1100,9 +1123,11 @@
 
       return new BlazeRuntime(
           serverBuilder.getQueryEnvironmentFactory(),
+          serverBuilder.getQueryFunctions(),
           packageFactory,
           ruleClassProvider,
           configurationFactory,
+          serverBuilder.getInfoItems(),
           clock,
           startupOptionsProvider,
           ImmutableList.copyOf(blazeModules),
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java b/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
index d99e22c..13f5646 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/ServerBuilder.java
@@ -16,10 +16,13 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.packages.AttributeContainer;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
 import com.google.devtools.build.lib.query2.QueryEnvironmentFactory;
+import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
+import com.google.devtools.build.lib.runtime.commands.InfoItem;
 import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
 import com.google.devtools.build.lib.util.Preconditions;
 
@@ -32,6 +35,8 @@
   private final InvocationPolicy.Builder invocationPolicyBuilder = InvocationPolicy.newBuilder();
   private Function<RuleClass, AttributeContainer> attributeContainerFactory;
   private final ImmutableList.Builder<BlazeCommand> commands = ImmutableList.builder();
+  private final ImmutableMap.Builder<String, InfoItem> infoItems = ImmutableMap.builder();
+  private final ImmutableList.Builder<QueryFunction> queryFunctions = ImmutableList.builder();
 
   @VisibleForTesting
   public ServerBuilder() {}
@@ -52,6 +57,14 @@
         : attributeContainerFactory;
   }
 
+  ImmutableMap<String, InfoItem> getInfoItems() {
+    return infoItems.build();
+  }
+
+  ImmutableList<QueryFunction> getQueryFunctions() {
+    return queryFunctions.build();
+  }
+
   @VisibleForTesting
   public ImmutableList<BlazeCommand> getCommands() {
     return commands.build();
@@ -111,4 +124,21 @@
     this.commands.add(commands);
     return this;
   }
+
+  /**
+   * Adds the given items as info items to the info command. It is an error to add info items with
+   * the same name to the same builder, regardless of whether that happens within the same module or
+   * across modules.
+   */
+  public ServerBuilder addInfoItems(InfoItem... infoItems) {
+    for (InfoItem item : infoItems) {
+      this.infoItems.put(item.getName(), item);
+    }
+    return this;
+  }
+
+  public ServerBuilder addQueryFunctions(QueryFunction... functions) {
+    this.queryFunctions.add(functions);
+    return this;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
index 3f0dc5c..0d7fb6a 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
@@ -14,7 +14,6 @@
 package com.google.devtools.build.lib.runtime.commands;
 
 import com.google.common.base.Supplier;
-import com.google.common.base.Verify;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.NoBuildEvent;
@@ -23,7 +22,6 @@
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
 import com.google.devtools.build.lib.runtime.BlazeCommand;
-import com.google.devtools.build.lib.runtime.BlazeModule;
 import com.google.devtools.build.lib.runtime.BlazeRuntime;
 import com.google.devtools.build.lib.runtime.Command;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
@@ -234,15 +232,9 @@
   }
 
   static Map<String, InfoItem> getInfoItemMap(
-      CommandEnvironment env, OptionsProvider commandOptions) {
-    Map<String, InfoItem> result = new TreeMap<>();  // order by key
-    for (BlazeModule module : env.getRuntime().getBlazeModules()) {
-      for (InfoItem item : module.getInfoItems()) {
-        Verify.verify(!result.containsKey(item.getName()));
-        result.put(item.getName(), item);
-      }
-    }
-    result.putAll(getHardwiredInfoItemMap(commandOptions, env.getRuntime().getProductName()));
-    return result;
+      CommandEnvironment env, OptionsProvider optionsProvider) {
+    Map<String, InfoItem> items = new TreeMap<>(env.getRuntime().getInfoItems());
+    items.putAll(getHardwiredInfoItemMap(optionsProvider, env.getRuntime().getProductName()));
+    return items;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
index 1e587d7..9be185e 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
@@ -26,7 +26,6 @@
 import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
 import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
 import com.google.devtools.build.lib.query2.engine.OutputFormatterCallback;
-import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
 import com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting;
 import com.google.devtools.build.lib.query2.engine.QueryEvalResult;
 import com.google.devtools.build.lib.query2.engine.QueryException;
@@ -36,7 +35,6 @@
 import com.google.devtools.build.lib.query2.output.QueryOptions;
 import com.google.devtools.build.lib.query2.output.QueryOutputUtils;
 import com.google.devtools.build.lib.runtime.BlazeCommand;
-import com.google.devtools.build.lib.runtime.BlazeModule;
 import com.google.devtools.build.lib.runtime.BlazeRuntime;
 import com.google.devtools.build.lib.runtime.Command;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
@@ -272,25 +270,23 @@
   public static AbstractBlazeQueryEnvironment<Target> newQueryEnvironment(CommandEnvironment env,
       boolean keepGoing, boolean orderedResults, List<String> universeScope,
       int loadingPhaseThreads, Set<Setting> settings) {
-    ImmutableList.Builder<QueryFunction> functions = ImmutableList.builder();
-    for (BlazeModule module : env.getRuntime().getBlazeModules()) {
-      functions.addAll(module.getQueryFunctions());
-    }
-    return env.getRuntime().getQueryEnvironmentFactory().create(
-        env.getPackageManager().newTransitiveLoader(),
-        env.getSkyframeExecutor(),
-        env.getPackageManager(),
-        env.newTargetPatternEvaluator(),
-        keepGoing,
-        /*strictScope=*/ true,
-        orderedResults,
-        universeScope,
-        loadingPhaseThreads,
-        /*labelFilter=*/ ALL_LABELS,
-        env.getReporter(),
-        settings,
-        functions.build(),
-        env.getPackageManager().getPackagePath());
+    return env.getRuntime()
+        .getQueryEnvironmentFactory()
+        .create(
+            env.getPackageManager().newTransitiveLoader(),
+            env.getSkyframeExecutor(),
+            env.getPackageManager(),
+            env.newTargetPatternEvaluator(),
+            keepGoing,
+            /*strictScope=*/ true,
+            orderedResults,
+            universeScope,
+            loadingPhaseThreads,
+            /*labelFilter=*/ ALL_LABELS,
+            env.getReporter(),
+            settings,
+            env.getRuntime().getQueryFunctions(),
+            env.getPackageManager().getPackagePath());
   }
 
   private static class AggregateAllOutputFormatterCallback<T> extends OutputFormatterCallback<T> {