Skyfunctions can now catch up to five exceptions.

This is a prerequisite to making some changes to PackageFunction that require handling another exception.

--
MOS_MIGRATED_REVID=112172100
diff --git a/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java b/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java
index 3d95e97..f457575 100644
--- a/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java
+++ b/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java
@@ -46,65 +46,108 @@
   }
 
   private <E1 extends Exception, E2 extends Exception, E3 extends Exception>
-  ValueOrException3<E1, E2, E3> getValueOrException(SkyKey depKey, Class<E1> exceptionClass1,
-      Class<E2> exceptionClass2, Class<E3> exceptionClass3) {
-    return ValueOrExceptionUtils.downconvert(getValueOrException(depKey, exceptionClass1,
-            exceptionClass2, exceptionClass3, BottomException.class), exceptionClass1,
-        exceptionClass2, exceptionClass3);
+      ValueOrException3<E1, E2, E3> getValueOrException(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3) {
+    return ValueOrExceptionUtils.downconvert(
+        getValueOrException(depKey, exceptionClass1, exceptionClass2, exceptionClass3,
+            BottomException.class),
+        exceptionClass1,
+        exceptionClass2,
+        exceptionClass3);
+  }
+
+  private <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
+      ValueOrException4<E1, E2, E3, E4> getValueOrException(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4) {
+    return ValueOrExceptionUtils.downconvert(
+        getValueOrException(depKey, exceptionClass1, exceptionClass2, exceptionClass3,
+            exceptionClass4, BottomException.class),
+        exceptionClass1,
+        exceptionClass2,
+        exceptionClass3,
+        exceptionClass4);
   }
 
   private <E1 extends Exception, E2 extends Exception, E3 extends Exception,
-      E4 extends Exception> ValueOrException4<E1, E2, E3, E4> getValueOrException(SkyKey depKey,
-      Class<E1> exceptionClass1, Class<E2> exceptionClass2, Class<E3> exceptionClass3,
-      Class<E4> exceptionClass4) {
-    return getValueOrExceptions(ImmutableSet.of(depKey), exceptionClass1, exceptionClass2,
-        exceptionClass3, exceptionClass4).get(depKey);
+           E4 extends Exception, E5 extends Exception>
+      ValueOrException5<E1, E2, E3, E4, E5> getValueOrException(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4,
+          Class<E5> exceptionClass5) {
+    return getValueOrExceptions(
+        ImmutableSet.of(depKey),
+        exceptionClass1,
+        exceptionClass2,
+        exceptionClass3,
+        exceptionClass4,
+        exceptionClass5).get(depKey);
   }
 
   private <E1 extends Exception, E2 extends Exception, E3 extends Exception,
-      E4 extends Exception> Map<SkyKey, ValueOrException4<E1, E2, E3, E4>> getValueOrExceptions(
-      Set<SkyKey> depKeys, Class<E1> exceptionClass1, Class<E2> exceptionClass2,
-      Class<E3> exceptionClass3, Class<E4> exceptionClass4) {
+           E4 extends Exception, E5 extends Exception>
+      Map<SkyKey, ValueOrException5<E1, E2, E3, E4, E5>> getValueOrExceptions(
+          Set<SkyKey> depKeys,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4,
+          Class<E5> exceptionClass5) {
     SkyFunctionException.validateExceptionType(exceptionClass1);
     SkyFunctionException.validateExceptionType(exceptionClass2);
     SkyFunctionException.validateExceptionType(exceptionClass3);
     SkyFunctionException.validateExceptionType(exceptionClass4);
+    SkyFunctionException.validateExceptionType(exceptionClass5);
     Map<SkyKey, ValueOrUntypedException> valueOrExceptions =
         getValueOrUntypedExceptions(depKeys);
-    ImmutableMap.Builder<SkyKey, ValueOrException4<E1, E2, E3, E4>> builder =
+    ImmutableMap.Builder<SkyKey, ValueOrException5<E1, E2, E3, E4, E5>> builder =
         ImmutableMap.builder();
     for (SkyKey depKey : depKeys) {
       ValueOrUntypedException voe = valueOrExceptions.get(depKey);
       SkyValue value = voe.getValue();
       if (value != null) {
-        builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofValue(value));
+        builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofValue(value));
         continue;
       }
       Exception e = voe.getException();
       if (e != null) {
         if (exceptionClass1.isInstance(e)) {
-          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofExn1(
+          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofExn1(
               exceptionClass1.cast(e)));
           continue;
         }
         if (exceptionClass2.isInstance(e)) {
-          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofExn2(
+          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofExn2(
               exceptionClass2.cast(e)));
           continue;
         }
         if (exceptionClass3.isInstance(e)) {
-          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofExn3(
+          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofExn3(
               exceptionClass3.cast(e)));
           continue;
         }
         if (exceptionClass4.isInstance(e)) {
-          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofExn4(
+          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofExn4(
               exceptionClass4.cast(e)));
           continue;
         }
+        if (exceptionClass5.isInstance(e)) {
+          builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofExn5(
+              exceptionClass5.cast(e)));
+          continue;
+        }
       }
       valuesMissing = true;
-      builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4>ofNullValue());
+      builder.put(depKey, ValueOrExceptionUtils.<E1, E2, E3, E4, E5>ofNullValue());
     }
     return builder.build();
   }
