Exported global symbols from Bootstraps.

RELNOTES: None
PiperOrigin-RevId: 211445103
diff --git a/src/main/java/com/google/devtools/build/docgen/ApiExporter.java b/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
index de98f0d..aeed62b 100644
--- a/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
+++ b/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.docgen;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.docgen.builtin.BuiltinProtos.Builtins;
 import com.google.devtools.build.docgen.builtin.BuiltinProtos.Callable;
 import com.google.devtools.build.docgen.builtin.BuiltinProtos.Param;
@@ -22,78 +23,94 @@
 import com.google.devtools.build.docgen.skylark.SkylarkMethodDoc;
 import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc;
 import com.google.devtools.build.docgen.skylark.SkylarkParamDoc;
-import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
-import com.google.devtools.build.lib.util.Classpath.ClassPathException;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.EvalUtils;
+import com.google.devtools.build.lib.syntax.FuncallExpression;
 import com.google.devtools.common.options.OptionsParser;
 import java.io.BufferedOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 /** The main class for the Skylark documentation generator. */
 public class ApiExporter {
-  private static ConfiguredRuleClassProvider createRuleClassProvider(String classProvider)
-      throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
-          IllegalAccessException {
-    Class<?> providerClass = Class.forName(classProvider);
-    Method createMethod = providerClass.getMethod("create");
-    return (ConfiguredRuleClassProvider) createMethod.invoke(null);
-  }
 
-  private static void appendBuiltins(
-      ProtoFileBuildEncyclopediaProcessor processor, String filename) {
-    try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename))) {
-      Builtins.Builder builtins = Builtins.newBuilder();
+  private static void appendTypes(
+      Builtins.Builder builtins,
+      Map<String, SkylarkModuleDoc> types,
+      List<RuleDocumentation> nativeRules)
+      throws BuildEncyclopediaDocException {
 
-      Map<String, SkylarkModuleDoc> allTypes = SkylarkDocumentationCollector.collectModules();
-
-      // Add all global variables and functions in Builtins as Values.
-      SkylarkModuleDoc topLevelModule =
-          allTypes.remove(SkylarkDocumentationCollector.getTopLevelModule().name());
-      for (SkylarkMethodDoc meth : topLevelModule.getMethods()) {
-        builtins.addGlobal(collectFieldInfo(meth));
-      }
-      for (Map.Entry<String, SkylarkModuleDoc> modEntry : allTypes.entrySet()) {
+    for (Entry<String, SkylarkModuleDoc> modEntry : types.entrySet()) {
         SkylarkModuleDoc mod = modEntry.getValue();
 
-        // Include SkylarkModuleDoc in Builtins as a Type.
         Type.Builder type = Type.newBuilder();
         type.setName(mod.getName());
         type.setDoc(mod.getDocumentation());
         for (SkylarkMethodDoc meth : mod.getJavaMethods()) {
-          // Constructors should be exported as globals.
-          if (meth instanceof SkylarkConstructorMethodDoc) {
-            builtins.addGlobal(collectFieldInfo(meth));
-          } else {
-            type.addField(collectFieldInfo(meth));
+        // Constructors are exported as global symbols.
+        if (!(meth instanceof SkylarkConstructorMethodDoc)) {
+          type.addField(collectMethodInfo(meth));
           }
         }
         // Add native rules to the native type.
         if (mod.getName().equals("native")) {
-          for (Value.Builder rule : processor.getNativeRules()) {
-            type.addField(rule);
+        for (RuleDocumentation rule : nativeRules) {
+          type.addField(collectRuleInfo(rule));
           }
         }
         builtins.addType(type);
-
-        // Include SkylarkModuleDoc in Builtins as a Value.
-        Value.Builder value = Value.newBuilder();
-        value.setName(mod.getName());
-        value.setType(mod.getName());
-        value.setDoc(mod.getDocumentation());
-        builtins.addGlobal(value);
-      }
-      Builtins build = builtins.build();
-      build.writeTo(out);
-    } catch (IOException | ClassPathException e) {
-      System.err.println(e);
     }
   }
 
-  private static Value.Builder collectFieldInfo(SkylarkMethodDoc meth) {
+  private static void appendGlobals(Builtins.Builder builtins, Map<String, Object> globals) {
+    for (Entry<String, Object> entry : globals.entrySet()) {
+      Object obj = entry.getValue();
+
+      if (obj instanceof BaseFunction) {
+        builtins.addGlobal(collectFunctionInfo((BaseFunction) obj));
+      } else {
+        Value.Builder value = Value.newBuilder();
+        value.setName(entry.getKey());
+
+        SkylarkModule typeModule = SkylarkInterfaceUtils.getSkylarkModule(obj.getClass());
+        if (typeModule != null) {
+          if (FuncallExpression.hasSelfCallMethod(obj.getClass())) {
+            builtins.addGlobal(collectFunctionInfo(FuncallExpression.getSelfCallMethod(obj)));
+            continue;
+          }
+          value.setType(entry.getKey());
+          value.setDoc(typeModule.doc());
+        }
+        builtins.addGlobal(value);
+      }
+    }
+  }
+
+  private static Value.Builder collectFunctionInfo(BaseFunction func) {
+    Value.Builder value = Value.newBuilder();
+    value.setName(func.getName());
+    Callable.Builder callable = Callable.newBuilder();
+    ImmutableList<String> paramNames = func.getSignature().getSignature().getNames();
+
+    for (int i = 0; i < paramNames.size(); i++) {
+      Param.Builder param = Param.newBuilder();
+      param.setName(paramNames.get(i));
+      callable.addParam(param);
+    }
+    if (func.getObjectType() != null) {
+      callable.setReturnType(EvalUtils.getDataTypeNameFromClass(func.getObjectType(), false));
+    }
+    value.setCallable(callable);
+    return value;
+  }
+
+  private static Value.Builder collectMethodInfo(SkylarkMethodDoc meth) {
     Value.Builder field = Value.newBuilder();
     field.setName(meth.getShortName());
     field.setDoc(meth.getDocumentation());
@@ -115,6 +132,28 @@
     return field;
   }
 
+  private static Value.Builder collectRuleInfo(RuleDocumentation rule)
+      throws BuildEncyclopediaDocException {
+    Value.Builder value = Value.newBuilder();
+    value.setName(rule.getRuleName());
+    value.setDoc(rule.getHtmlDocumentation());
+    Callable.Builder callable = Callable.newBuilder();
+    for (RuleDocumentationAttribute attr : rule.getAttributes()) {
+      Param.Builder param = Param.newBuilder();
+      param.setName(attr.getAttributeName());
+      callable.addParam(param);
+    }
+    value.setCallable(callable);
+    return value;
+  }
+
+  private static void writeBuiltins(String filename, Builtins.Builder builtins) throws IOException {
+    try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename))) {
+      Builtins build = builtins.build();
+      build.writeTo(out);
+    }
+  }
+
   private static void printUsage(OptionsParser parser) {
     System.err.println(
         "Usage: api_exporter_bin -n product_name -p rule_class_provider (-i input_dir)+\n"
@@ -146,14 +185,18 @@
     }
 
     try {
-      ProtoFileBuildEncyclopediaProcessor processor =
-          new ProtoFileBuildEncyclopediaProcessor(
-              options.productName, createRuleClassProvider(options.provider));
-      processor.generateDocumentation(options.inputDirs, options.outputFile, options.blacklist);
+      SymbolFamilies symbols =
+          new SymbolFamilies(
+              options.productName, options.provider, options.inputDirs, options.blacklist);
+      Builtins.Builder builtins = Builtins.newBuilder();
 
-      appendBuiltins(processor, options.outputFile);
+      appendTypes(builtins, symbols.getTypes(), symbols.getNativeRules());
+      appendGlobals(builtins, symbols.getGlobalSymbols());
+      writeBuiltins(options.outputFile, builtins);
+
     } catch (Throwable e) {
       System.err.println("ERROR: " + e.getMessage());
+      e.printStackTrace();
     }
   }
 }
