Create a real ToolchainContext for TransitionsOutputFormatterCallback.

Part of work on execution transitions, #7935.

Closes #8121.

PiperOrigin-RevId: 245228413
diff --git a/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetAccessor.java b/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetAccessor.java
index 37f12f9..2063b57 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetAccessor.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetAccessor.java
@@ -19,9 +19,12 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.ToolchainContext;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -35,11 +38,15 @@
 import com.google.devtools.build.lib.query2.engine.QueryExpression;
 import com.google.devtools.build.lib.query2.engine.QueryVisibility;
 import com.google.devtools.build.lib.rules.AliasConfiguredTarget;
+import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction;
 import com.google.devtools.build.lib.skyframe.PackageValue;
+import com.google.devtools.build.lib.skyframe.UnloadedToolchainContext;
 import com.google.devtools.build.skyframe.WalkableGraph;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import javax.annotation.Nullable;
 
 /**
  * A {@link TargetAccessor} for {@link ConfiguredTarget} objects.
@@ -181,4 +188,40 @@
     }
     return target;
   }
+
+  @Nullable
+  public ToolchainContext getToolchainContext(Target target, BuildConfiguration config) {
+    return getToolchainContext(target, config, walkableGraph);
+  }
+
+  @Nullable
+  public static ToolchainContext getToolchainContext(
+      Target target, BuildConfiguration config, WalkableGraph walkableGraph) {
+    if (!(target instanceof Rule)) {
+      return null;
+    }
+
+    Rule rule = ((Rule) target);
+    if (!rule.getRuleClassObject().supportsPlatforms()) {
+      return null;
+    }
+
+    ImmutableSet<Label> requiredToolchains = rule.getRuleClassObject().getRequiredToolchains();
+
+    // Collect local (target, rule) constraints for filtering out execution platforms.
+    ImmutableSet<Label> execConstraintLabels =
+        ConfiguredTargetFunction.getExecutionPlatformConstraints(rule);
+    try {
+      return (UnloadedToolchainContext)
+          walkableGraph.getValue(
+              UnloadedToolchainContext.key()
+                  .configurationKey(BuildConfigurationValue.key(config))
+                  .requiredToolchainTypeLabels(requiredToolchains)
+                  .execConstraintLabels(execConstraintLabels)
+                  .build());
+    } catch (InterruptedException e) {
+      throw new IllegalStateException(
+          "Thread interrupted in the middle of getting a ToolchainContext.", e);
+    }
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
index 848a1cf..1365d72 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
@@ -23,6 +23,7 @@
 import com.google.devtools.build.lib.analysis.DependencyResolver.DependencyKind;
 import com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
+import com.google.devtools.build.lib.analysis.ToolchainContext;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.BuildOptions.OptionsDiff;
@@ -117,6 +118,9 @@
       OrderedSetMultimap<DependencyKind, Dependency> deps;
       ImmutableMap<Label, ConfigMatchingProvider> configConditions =
           ((RuleConfiguredTarget) configuredTarget).getConfigConditions();
+
+      // Get a ToolchainContext to use for dependency resolution.
+      ToolchainContext toolchainContext = accessor.getToolchainContext(target, config);
       try {
         // We don't actually use fromOptions in our implementation of
         // DependencyResolver but passing to avoid passing a null and since we have the information
@@ -128,7 +132,9 @@
                     hostConfiguration,
                     /*aspect=*/ null,
                     configConditions,
-                    /*toolchainLabels=*/ ImmutableSet.of(),
+                    toolchainContext == null
+                        ? ImmutableSet.of()
+                        : toolchainContext.resolvedToolchainLabels(),
                     trimmingTransitionFactory);
       } catch (EvalException | InconsistentAspectOrderException e) {
         throw new InterruptedException(e.getMessage());
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index 0c3961e..9e24416 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -459,7 +459,7 @@
    * Returns the target-specific execution platform constraints, based on the rule definition and
    * any constraints added by the target.
    */
-  private static ImmutableSet<Label> getExecutionPlatformConstraints(Rule rule) {
+  public static ImmutableSet<Label> getExecutionPlatformConstraints(Rule rule) {
     NonconfigurableAttributeMapper mapper = NonconfigurableAttributeMapper.of(rule);
     ImmutableSet.Builder<Label> execConstraintLabels = new ImmutableSet.Builder<>();