Add toolchains attribute to aspect.

Part of #2219.

Change-Id: I39ced1f3e2605154771df9424d6ed2f971820baf
PiperOrigin-RevId: 157002268
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index b1ec35d..3e48b7a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -244,6 +244,9 @@
             .setConfigConditions(configConditions)
             .setUniversalFragment(ruleClassProvider.getUniversalFragment())
             .setSkylarkProvidersRegistry(ruleClassProvider.getRegisteredSkylarkProviders())
+            // TODO(katre): Populate the actual selected toolchains.
+            .setToolchainContext(
+                new ToolchainContext(rule.getRuleClassObject().getRequiredToolchains(), null))
             .build();
     if (ruleContext.hasErrors()) {
       return null;
@@ -350,6 +353,9 @@
             .setAspectAttributes(aspect.getDefinition().getAttributes())
             .setConfigConditions(configConditions)
             .setUniversalFragment(ruleClassProvider.getUniversalFragment())
+            // TODO(katre): Populate the actual selected toolchains.
+            .setToolchainContext(
+                new ToolchainContext(aspect.getDefinition().getRequiredToolchains(), null))
             .build();
     if (ruleContext.hasErrors()) {
       return null;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 5989b62..170d323 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -167,7 +167,7 @@
   private final ErrorReporter reporter;
   private final ImmutableBiMap<String, Class<? extends TransitiveInfoProvider>>
       skylarkProviderRegistry;
-  private final ToolchainContext toolchainContext;
+  @Nullable private final ToolchainContext toolchainContext;
 
   private ActionOwner actionOwner;
 
@@ -182,7 +182,8 @@
       ImmutableMap<Label, ConfigMatchingProvider> configConditions,
       Class<? extends BuildConfiguration.Fragment> universalFragment,
       String ruleClassNameForLogging,
-      ImmutableMap<String, Attribute> aspectAttributes) {
+      ImmutableMap<String, Attribute> aspectAttributes,
+      @Nullable ToolchainContext toolchainContext) {
     super(builder.env, builder.rule, builder.configuration, builder.prerequisiteMap.get(null),
         builder.visibility);
     this.rule = builder.rule;
@@ -198,8 +199,7 @@
     this.skylarkProviderRegistry = builder.skylarkProviderRegistry;
     this.hostConfiguration = builder.hostConfiguration;
     reporter = builder.reporter;
-    // TODO(katre): Populate the actual selected toolchains.
-    this.toolchainContext = new ToolchainContext(null);
+    this.toolchainContext = toolchainContext;
   }
 
   private ImmutableSet<String> getEnabledFeatures() {
@@ -1124,6 +1124,7 @@
     }
   }
 
+  @Nullable
   public ToolchainContext getToolchainContext() {
     return toolchainContext;
   }
@@ -1497,6 +1498,7 @@
     private ImmutableMap<String, Attribute> aspectAttributes;
     private ImmutableBiMap<String, Class<? extends TransitiveInfoProvider>> skylarkProviderRegistry;
     private ImmutableList<AspectDescriptor> aspectDescriptors;
+    private ToolchainContext toolchainContext;
 
     Builder(
         AnalysisEnvironment env,
@@ -1533,7 +1535,8 @@
           configConditions,
           universalFragment,
           getRuleClassNameForLogging(),
-          aspectAttributes != null ? aspectAttributes : ImmutableMap.<String, Attribute>of());
+          aspectAttributes != null ? aspectAttributes : ImmutableMap.<String, Attribute>of(),
+          toolchainContext);
     }
 
     private void validateAttributes(AttributeMap attributes) {
@@ -1593,6 +1596,12 @@
       return this;
     }
 
+    /** Sets the {@link ToolchainContext} used to access toolchains used by this rule. */
+    Builder setToolchainContext(ToolchainContext toolchainContext) {
+      this.toolchainContext = toolchainContext;
+      return this;
+    }
+
     private boolean validateFilesetEntry(FilesetEntry filesetEntry, ConfiguredTarget src) {
       if (src.getProvider(FilesetProvider.class) != null) {
         return true;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
index c4c9a9f..fc903dc 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.analysis;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
 import com.google.devtools.build.lib.packages.ClassObjectConstructor;
@@ -23,15 +24,23 @@
 
 /** Contains toolchain-related information needed for a {@link RuleContext}. */
 public class ToolchainContext {
+  private final ImmutableList<ClassObjectConstructor.Key> requiredToolchains;
   private final ImmutableMap<ClassObjectConstructor.Key, ToolchainInfo> toolchains;
 
-  public ToolchainContext(@Nullable Map<ClassObjectConstructor.Key, ToolchainInfo> toolchains) {
+  public ToolchainContext(
+      ImmutableList<ClassObjectConstructor.Key> requiredToolchains,
+      @Nullable Map<ClassObjectConstructor.Key, ToolchainInfo> toolchains) {
+    this.requiredToolchains = requiredToolchains;
     this.toolchains =
         toolchains == null
             ? ImmutableMap.<ClassObjectConstructor.Key, ToolchainInfo>of()
             : ImmutableMap.copyOf(toolchains);
   }
 
+  public ImmutableList<ClassObjectConstructor.Key> getRequiredToolchains() {
+    return requiredToolchains;
+  }
+
   public SkylarkDict<ClassObjectConstructor.Key, ToolchainInfo> collectToolchains() {
     return SkylarkDict.<ClassObjectConstructor.Key, ToolchainInfo>copyOf(null, toolchains);
   }