Add toolchains data to RuleClass and RuleContext.

Also expose both sides to Skylark.
Part of #2219.

Change-Id: I4d749dd9981fe33f75310acb0ec3927cff6f28fe
PiperOrigin-RevId: 156340638
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
index b0a23b4..63ccc24 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -908,6 +908,7 @@
             .setMissingFragmentPolicy(missingFragmentPolicy)
             .build(),
         supportsConstraintChecking,
+        /*requiredToolchains=*/ ImmutableList.<ClassObjectConstructor.Key>of(),
         attributes);
   }
 
@@ -1040,4 +1041,21 @@
       // expected
     }
   }
+
+  @Test
+  public void testRequiredToolchains() throws Exception {
+    RuleClass.Builder ruleClassBuilder =
+        new RuleClass.Builder("ruleClass", RuleClassType.NORMAL, false)
+            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+            .add(attr("tags", STRING_LIST));
+
+    ClassObjectConstructor.Key toolchain1 = new ClassObjectConstructor.Key() {};
+    ClassObjectConstructor.Key toolchain2 = new ClassObjectConstructor.Key() {};
+    ruleClassBuilder.addRequiredToolchain(toolchain1);
+    ruleClassBuilder.addRequiredToolchain(toolchain2);
+
+    RuleClass ruleClass = ruleClassBuilder.build();
+
+    assertThat(ruleClass.getRequiredToolchains()).containsExactly(toolchain1, toolchain2).inOrder();
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/BUILD b/src/test/java/com/google/devtools/build/lib/skylark/BUILD
index 0cd4824..52a35a8 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/skylark/BUILD
@@ -20,6 +20,7 @@
         "//src/main/java/com/google/devtools/build/lib:packages",
         "//src/main/java/com/google/devtools/build/lib:vfs",
         "//src/main/java/com/google/devtools/build/lib/actions",
+        "//src/main/java/com/google/devtools/build/lib/rules/platform",
         "//src/test/java/com/google/devtools/build/lib:analysis_testutil",
         "//src/test/java/com/google/devtools/build/lib:foundations_testutil",
         "//src/test/java/com/google/devtools/build/lib:syntax_testutil",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index 8852be8..2be126b 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -42,6 +42,7 @@
 import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
+import com.google.devtools.build.lib.packages.ToolchainConstructor;
 import com.google.devtools.build.lib.rules.SkylarkAttr;
 import com.google.devtools.build.lib.rules.SkylarkAttr.Descriptor;
 import com.google.devtools.build.lib.rules.SkylarkFileType;
@@ -1377,5 +1378,15 @@
           + "provided.");
     }
   }
-}
 
+  @Test
+  public void testRuleAddToolchain() throws Exception {
+    evalAndExport(
+        "my_toolchain_type = platform_common.toolchain_type()",
+        "def impl(ctx): return None",
+        "r1 = rule(impl, toolchains=[my_toolchain_type])");
+    ToolchainConstructor toolchain = (ToolchainConstructor) lookup("my_toolchain_type");
+    RuleClass c = ((RuleFunction) lookup("r1")).getRuleClass();
+    assertThat(c.getRequiredToolchains()).containsExactly(toolchain.getKey());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
index 8c86c07..e416997 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
@@ -26,12 +26,14 @@
 import com.google.devtools.build.lib.packages.PackageFactory.PackageContext;
 import com.google.devtools.build.lib.rules.SkylarkModules;
 import com.google.devtools.build.lib.rules.SkylarkRuleContext;
+import com.google.devtools.build.lib.rules.platform.PlatformCommon;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.Environment.Phase;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.SkylarkUtils;
 import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
 import com.google.devtools.build.lib.testutil.TestConstants;
+import java.util.List;
 import org.junit.Before;
 
 /**
@@ -52,10 +54,15 @@
     return new EvaluationTestCase() {
       @Override
       public Environment newEnvironment() throws Exception {
+        List<Class<?>> modules =
+            new ImmutableList.Builder<Class<?>>()
+                .addAll(SkylarkModules.MODULES)
+                .add(PlatformCommon.class)
+                .build();
         Environment env =
             Environment.builder(mutability)
                 .setEventHandler(getEventHandler())
-                .setGlobals(SkylarkModules.getGlobals(SkylarkModules.MODULES))
+                .setGlobals(SkylarkModules.getGlobals(modules))
                 .setPhase(Phase.LOADING)
                 .build()
                 .setupDynamic(