Add a ServerBuilder, and use that in the module API.

This change is similar to a previous change that introduced WorkspaceBuilder.

--
MOS_MIGRATED_REVID=126799657
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 ec7c7a0..2a22272 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
@@ -18,7 +18,6 @@
 import com.google.common.base.Function;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -35,10 +34,8 @@
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.OutputFilter;
 import com.google.devtools.build.lib.flags.CommandNameCache;
-import com.google.devtools.build.lib.packages.AttributeContainer;
 import com.google.devtools.build.lib.packages.Package;
 import com.google.devtools.build.lib.packages.PackageFactory;
-import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.profiler.AutoProfiler;
 import com.google.devtools.build.lib.profiler.MemoryProfiler;
@@ -51,19 +48,6 @@
 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.BuildCommand;
-import com.google.devtools.build.lib.runtime.commands.CanonicalizeCommand;
-import com.google.devtools.build.lib.runtime.commands.CleanCommand;
-import com.google.devtools.build.lib.runtime.commands.DumpCommand;
-import com.google.devtools.build.lib.runtime.commands.HelpCommand;
-import com.google.devtools.build.lib.runtime.commands.InfoCommand;
-import com.google.devtools.build.lib.runtime.commands.MobileInstallCommand;
-import com.google.devtools.build.lib.runtime.commands.ProfileCommand;
-import com.google.devtools.build.lib.runtime.commands.QueryCommand;
-import com.google.devtools.build.lib.runtime.commands.RunCommand;
-import com.google.devtools.build.lib.runtime.commands.ShutdownCommand;
-import com.google.devtools.build.lib.runtime.commands.TestCommand;
-import com.google.devtools.build.lib.runtime.commands.VersionCommand;
 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;
@@ -190,21 +174,6 @@
     this.productName = productName;
   }
 
-  private static InvocationPolicy createInvocationPolicyFromModules(
-      InvocationPolicy initialInvocationPolicy,
-      Iterable<BlazeModule> modules) {
-    InvocationPolicy.Builder builder = InvocationPolicy.newBuilder();
-    builder.mergeFrom(initialInvocationPolicy);
-    // Merge the policies from the modules
-    for (BlazeModule module : modules) {
-      InvocationPolicy modulePolicy = module.getInvocationPolicy();
-      if (modulePolicy != null) {
-        builder.mergeFrom(module.getInvocationPolicy());
-      }
-    }
-    return builder.build();
-  }
-
   public void initWorkspace(BlazeDirectories directories, BinTools binTools)
       throws AbruptExitException {
     boolean watchFS = startupOptionsProvider != null
@@ -248,11 +217,6 @@
     for (BlazeCommand command : commands) {
       addCommand(command);
     }
-    for (BlazeModule module : blazeModules) {
-      for (BlazeCommand command : module.getCommands()) {
-        addCommand(command);
-      }
-    }
   }
 
   public CommandEnvironment initCommand() {
@@ -993,10 +957,10 @@
       LoggingUtil.installRemoteLogger(getTestCrashLogger());
     }
 
+    runtimeBuilder.addBlazeModule(new BuiltinCommandModule());
     for (BlazeModule blazeModule : blazeModules) {
       runtimeBuilder.addBlazeModule(blazeModule);
     }
-    runtimeBuilder.addCommands(getBuiltinCommandList());
 
     BlazeRuntime runtime = runtimeBuilder.build();
     AutoProfiler.setClock(runtime.getClock());
@@ -1056,28 +1020,6 @@
         });
   }
 
-
-  /**
-   * Returns an immutable list containing new instances of each Blaze command.
-   */
-  @VisibleForTesting
-  public static List<BlazeCommand> getBuiltinCommandList() {
-    return ImmutableList.of(
-        new BuildCommand(),
-        new CanonicalizeCommand(),
-        new CleanCommand(),
-        new DumpCommand(),
-        new HelpCommand(),
-        new InfoCommand(),
-        new MobileInstallCommand(),
-        new ProfileCommand(),
-        new QueryCommand(),
-        new RunCommand(),
-        new ShutdownCommand(),
-        new TestCommand(),
-        new VersionCommand());
-  }
-
   public String getProductName() {
     return productName;
   }
@@ -1093,15 +1035,12 @@
    */
   public static class Builder {
     private BlazeDirectories directories;
-    private ConfigurationFactory configurationFactory;
     private Clock clock;
     private OptionsProvider startupOptionsProvider;
     private final List<BlazeModule> blazeModules = new ArrayList<>();
     private SubscriberExceptionHandler eventBusExceptionHandler = new RemoteExceptionHandler();
     private BinTools binTools;
     private UUID instanceId;
-    private final List<BlazeCommand> commands = new ArrayList<>();
-    private InvocationPolicy invocationPolicy = InvocationPolicy.getDefaultInstance();
     private String productName;
 
     public BlazeRuntime build() throws AbruptExitException {
@@ -1117,20 +1056,9 @@
         module.blazeStartup(startupOptionsProvider,
             BlazeVersionInfo.instance(), instanceId, directories, clock);
       }
-
-      QueryEnvironmentFactory queryEnvironmentFactory = null;
+      ServerBuilder serverBuilder = new ServerBuilder();
       for (BlazeModule module : blazeModules) {
-        QueryEnvironmentFactory queryEnvFactory = module.getQueryEnvironmentFactory();
-        if (queryEnvFactory != null) {
-          Preconditions.checkState(queryEnvironmentFactory == null,
-              "At most one query environment factory supported. But found two: %s and %s",
-              queryEnvFactory,
-              queryEnvironmentFactory);
-          queryEnvironmentFactory = queryEnvFactory;
-        }
-      }
-      if (queryEnvironmentFactory == null) {
-        queryEnvironmentFactory = new QueryEnvironmentFactory();
+        module.serverInit(startupOptionsProvider, serverBuilder);
       }
 
       ConfiguredRuleClassProvider.Builder ruleClassBuilder =
@@ -1139,35 +1067,6 @@
         module.initializeRuleClasses(ruleClassBuilder);
       }
 
