Introduce the transitions() function and "transition" type in Starlark.

This is under development and experimental, and is thus attached to the new flag --experimental_starlark_config_transitions. This new API is subject to change at any time until it is promoted out of "experimental".

RELNOTES: None.
PiperOrigin-RevId: 217533910
diff --git a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
index d685361..f011afe 100644
--- a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
+++ b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
@@ -47,6 +47,7 @@
 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.FakeConfigGlobalLibrary;
 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;
@@ -174,7 +175,8 @@
             new FakeAndroidNativeLibsInfoProvider());
     AppleBootstrap appleBootstrap = new AppleBootstrap(new FakeAppleCommon());
     ConfigBootstrap configBootstrap =
-        new ConfigBootstrap(new FakeConfigSkylarkCommon(), new FakeConfigApi());
+        new ConfigBootstrap(new FakeConfigSkylarkCommon(), new FakeConfigApi(),
+            new FakeConfigGlobalLibrary());
     CcBootstrap ccBootstrap = new CcBootstrap(new FakeCcModule());
     JavaBootstrap javaBootstrap =
         new JavaBootstrap(
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 42c7e7f..7a44895 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -614,6 +614,7 @@
         "//src/main/java/com/google/devtools/build/lib/shell",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
+        "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test",
         "//src/main/java/com/google/devtools/build/lib/vfs",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java
new file mode 100644
index 0000000..b9ee47a
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java
@@ -0,0 +1,47 @@
+// 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.lib.analysis.config;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+
+/**
+ * Implementation of {@link ConfigurationTransitionApi}.
+ *
+ * Represents a configuration transition across a dependency edge defined in Starlark.
+ */
+public class StarlarkDefinedConfigTransition implements ConfigurationTransitionApi {
+
+  private final BaseFunction impl;
+
+  public StarlarkDefinedConfigTransition(BaseFunction impl) {
+    this.impl = impl;
+  }
+
+  /**
+   * Returns the implementation function of this transition object.
+   *
+   * @see com.google.devtools.build.lib.skylarkbuildapi.config.ConfigGlobalLibraryApi#transition
+   *     for details on the function signature
+   */
+  public BaseFunction getImplementation() {
+    return impl;
+  }
+
+  @Override
+  public void repr(SkylarkPrinter printer) {
+    printer.append("<transition object>");
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
index 51019a7..f59d7de 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
@@ -20,6 +20,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.analysis.config.HostTransition;
+import com.google.devtools.build.lib.analysis.config.StarlarkDefinedConfigTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.Attribute;
@@ -255,10 +256,11 @@
         builder.cfg((SplitTransition) trans);
       } else if (trans instanceof SplitTransitionProvider) {
         builder.cfg((SplitTransitionProvider) trans);
-      } else if (trans instanceof BaseFunction) {
+      } else if (trans instanceof StarlarkDefinedConfigTransition) {
+        BaseFunction transImpl = ((StarlarkDefinedConfigTransition) trans).getImplementation();
         builder.hasFunctionTransition();
-        builder.cfg(new FunctionSplitTransitionProvider((BaseFunction) trans,
-                env.getSemantics(), env.getEventHandler()));
+        builder.cfg(new FunctionSplitTransitionProvider(transImpl,
+            env.getSemantics(), env.getEventHandler()));
       } else if (!trans.equals("target")) {
         throw new EvalException(ast.getLocation(),
             "cfg must be either 'data', 'host', or 'target'.");
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 4af330c..3ff7dff 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -123,6 +123,19 @@
           + "debugging.")
   public boolean experimentalPlatformsApi;
 
+  // TODO(cparsons): Resolve and finalize the transition() API. The transition implementation
+  // function should accept two mandatory parameters, 'settings' and 'attr'.
+  @Option(
+      name = "experimental_starlark_config_transitions",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
+      effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+      metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+      help =
+          "If set to true, enables creation of configuration transition objects (the "
+              + "`transition()` function) in Starlark.")
+  public boolean experimentalStarlarkConfigTransitions;
+
   @Option(
     name = "incompatible_bzl_disallow_load_after_statement",
     defaultValue = "false",
@@ -523,6 +536,7 @@
         .experimentalEnableRepoMapping(experimentalEnableRepoMapping)
         .experimentalRemapMainRepo(experimentalRemapMainRepo)
         .experimentalPlatformsApi(experimentalPlatformsApi)
+        .experimentalStarlarkConfigTransitions(experimentalStarlarkConfigTransitions)
         .incompatibleBzlDisallowLoadAfterStatement(incompatibleBzlDisallowLoadAfterStatement)
         .incompatibleDepsetIsNotIterable(incompatibleDepsetIsNotIterable)
         .incompatibleDepsetUnion(incompatibleDepsetUnion)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java
new file mode 100644
index 0000000..85f71a8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java
@@ -0,0 +1,43 @@
+// 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.lib.rules.config;
+
+import com.google.devtools.build.lib.analysis.config.StarlarkDefinedConfigTransition;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigGlobalLibraryApi;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics;
+import java.util.List;
+
+/**
+ * Implementation of {@link ConfigGlobalLibraryApi}.
+ *
+ * <p>A collection of top-level Starlark functions pertaining to configuration.
+ */
+public class ConfigGlobalLibrary implements ConfigGlobalLibraryApi {
+
+  @Override
+  public ConfigurationTransitionApi transition(BaseFunction implementation, List<String> inputs,
+      List<String> outputs, Location location, SkylarkSemantics semantics) throws EvalException {
+    if (!semantics.experimentalStarlarkConfigTransitions()) {
+      throw new EvalException(location, "transition() is experimental and disabled by default. "
+          + "This API is in development and subject to change at any time. Use "
+          + "--experimental_starlark_config_transitions to use this experimental API.");
+    }
+    return new StarlarkDefinedConfigTransition(implementation);
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRules.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRules.java
index 1281325..2f48187 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRules.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRules.java
@@ -43,7 +43,10 @@
 
     builder.addRuleDefinition(new ConfigRuleClasses.ConfigFeatureFlagRule());
     builder.addSkylarkBootstrap(
-        new ConfigBootstrap(new ConfigSkylarkCommon(), new SkylarkConfig()));
+        new ConfigBootstrap(
+            new ConfigSkylarkCommon(),
+            new SkylarkConfig(),
+            new ConfigGlobalLibrary()));
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/BUILD b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/BUILD
index 1f1b245..40f3069 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/BUILD
@@ -19,7 +19,9 @@
     name = "config",
     srcs = glob(["*.java"]),
     deps = [
+        "//src/main/java/com/google/devtools/build/lib:events",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
+        "//src/main/java/com/google/devtools/build/lib:syntax",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
         "//third_party:guava",
         "//third_party:jsr305",
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigBootstrap.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigBootstrap.java
index 80379a3..7300f5f 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigBootstrap.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigBootstrap.java
@@ -17,6 +17,7 @@
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.devtools.build.lib.skylarkbuildapi.Bootstrap;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkConfigApi;
+import com.google.devtools.build.lib.syntax.Runtime;
 
 /**
  * A {@link Bootstrap} for config-related libraries of the build API.
@@ -25,16 +26,21 @@
 
   private final ConfigSkylarkCommonApi configSkylarkCommonApi;
   private final SkylarkConfigApi skylarkConfigApi;
+  private final ConfigGlobalLibraryApi configGlobalLibrary;
 
   public ConfigBootstrap(
-      ConfigSkylarkCommonApi configSkylarkCommonApi, SkylarkConfigApi skylarkConfigApi) {
+      ConfigSkylarkCommonApi configSkylarkCommonApi,
+      SkylarkConfigApi skylarkConfigApi,
+      ConfigGlobalLibraryApi configGlobalLibrary) {
     this.configSkylarkCommonApi = configSkylarkCommonApi;
     this.skylarkConfigApi = skylarkConfigApi;
+    this.configGlobalLibrary = configGlobalLibrary;
   }
 
   @Override
   public void addBindingsToBuilder(Builder<String, Object> builder) {
     builder.put("config_common", configSkylarkCommonApi);
     builder.put("config", skylarkConfigApi);
+    Runtime.setupSkylarkLibrary(builder, configGlobalLibrary);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java
new file mode 100644
index 0000000..517b829
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java
@@ -0,0 +1,92 @@
+// 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.lib.skylarkbuildapi.config;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics;
+import java.util.List;
+
+/**
+ * A collection of top-level Starlark functions pertaining to configuration.
+ */
+@SkylarkGlobalLibrary
+public interface ConfigGlobalLibraryApi {
+  @SkylarkCallable(
+      name = "transition",
+      // TODO(cparsons): Improve documentation with an example once this feature is
+      // non-experimental.
+      doc =
+          "<b>Experimental. This type is experimental and subject to change at any time. Do "
+              + "not depend on it.</b><p> Creates a configuration transition to be applied across"
+              + " a dependency edge.",
+      parameters = {
+          @Param(
+              name = "implementation",
+              type = BaseFunction.class,
+              positional = false,
+              named = true,
+              // TODO(cparsons): The settings dict should take actual Label objects as keys and not
+              // strings. Update the documentation.
+              doc = "The function implementing this transition. This function always has the "
+                  + "parameter <code>settings</code>, a dictionary whose set of keys is defined by "
+                  + "the inputs parameter. So, for each build setting <code>--//foo=bar</code>, if "
+                  + "<code>inputs</code> contains <code>//foo</code>, <code>settings</code> will "
+                  + "have an entry <code>settings['//foo']='bar'</code>.<p>"
+                  // TODO(cparsons): Consider making this parameter mandatory, and determine
+                  // what to do with attributes which are defined with select().
+                  + "This function also optionally takes a parameter <code>attr</code> which is "
+                  + "a reference to <code>ctx.attr</code> but pre-analysis-phase. This gives the "
+                  + "implementation function access to the rule's attributes to make "
+                  + "attribute-parameterized transitions possible.<p>"
+                  // TODO(cparsons): Mention the expected output for split transitions.
+                  + "This function must return a <code>dict</code> from build setting identifier "
+                  + "to build setting value; this represents the configuration transition: for "
+                  + "each entry in the returned <code>dict</code>, the transition updates that "
+                  + "setting to the new value. All other settings are unchanged."),
+          @Param(
+              name = "inputs",
+              type = SkylarkList.class,
+              generic1 = String.class,
+              positional = false,
+              named = true,
+              doc = "List of build settings that can be read by this transition. This becomes the "
+                  + "key set of the settings parameter of the implementation function parameter."),
+          @Param(
+              name = "outputs",
+              type = SkylarkList.class,
+              generic1 = String.class,
+              positional = false,
+              named = true,
+              doc = "List of build settings that can be written by this transition. This must be "
+                  + "a superset of the key set of the dictionary returned by this transition."),
+      },
+      useLocation = true,
+      useSkylarkSemantics = true)
+  @SkylarkConstructor(objectType = ConfigurationTransitionApi.class)
+  public ConfigurationTransitionApi transition(
+      BaseFunction implementation,
+      List<String> inputs,
+      List<String> outputs,
+      Location location,
+      SkylarkSemantics semantics)
+      throws EvalException;
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigurationTransitionApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigurationTransitionApi.java
new file mode 100644
index 0000000..641ede4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigurationTransitionApi.java
@@ -0,0 +1,33 @@
+// 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.lib.skylarkbuildapi.config;
+
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+
+/**
+ * Represents a configuration transition across a dependency edge.
+ */
+@SkylarkModule(
+    name = "transition",
+    doc = "<b>Experimental. This type is experimental and subject to change at any time. Do "
+        + "not depend on it.</b><p> "
+        + "Represents a configuration transition across a dependency edge. For example, if "
+        + "<code>//package:foo</code> depends on <code>//package:bar</code> with a configuration "
+        + "transition, then the configuration of these two targets will differ: "
+        + "<code>//package:bar</code>'s transition will be determined by that of "
+        + "<code>//package:foo</code>, as subject to the function defined by a transition object."
+)
+public interface ConfigurationTransitionApi extends SkylarkValue {}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index 9fba528..0240a67 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -104,6 +104,8 @@
 
   public abstract boolean experimentalPlatformsApi();
 
+  public abstract boolean experimentalStarlarkConfigTransitions();
+
   public abstract boolean incompatibleBzlDisallowLoadAfterStatement();
 
   public abstract boolean incompatibleDepsetIsNotIterable();
@@ -181,6 +183,7 @@
           .experimentalEnableRepoMapping(false)
           .experimentalRemapMainRepo(false)
           .experimentalPlatformsApi(false)
+          .experimentalStarlarkConfigTransitions(false)
           .incompatibleBzlDisallowLoadAfterStatement(false)
           .incompatibleDepsetIsNotIterable(false)
           .incompatibleDepsetUnion(false)
@@ -228,6 +231,8 @@
 
     public abstract Builder experimentalPlatformsApi(boolean value);
 
+    public abstract Builder experimentalStarlarkConfigTransitions(boolean value);
+
     public abstract Builder incompatibleBzlDisallowLoadAfterStatement(boolean value);
 
     public abstract Builder incompatibleDepsetIsNotIterable(boolean value);
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
index db2ec31..1ef470f 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -57,6 +57,7 @@
 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.FakeConfigGlobalLibrary;
 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;
@@ -322,7 +323,8 @@
         new FakeAndroidNativeLibsInfoProvider());
     AppleBootstrap appleBootstrap = new AppleBootstrap(new FakeAppleCommon());
     ConfigBootstrap configBootstrap =
-        new ConfigBootstrap(new FakeConfigSkylarkCommon(), new FakeConfigApi());
+        new ConfigBootstrap(new FakeConfigSkylarkCommon(), new FakeConfigApi(),
+            new FakeConfigGlobalLibrary());
     CcBootstrap ccBootstrap = new CcBootstrap(new FakeCcModule());
     JavaBootstrap javaBootstrap = new JavaBootstrap(new FakeJavaCommon(),
         new FakeJavaInfoProvider(),
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/BUILD b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/BUILD
index 337cb58..2c13593 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/BUILD
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/BUILD
@@ -13,7 +13,9 @@
     name = "config",
     srcs = glob(["*.java"]),
     deps = [
+        "//src/main/java/com/google/devtools/build/lib:events",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
+        "//src/main/java/com/google/devtools/build/lib:syntax",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config",
         "//src/main/java/com/google/devtools/build/skydoc/fakebuildapi",
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java
new file mode 100644
index 0000000..69fe591
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java
@@ -0,0 +1,34 @@
+// 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.skydoc.fakebuildapi.config;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigGlobalLibraryApi;
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics;
+import java.util.List;
+
+/**
+ * Fake implementation of {@link ConfigGlobalLibraryApi}.
+ */
+public class FakeConfigGlobalLibrary implements ConfigGlobalLibraryApi {
+
+  @Override
+  public ConfigurationTransitionApi transition(BaseFunction implementation, List<String> inputs,
+      List<String> outputs, Location location, SkylarkSemantics semantics) {
+    return new FakeConfigurationTransition();
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigurationTransition.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigurationTransition.java
new file mode 100644
index 0000000..9f1ed7c
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigurationTransition.java
@@ -0,0 +1,27 @@
+// 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.skydoc.fakebuildapi.config;
+
+import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+
+/**
+ * Fake implementation of {@link ConfigurationTransitionApi}.
+ */
+public class FakeConfigurationTransition implements ConfigurationTransitionApi {
+
+  @Override
+  public void repr(SkylarkPrinter printer) {}
+}