Update RegisteredToolchainsFunction and ToolchainUtil to check values for errors even if not all values are present.

Fixes #3751.

Change-Id: I92fd7527384800beca80b9daac58f3a7760268b2
PiperOrigin-RevId: 169907526
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
index 13e055b..84c0e25 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
@@ -82,6 +82,32 @@
     }
   }
 
+  /**
+   * Returns the {@link PlatformInfo} provider from the {@link ConfiguredTarget} in the {@link
+   * ValueOrException}, or {@code null} if the {@link ConfiguredTarget} is not present. If the
+   * {@link ConfiguredTarget} does not have a {@link PlatformInfo} provider, a {@link
+   * InvalidPlatformException} is thrown, wrapped in a {@link ToolchainContextException}.
+   */
+  @Nullable
+  private static PlatformInfo findPlatformInfo(
+      ValueOrException<ConfiguredValueCreationException> valueOrException, String platformType)
+      throws ConfiguredValueCreationException, ToolchainContextException {
+
+    ConfiguredTargetValue ctv = (ConfiguredTargetValue) valueOrException.get();
+    if (ctv == null) {
+      return null;
+    }
+
+    ConfiguredTarget configuredTarget = ctv.getConfiguredTarget();
+    PlatformInfo platformInfo = PlatformProviderUtils.platform(configuredTarget);
+    if (platformInfo == null) {
+      throw new ToolchainContextException(
+          new InvalidPlatformException(platformType, configuredTarget));
+    }
+
+    return platformInfo;
+  }
+
   @Nullable
   private static PlatformDescriptors loadPlatformDescriptors(
       Environment env, BuildConfiguration configuration)
@@ -104,24 +130,15 @@
         env.getValuesOrThrow(
             ImmutableList.of(executionPlatformKey, targetPlatformKey),
             ConfiguredValueCreationException.class);
-    if (env.valuesMissing()) {
-      return null;
-    }
+    boolean valuesMissing = env.valuesMissing();
     try {
-      ConfiguredTarget executionPlatformTarget =
-          ((ConfiguredTargetValue) values.get(executionPlatformKey).get()).getConfiguredTarget();
-      ConfiguredTarget targetPlatformTarget =
-          ((ConfiguredTargetValue) values.get(targetPlatformKey).get()).getConfiguredTarget();
-      PlatformInfo execPlatform = PlatformProviderUtils.platform(executionPlatformTarget);
-      PlatformInfo targetPlatform = PlatformProviderUtils.platform(targetPlatformTarget);
+      PlatformInfo execPlatform =
+          findPlatformInfo(values.get(executionPlatformKey), "execution platform");
+      PlatformInfo targetPlatform =
+          findPlatformInfo(values.get(targetPlatformKey), "target platform");
 
-      if (execPlatform == null) {
-        throw new ToolchainContextException(
-            new InvalidPlatformException("execution platform", executionPlatformTarget));
-      }
-      if (targetPlatform == null) {
-        throw new ToolchainContextException(
-            new InvalidPlatformException("target platform", targetPlatformTarget));
+      if (valuesMissing) {
+        return null;
       }
 
       return PlatformDescriptors.create(execPlatform, targetPlatform);
@@ -166,9 +183,7 @@
                 ConfiguredValueCreationException.class,
                 InvalidToolchainLabelException.class,
                 EvalException.class);
-    if (env.valuesMissing()) {
-      return null;
-    }
+    boolean valuesMissing = false;
 
     // Load the toolchains.
     ImmutableBiMap.Builder<Label, Label> builder = new ImmutableBiMap.Builder<>();
@@ -182,8 +197,17 @@
       try {
         Label requiredToolchainType =
             ((ToolchainResolutionKey) entry.getKey().argument()).toolchainType();
-        Label toolchainLabel = ((ToolchainResolutionValue) entry.getValue().get()).toolchainLabel();
-        builder.put(requiredToolchainType, toolchainLabel);
+        ValueOrException4<
+                NoToolchainFoundException, ConfiguredValueCreationException,
+                InvalidToolchainLabelException, EvalException>
+            valueOrException = entry.getValue();
+        if (valueOrException.get() == null) {
+          valuesMissing = true;
+        } else {
+          Label toolchainLabel =
+              ((ToolchainResolutionValue) valueOrException.get()).toolchainLabel();
+          builder.put(requiredToolchainType, toolchainLabel);
+        }
       } catch (NoToolchainFoundException e) {
         // Save the missing type and continue looping to check for more.
         missingToolchains.add(e.missingToolchainType());
@@ -196,6 +220,10 @@
       }
     }
 
+    if (valuesMissing) {
+      return null;
+    }
+
     if (!missingToolchains.isEmpty()) {
       throw new ToolchainContextException(new UnresolvedToolchainsException(missingToolchains));
     }