diff --git a/src/main/java/com/google/devtools/build/docgen/BUILD b/src/main/java/com/google/devtools/build/docgen/BUILD
index 7ea02a4..3585027 100644
--- a/src/main/java/com/google/devtools/build/docgen/BUILD
+++ b/src/main/java/com/google/devtools/build/docgen/BUILD
@@ -12,9 +12,11 @@
         "//src/main/java/com/google/devtools/build/lib:android-rules",
         "//src/main/java/com/google/devtools/build/lib:build-base",
         "//src/main/java/com/google/devtools/build/lib:classpath-util",
+        "//src/main/java/com/google/devtools/build/lib:events",
         "//src/main/java/com/google/devtools/build/lib:java-compilation",
         "//src/main/java/com/google/devtools/build/lib:java-rules",
         "//src/main/java/com/google/devtools/build/lib:packages",
+        "//src/main/java/com/google/devtools/build/lib:packages-internal",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib/actions",
         "//src/main/java/com/google/devtools/build/lib/collect/nestedset",
@@ -23,6 +25,25 @@
         "//src/main/java/com/google/devtools/build/lib/rules/cpp",
         "//src/main/java/com/google/devtools/build/lib/rules/objc",
         "//src/main/java/com/google/devtools/build/lib/rules/platform",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/android",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/apple",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/repository",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/platform",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test",