-      Map<String, String> platformRegexps = null;
-      {
-        ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
-        for (BlazeModule module : blazeModules) {
-          builder.putAll(module.getPlatformSetRegexps());
-        }
-        platformRegexps = builder.build();
-        if (platformRegexps.isEmpty()) {
-          platformRegexps = null; // Use the default.
-        }
-      }
-
-      Function<RuleClass, AttributeContainer> attributeContainerFactory = null;
-      for (BlazeModule module : blazeModules) {
-        Function<RuleClass, AttributeContainer> attrContainerFactory =
-            module.getAttributeContainerSupplier();
-        if (attrContainerFactory != null) {
-          Preconditions.checkState(
-              attributeContainerFactory == null,
-              "At most one attribute container supplier supported. But found two: %s and %s",
-              attrContainerFactory,
-              attributeContainerFactory);
-          attributeContainerFactory = attrContainerFactory;
-        }
-      }
-      if (attributeContainerFactory == null) {
-        attributeContainerFactory = AttributeContainer.ATTRIBUTE_CONTAINER_FACTORY;
-      }
-
       ConfiguredRuleClassProvider ruleClassProvider = ruleClassBuilder.build();
 
       List<PackageFactory.EnvironmentExtension> extensions = new ArrayList<>();
@@ -1192,17 +1091,16 @@
       PackageFactory packageFactory =
           new PackageFactory(
               ruleClassProvider,
-              platformRegexps,
-              attributeContainerFactory,
+              ruleClassBuilder.getPlatformRegexps(),
+              serverBuilder.getAttributeContainerFactory(),
               extensions,
               BlazeVersionInfo.instance().getVersion(),
               packageBuilderHelper);
 
-      if (configurationFactory == null) {
-        configurationFactory = new ConfigurationFactory(
-            ruleClassProvider.getConfigurationCollectionFactory(),
-            ruleClassProvider.getConfigurationFragments());
-      }
+      ConfigurationFactory configurationFactory =
+          new ConfigurationFactory(
+              ruleClassProvider.getConfigurationCollectionFactory(),
+              ruleClassProvider.getConfigurationFragments());
 
       ProjectFile.Provider projectFileProvider = null;
       for (BlazeModule module : blazeModules) {
@@ -1214,12 +1112,20 @@
         }
       }
 
-      invocationPolicy = createInvocationPolicyFromModules(invocationPolicy, blazeModules);
-
-      BlazeRuntime runtime = new BlazeRuntime(queryEnvironmentFactory, packageFactory,
-          ruleClassProvider, configurationFactory, clock, startupOptionsProvider,
-          ImmutableList.copyOf(blazeModules), eventBusExceptionHandler, projectFileProvider,
-          invocationPolicy, commands, productName);
+      BlazeRuntime runtime =
+          new BlazeRuntime(
+              serverBuilder.getQueryEnvironmentFactory(),
+              packageFactory,
+              ruleClassProvider,
+              configurationFactory,
+              clock,
+              startupOptionsProvider,
+              ImmutableList.copyOf(blazeModules),
+              eventBusExceptionHandler,
+              projectFileProvider,
+              serverBuilder.getInvocationPolicy(),
+              serverBuilder.getCommands(),
+              productName);
       runtime.initWorkspace(directories, binTools);
       return runtime;
     }
@@ -1234,29 +1140,15 @@
       return this;
     }
 
-    public Builder setInvocationPolicy(InvocationPolicy invocationPolicy) {
-      this.invocationPolicy = invocationPolicy;
-      return this;
-    }
-
     public Builder setDirectories(BlazeDirectories directories) {
       this.directories = directories;
       return this;
     }
 
-    /**
-     * Creates and sets a new {@link BlazeDirectories} instance with the given
-     * parameters.
-     */
-    public Builder setDirectories(Path installBase, Path outputBase,
-        Path workspace, String productName) {
-      this.directories = new BlazeDirectories(installBase, outputBase, workspace, productName);
-      return this;
-    }
-
-    public Builder setConfigurationFactory(ConfigurationFactory configurationFactory) {
-      this.configurationFactory = configurationFactory;
-      return this;
+    /** Creates and sets a new {@link BlazeDirectories} instance with the given parameters. */
+    public Builder setDirectories(
+        Path installBase, Path outputBase, Path workspace, String productName) {
+      return setDirectories(new BlazeDirectories(installBase, outputBase, workspace, productName));
     }
 
     public Builder setClock(Clock clock) {
@@ -1285,15 +1177,5 @@
       this.eventBusExceptionHandler = eventBusExceptionHandler;
       return this;
     }
-
-    public Builder addCommands(BlazeCommand... commands) {
-      this.commands.addAll(Arrays.asList(commands));
-      return this;
-    }
-
-    public Builder addCommands(Iterable<BlazeCommand> commands) {
-      Iterables.addAll(this.commands, commands);
-      return this;
-    }
   }
 }