@@ -132,29 +175,61 @@
 
   @Override
   @Nullable
-  public <E1 extends Exception, E2 extends Exception> SkyValue getValueOrThrow(SkyKey depKey,
-      Class<E1> exceptionClass1, Class<E2> exceptionClass2) throws E1, E2 {
+  public <E1 extends Exception, E2 extends Exception> SkyValue getValueOrThrow(
+      SkyKey depKey,
+      Class<E1> exceptionClass1,
+      Class<E2> exceptionClass2) throws E1, E2 {
     return getValueOrException(depKey, exceptionClass1, exceptionClass2).get();
   }
 
   @Override
   @Nullable
-  public <E1 extends Exception, E2 extends Exception,
-      E3 extends Exception> SkyValue getValueOrThrow(SkyKey depKey, Class<E1> exceptionClass1,
-      Class<E2> exceptionClass2, Class<E3> exceptionClass3) throws E1, E2, E3 {
+  public <E1 extends Exception, E2 extends Exception, E3 extends Exception>
+      SkyValue getValueOrThrow(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3) throws E1, E2, E3 {
     return getValueOrException(depKey, exceptionClass1, exceptionClass2, exceptionClass3).get();
   }
 
   @Override
-  public <E1 extends Exception, E2 extends Exception, E3 extends Exception,
-      E4 extends Exception> SkyValue getValueOrThrow(SkyKey depKey, Class<E1> exceptionClass1,
-      Class<E2> exceptionClass2, Class<E3> exceptionClass3, Class<E4> exceptionClass4) throws E1,
-      E2, E3, E4 {
-    return getValueOrException(depKey, exceptionClass1, exceptionClass2, exceptionClass3,
+  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
+      SkyValue getValueOrThrow(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4) throws E1, E2, E3, E4 {
+    return getValueOrException(
+        depKey,
+        exceptionClass1,
+        exceptionClass2,
+        exceptionClass3,
         exceptionClass4).get();
   }
 
   @Override
+  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception,
+          E5 extends Exception>
+      SkyValue getValueOrThrow(
+          SkyKey depKey,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4,
+          Class<E5> exceptionClass5
+  ) throws E1, E2, E3, E4, E5 {
+    return getValueOrException(
+        depKey,
+        exceptionClass1,
+        exceptionClass2,
+        exceptionClass3,
+        exceptionClass4,
+        exceptionClass5).get();
+  }
+
+  @Override
   public Map<SkyKey, SkyValue> getValues(Iterable<SkyKey> depKeys) {
     return Maps.transformValues(getValuesOrThrow(depKeys, BottomException.class),
         GET_VALUE_FROM_VOE);
@@ -163,36 +238,63 @@
   @Override
   public <E extends Exception> Map<SkyKey, ValueOrException<E>> getValuesOrThrow(
       Iterable<SkyKey> depKeys, Class<E> exceptionClass) {
-    return Maps.transformValues(getValuesOrThrow(depKeys, exceptionClass, BottomException.class),
+    return Maps.transformValues(
+        getValuesOrThrow(depKeys, exceptionClass, BottomException.class),
         makeSafeDowncastToVOEFunction(exceptionClass));
   }
 
   @Override
-  public <E1 extends Exception,
-      E2 extends Exception> Map<SkyKey, ValueOrException2<E1, E2>> getValuesOrThrow(
-      Iterable<SkyKey> depKeys, Class<E1> exceptionClass1, Class<E2> exceptionClass2) {
-    return Maps.transformValues(getValuesOrThrow(depKeys, exceptionClass1, exceptionClass2,
-        BottomException.class), makeSafeDowncastToVOE2Function(exceptionClass1,
-        exceptionClass2));
+  public <E1 extends Exception, E2 extends Exception>
+      Map<SkyKey, ValueOrException2<E1, E2>> getValuesOrThrow(
+          Iterable<SkyKey> depKeys,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2) {
+    return Maps.transformValues(
+        getValuesOrThrow(depKeys, exceptionClass1, exceptionClass2, BottomException.class),
+        makeSafeDowncastToVOE2Function(exceptionClass1, exceptionClass2));
   }
 
   @Override
-  public <E1 extends Exception, E2 extends Exception, E3 extends Exception> Map<SkyKey,
-      ValueOrException3<E1, E2, E3>> getValuesOrThrow(Iterable<SkyKey> depKeys,
-      Class<E1> exceptionClass1, Class<E2> exceptionClass2, Class<E3> exceptionClass3) {
-    return Maps.transformValues(getValuesOrThrow(depKeys, exceptionClass1, exceptionClass2,
-        exceptionClass3, BottomException.class), makeSafeDowncastToVOE3Function(exceptionClass1,
-        exceptionClass2, exceptionClass3));
+  public <E1 extends Exception, E2 extends Exception, E3 extends Exception>
+      Map<SkyKey, ValueOrException3<E1, E2, E3>> getValuesOrThrow(
+          Iterable<SkyKey> depKeys,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3) {
+    return Maps.transformValues(
+        getValuesOrThrow(depKeys, exceptionClass1, exceptionClass2, exceptionClass3,
+            BottomException.class),
+        makeSafeDowncastToVOE3Function(exceptionClass1, exceptionClass2, exceptionClass3));
+  }
+
+  @Override
+  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
+      Map<SkyKey, ValueOrException4<E1, E2, E3, E4>> getValuesOrThrow(
+          Iterable<SkyKey> depKeys,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4) {
+    return Maps.transformValues(
+        getValuesOrThrow(depKeys, exceptionClass1, exceptionClass2, exceptionClass3,
+            exceptionClass4, BottomException.class),
+        makeSafeDowncastToVOE4Function(exceptionClass1, exceptionClass2, exceptionClass3,
+            exceptionClass4));
   }
 
   @Override
   public <E1 extends Exception, E2 extends Exception, E3 extends Exception,
-      E4 extends Exception> Map<SkyKey, ValueOrException4<E1, E2, E3, E4>> getValuesOrThrow(
-      Iterable<SkyKey> depKeys, Class<E1> exceptionClass1, Class<E2> exceptionClass2,
-      Class<E3> exceptionClass3, Class<E4> exceptionClass4) {
+          E4 extends Exception, E5 extends Exception>
+      Map<SkyKey, ValueOrException5<E1, E2, E3, E4, E5>> getValuesOrThrow(
+          Iterable<SkyKey> depKeys,
+          Class<E1> exceptionClass1,
+          Class<E2> exceptionClass2,
+          Class<E3> exceptionClass3,
+          Class<E4> exceptionClass4,
+          Class<E5> exceptionClass5) {
     Set<SkyKey> keys = ImmutableSet.copyOf(depKeys);
-    Map<SkyKey, ValueOrException4<E1, E2, E3, E4>> result = getValueOrExceptions(keys,
-        exceptionClass1, exceptionClass2, exceptionClass3, exceptionClass4);
+    Map<SkyKey, ValueOrException5<E1, E2, E3, E4, E5>> result = getValueOrExceptions(keys,
+        exceptionClass1, exceptionClass2, exceptionClass3, exceptionClass4, exceptionClass5);
     return Collections.unmodifiableMap(result);
   }
 
@@ -211,8 +313,8 @@
       };
 
   private static <E extends Exception>
-  Function<ValueOrException2<E, BottomException>, ValueOrException<E>>
-  makeSafeDowncastToVOEFunction(final Class<E> exceptionClass) {
+      Function<ValueOrException2<E, BottomException>, ValueOrException<E>>
+          makeSafeDowncastToVOEFunction(final Class<E> exceptionClass) {
     return new Function<ValueOrException2<E, BottomException>, ValueOrException<E>>() {
       @Override
       public ValueOrException<E> apply(ValueOrException2<E, BottomException> voe) {
@@ -222,11 +324,11 @@
   }
 
   private static <E1 extends Exception, E2 extends Exception>
-  Function<ValueOrException3<E1, E2, BottomException>, ValueOrException2<E1, E2>>
-  makeSafeDowncastToVOE2Function(final Class<E1> exceptionClass1,
-      final Class<E2> exceptionClass2) {
-    return new Function<ValueOrException3<E1, E2, BottomException>,
-        ValueOrException2<E1, E2>>() {
+      Function<ValueOrException3<E1, E2, BottomException>, ValueOrException2<E1, E2>>
+      makeSafeDowncastToVOE2Function(
+          final Class<E1> exceptionClass1,
+          final Class<E2> exceptionClass2) {
+    return new Function<ValueOrException3<E1, E2, BottomException>, ValueOrException2<E1, E2>>() {
       @Override
       public ValueOrException2<E1, E2> apply(ValueOrException3<E1, E2, BottomException> voe) {
         return ValueOrExceptionUtils.downconvert(voe, exceptionClass1, exceptionClass2);
@@ -235,16 +337,38 @@
   }
 
   private static <E1 extends Exception, E2 extends Exception, E3 extends Exception>
-  Function<ValueOrException4<E1, E2, E3, BottomException>, ValueOrException3<E1, E2, E3>>
-  makeSafeDowncastToVOE3Function(final Class<E1> exceptionClass1,
-      final Class<E2> exceptionClass2, final Class<E3> exceptionClass3) {
+      Function<ValueOrException4<E1, E2, E3, BottomException>, ValueOrException3<E1, E2, E3>>
+      makeSafeDowncastToVOE3Function(
+          final Class<E1> exceptionClass1,
+          final Class<E2> exceptionClass2,
+          final Class<E3> exceptionClass3) {
     return new Function<ValueOrException4<E1, E2, E3, BottomException>,
         ValueOrException3<E1, E2, E3>>() {
       @Override
-      public ValueOrException3<E1, E2, E3> apply(ValueOrException4<E1, E2, E3,
-          BottomException> voe) {
-        return ValueOrExceptionUtils.downconvert(voe, exceptionClass1, exceptionClass2,
-            exceptionClass3);
+      public ValueOrException3<E1, E2, E3> apply(
+          ValueOrException4<E1, E2, E3, BottomException> voe) {
+        return ValueOrExceptionUtils.downconvert(
+            voe, exceptionClass1, exceptionClass2, exceptionClass3);
+      }
+    };
+  }
+
+  private static <E1 extends Exception, E2 extends Exception, E3 extends Exception,
+                  E4 extends Exception>
+      Function<ValueOrException5<E1, E2, E3, E4, BottomException>,
+          ValueOrException4<E1, E2, E3, E4>>
+      makeSafeDowncastToVOE4Function(
+          final Class<E1> exceptionClass1,
+          final Class<E2> exceptionClass2,
+          final Class<E3> exceptionClass3,
+          final Class<E4> exceptionClass4) {
+    return new Function<ValueOrException5<E1, E2, E3, E4, BottomException>,
+                        ValueOrException4<E1, E2, E3, E4>>() {
+      @Override
+      public ValueOrException4<E1, E2, E3, E4> apply(
+          ValueOrException5<E1, E2, E3, E4, BottomException> voe) {
+        return ValueOrExceptionUtils.downconvert(
+            voe, exceptionClass1, exceptionClass2, exceptionClass3, exceptionClass4);
       }
     };
   }