+        "//src/main/java/com/google/devtools/build/skydoc/rendering",
         "//src/main/java/com/google/devtools/common/options",
         "//src/main/protobuf:builtin_java_proto",
         "//third_party:apache_velocity",
@@ -61,5 +82,16 @@
 
 filegroup(
     name = "srcs",
-    srcs = glob(["**"]),
+    srcs = glob(["**"]) + [
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/android:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/apple:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/platform:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test:srcs",
+        "//src/main/java/com/google/devtools/build/skydoc/rendering:srcs",
+    ],
 )
diff --git a/src/main/java/com/google/devtools/build/docgen/ProtoFileBuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/ProtoFileBuildEncyclopediaProcessor.java
index 2d75605..6df86aa 100644
--- a/src/main/java/com/google/devtools/build/docgen/ProtoFileBuildEncyclopediaProcessor.java
+++ b/src/main/java/com/google/devtools/build/docgen/ProtoFileBuildEncyclopediaProcessor.java
@@ -14,25 +14,25 @@
 
 package com.google.devtools.build.docgen;
 
-import com.google.devtools.build.docgen.builtin.BuiltinProtos.Callable;
-import com.google.devtools.build.docgen.builtin.BuiltinProtos.Param;
-import com.google.devtools.build.docgen.builtin.BuiltinProtos.Value;
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
 /** Assembles a list of native rules that can be exported to a builtin.proto file. */
 public class ProtoFileBuildEncyclopediaProcessor extends BuildEncyclopediaProcessor {
-  private List<Value.Builder> nativeRules = null;
+  private ImmutableList<RuleDocumentation> nativeRules = null;
 
   public ProtoFileBuildEncyclopediaProcessor(
       String productName, ConfiguredRuleClassProvider ruleClassProvider) {
     super(productName, ruleClassProvider);
-    nativeRules = new ArrayList<>();
   }
 
+  /*
+   * Collects and processes all rule and attribute documentation in inputDirs and generates a list
+   * of RuleDocumentation objects.
+   */
   @Override
   public void generateDocumentation(List<String> inputDirs, String outputFile, String blackList)
       throws BuildEncyclopediaDocException, IOException {
@@ -41,25 +41,17 @@
     Map<String, RuleDocumentation> ruleDocEntries =
         collector.collect(inputDirs, blackList, expander);
     RuleFamilies ruleFamilies = assembleRuleFamilies(ruleDocEntries.values());
+    ImmutableList.Builder<RuleDocumentation> ruleDocsBuilder = new ImmutableList.Builder<>();
 
     for (RuleFamily entry : ruleFamilies.all) {
       for (RuleDocumentation doc : entry.getRules()) {
-        Value.Builder rule = Value.newBuilder();
-        rule.setName(doc.getRuleName());
-        rule.setDoc(doc.getHtmlDocumentation());
-        Callable.Builder callable = Callable.newBuilder();
-        for (RuleDocumentationAttribute attr : doc.getAttributes()) {
-          Param.Builder param = Param.newBuilder();
-          param.setName(attr.getAttributeName());
-          callable.addParam(param);
-        }
-        rule.setCallable(callable);
-        nativeRules.add(rule);
+        ruleDocsBuilder.add(doc);
       }
     }
+    nativeRules = ruleDocsBuilder.build();
   }
 
-  public List<Value.Builder> getNativeRules() {
+  public ImmutableList<RuleDocumentation> getNativeRules() {
     return nativeRules;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
new file mode 100644
index 0000000..3c08a42
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
@@ -0,0 +1,170 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.docgen;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.skylarkbuildapi.TopLevelBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.android.AndroidBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.apple.AppleBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.java.JavaBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.platform.PlatformBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.repository.RepositoryBootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.test.TestingBootstrap;
+import com.google.devtools.build.lib.syntax.MethodLibrary;
+import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.util.Classpath.ClassPathException;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeActionsInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeBuildApiGlobals;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeDefaultInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeOutputGroupInfo.FakeOutputGroupInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeSkylarkAttrApi;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeSkylarkCommandLineApi;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeSkylarkNativeModuleApi;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeSkylarkRuleFunctionsApi;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeStructApi.FakeStructProviderApi;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeAndroidDeviceBrokerInfo.FakeAndroidDeviceBrokerInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeAndroidInstrumentationInfo.FakeAndroidInstrumentationInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeAndroidNativeLibsInfo.FakeAndroidNativeLibsInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeAndroidResourcesInfo.FakeAndroidResourcesInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeAndroidSkylarkCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.android.FakeApkInfo.FakeApkInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.apple.FakeAppleCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.config.FakeConfigSkylarkCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeCcModule;
+import com.google.devtools.build.skydoc.fakebuildapi.java.FakeJavaCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.java.FakeJavaInfo.FakeJavaInfoProvider;
+import com.google.devtools.build.skydoc.fakebuildapi.java.FakeJavaProtoCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.platform.FakePlatformCommon;
+import com.google.devtools.build.skydoc.fakebuildapi.repository.FakeRepositoryModule;
+import com.google.devtools.build.skydoc.fakebuildapi.test.FakeTestingModule;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A helper class that collects Starlark Api symbols including top level modules, native rules and
+ * builtin types.
+ */
+public class SymbolFamilies {
+  private final ImmutableList<RuleDocumentation> nativeRules;
+  private final ImmutableMap<String, Object> globalSymbols;
+  private final ImmutableMap<String, SkylarkModuleDoc> types;
+
+  public SymbolFamilies(
+      String productName, String provider, List<String> inputDirs, String blackList)
+      throws NoSuchMethodException, ClassPathException, InvocationTargetException,
+          IllegalAccessException, BuildEncyclopediaDocException, ClassNotFoundException,
+          IOException {
+    this.nativeRules =
+        ImmutableList.copyOf(collectNativeRules(productName, provider, inputDirs, blackList));
+    this.globalSymbols = ImmutableMap.copyOf(collectGlobalSymbols());
+    this.types = ImmutableMap.copyOf(collectTypes());
+  }
+
+  /*
+   * Returns a list of native rules.
+   */
+  public List<RuleDocumentation> getNativeRules() {
+    return nativeRules;
+  }
+
+  /*
+   * Returns a mapping between Starlark module names and Starkark entities generated from the
+   * fakebuildapi.
+   */
+  public Map<String, Object> getGlobalSymbols() {
+    return globalSymbols;
+  }
+
+  // Returns a mapping between type names and module/type documentation.
+  public Map<String, SkylarkModuleDoc> getTypes() {
+    return types;
+  }
+
+  private Map<String, SkylarkModuleDoc> collectTypes() throws ClassPathException {
+    return SkylarkDocumentationCollector.collectModules();
+  }
+
+  private List<RuleDocumentation> collectNativeRules(
+      String productName, String provider, List<String> inputDirs, String blackList)
+      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+          BuildEncyclopediaDocException, ClassNotFoundException, IOException {
+    ProtoFileBuildEncyclopediaProcessor processor =
+        new ProtoFileBuildEncyclopediaProcessor(productName, createRuleClassProvider(provider));
+    processor.generateDocumentation(inputDirs, "", blackList);
+    return processor.getNativeRules();
+  }
+
+  private Map<String, Object> collectGlobalSymbols() {
+    ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder();
+    TopLevelBootstrap topLevelBootstrap =
+        new TopLevelBootstrap(
+            new FakeBuildApiGlobals(),
+            new FakeSkylarkAttrApi(),
+            new FakeSkylarkCommandLineApi(),
+            new FakeSkylarkNativeModuleApi(),
+            new FakeSkylarkRuleFunctionsApi(Lists.newArrayList()),
+            new FakeStructProviderApi(),
+            new FakeOutputGroupInfoProvider(),
+            new FakeActionsInfoProvider(),
+            new FakeDefaultInfoProvider());
+    AndroidBootstrap androidBootstrap =
+        new AndroidBootstrap(
+            new FakeAndroidSkylarkCommon(),
+            new FakeApkInfoProvider(),
+            new FakeAndroidInstrumentationInfoProvider(),
+            new FakeAndroidDeviceBrokerInfoProvider(),
+            new FakeAndroidResourcesInfoProvider(),
+            new FakeAndroidNativeLibsInfoProvider());
+    AppleBootstrap appleBootstrap = new AppleBootstrap(new FakeAppleCommon());
+    ConfigBootstrap configBootstrap = new ConfigBootstrap(new FakeConfigSkylarkCommon());
+    CcBootstrap ccBootstrap = new CcBootstrap(new FakeCcModule());
+    JavaBootstrap javaBootstrap =
+        new JavaBootstrap(
+            new FakeJavaCommon(), new FakeJavaInfoProvider(), new FakeJavaProtoCommon());
+    PlatformBootstrap platformBootstrap = new PlatformBootstrap(new FakePlatformCommon());
+    RepositoryBootstrap repositoryBootstrap = new RepositoryBootstrap(new FakeRepositoryModule());
+    TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule());
+
+    Runtime.addConstantsToBuilder(envBuilder);
+    MethodLibrary.addBindingsToBuilder(envBuilder);
+    topLevelBootstrap.addBindingsToBuilder(envBuilder);
+    androidBootstrap.addBindingsToBuilder(envBuilder);
+    appleBootstrap.addBindingsToBuilder(envBuilder);
+    ccBootstrap.addBindingsToBuilder(envBuilder);
+    configBootstrap.addBindingsToBuilder(envBuilder);
+    javaBootstrap.addBindingsToBuilder(envBuilder);
+    platformBootstrap.addBindingsToBuilder(envBuilder);
+    repositoryBootstrap.addBindingsToBuilder(envBuilder);
+    testingBootstrap.addBindingsToBuilder(envBuilder);
+
+    return envBuilder.build();
+  }
+
+  private ConfiguredRuleClassProvider createRuleClassProvider(String classProvider)
+      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+          ClassNotFoundException {
+    Class<?> providerClass = Class.forName(classProvider);
+    Method createMethod = providerClass.getMethod("create");
+    return (ConfiguredRuleClassProvider) createMethod.invoke(null);
+  }
+}