Introduce ArrayHelper.setAt() to use with EnumMap.

This makes sure the out of bounds index access is encapsulated so that
it can be super-sourced for WASM.

J2CL uses the GWT emul sources, and the same sources also transpile to
WASM (unless the entire implementation must be different using
super-wasm sources, which is generally not true for collections
classes). For these classes, array elements should not be read or
assigned out of bounds, which will result in a WASM exception (for
WASM-GC arrays). ArrayHelper will have a super-wasm implementation,
which will resize the backing array if needed before proceeding.

Like the original EnumMap helper method, this returns the original value
at the index (or else null), which can be done efficiently in GWT
without bounds checks.

PiperOrigin-RevId: 378638984
Change-Id: Ia19caef0576f8064a23b7cc73b20eea445e18b60
diff --git a/user/super/com/google/gwt/emul/java/util/EnumMap.java b/user/super/com/google/gwt/emul/java/util/EnumMap.java
index 0dbd223..00ef1b9 100644
--- a/user/super/com/google/gwt/emul/java/util/EnumMap.java
+++ b/user/super/com/google/gwt/emul/java/util/EnumMap.java
@@ -110,7 +110,7 @@
 
     @Override
     public V setValue(V value) {
-      return set(key.ordinal(), value);
+      return ArrayHelper.setAt(values, key.ordinal(), value);
     }
   }
 
@@ -175,12 +175,12 @@
   @Override
   public V put(K key, V value) {
     keySet.add(key);
-    return set(key.ordinal(), value);
+    return ArrayHelper.setAt(values, key.ordinal(), value);
   }
 
   @Override
   public V remove(Object key) {
-    return keySet.remove(key) ? set(asOrdinal(key), null) : null;
+    return keySet.remove(key) ? ArrayHelper.setAt(values, asOrdinal(key), null) : null;
   }
 
   @Override
@@ -212,10 +212,4 @@
     keySet = m.keySet.clone();
     values = ArrayHelper.clone(m.values);
   }
-
-  private V set(int ordinal, V value) {
-    V was = values[ordinal];
-    values[ordinal] = value;
-    return was;
-  }
 }
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
index c474c9a..70be843 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
@@ -64,6 +64,18 @@
     asNativeArray(array).push(o);
   }
 
+  /**
+   * Sets an element of an array.
+   *
+   * <p>In GWT, the naive approach of checking or setting an element which may be out of bounds is
+   * optimal. This method always returns the original value, or null for out of bounds.
+   */
+  public static <T> T setAt(T[] array, int index, T value) {
+    T originalValue = array[index];
+    array[index] = value;
+    return originalValue;
+  }
+
   public static void removeFrom(Object[] array, int index, int deleteCount) {
     asNativeArray(array).splice(index, deleteCount);
   }