Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLUnmodifiedType;
import graphql.util.LinkedHashMapFactory;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

Expand Down Expand Up @@ -100,7 +101,7 @@ public static CompilerResult compileToDocument(@NonNull GraphQLSchema schema,
@Nullable String operationName,
@NonNull List<ExecutableNormalizedField> topLevelFields,
@Nullable VariablePredicate variablePredicate) {
return compileToDocument(schema, operationKind, operationName, topLevelFields, Map.of(), variablePredicate);
return compileToDocument(schema, operationKind, operationName, topLevelFields, LinkedHashMapFactory.of(), variablePredicate);
}

/**
Expand Down Expand Up @@ -151,7 +152,7 @@ public static CompilerResult compileToDocumentWithDeferSupport(@NonNull GraphQLS
@NonNull List<ExecutableNormalizedField> topLevelFields,
@Nullable VariablePredicate variablePredicate
) {
return compileToDocumentWithDeferSupport(schema, operationKind, operationName, topLevelFields, Map.of(), variablePredicate);
return compileToDocumentWithDeferSupport(schema, operationKind, operationName, topLevelFields, LinkedHashMapFactory.of(), variablePredicate);
}

/**
Expand Down
344 changes: 344 additions & 0 deletions src/main/java/graphql/util/LinkedHashMapFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
package graphql.util;

import graphql.Internal;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* Factory class for creating LinkedHashMap instances with insertion order preservation.
* Use this instead of Map.of() to ensure consistent serialization order.
* <p>
* This class provides static factory methods similar to Map.of() but returns mutable LinkedHashMap
* instances that preserve insertion order, which is important for consistent serialization.
*/
@Internal
public final class LinkedHashMapFactory {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is verbose. Originally I was only going to have one method (the last one) with variable length parameters, but saw the original Map.java had all of these extra methods for performance.

I don't think the difference is massive for our purposes, but I thought I'd follow the original


private LinkedHashMapFactory() {
// utility class
}

/**
* Returns an empty LinkedHashMap.
*
* @param <K> the key type
* @param <V> the value type
* @return an empty LinkedHashMap
*/
public static <K, V> Map<K, V> of() {
return new LinkedHashMap<>();
}

/**
* Returns a LinkedHashMap containing a single mapping.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the mapping's key
* @param v1 the mapping's value
* @return a LinkedHashMap containing the specified mapping
*/
public static <K, V> Map<K, V> of(K k1, V v1) {
Map<K, V> map = new LinkedHashMap<>(1);
map.put(k1, v1);
return map;
}

/**
* Returns a LinkedHashMap containing two mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
Map<K, V> map = new LinkedHashMap<>(2);
map.put(k1, v1);
map.put(k2, v2);
return map;
}

/**
* Returns a LinkedHashMap containing three mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
Map<K, V> map = new LinkedHashMap<>(3);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
return map;
}

/**
* Returns a LinkedHashMap containing four mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
Map<K, V> map = new LinkedHashMap<>(4);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
return map;
}

/**
* Returns a LinkedHashMap containing five mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
Map<K, V> map = new LinkedHashMap<>(5);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
return map;
}

/**
* Returns a LinkedHashMap containing six mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @param k6 the sixth mapping's key
* @param v6 the sixth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) {
Map<K, V> map = new LinkedHashMap<>(6);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
map.put(k6, v6);
return map;
}

/**
* Returns a LinkedHashMap containing seven mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @param k6 the sixth mapping's key
* @param v6 the sixth mapping's value
* @param k7 the seventh mapping's key
* @param v7 the seventh mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) {
Map<K, V> map = new LinkedHashMap<>(7);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
map.put(k6, v6);
map.put(k7, v7);
return map;
}

/**
* Returns a LinkedHashMap containing eight mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @param k6 the sixth mapping's key
* @param v6 the sixth mapping's value
* @param k7 the seventh mapping's key
* @param v7 the seventh mapping's value
* @param k8 the eighth mapping's key
* @param v8 the eighth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) {
Map<K, V> map = new LinkedHashMap<>(8);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
map.put(k6, v6);
map.put(k7, v7);
map.put(k8, v8);
return map;
}

/**
* Returns a LinkedHashMap containing nine mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @param k6 the sixth mapping's key
* @param v6 the sixth mapping's value
* @param k7 the seventh mapping's key
* @param v7 the seventh mapping's value
* @param k8 the eighth mapping's key
* @param v8 the eighth mapping's value
* @param k9 the ninth mapping's key
* @param v9 the ninth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
Map<K, V> map = new LinkedHashMap<>(9);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
map.put(k6, v6);
map.put(k7, v7);
map.put(k8, v8);
map.put(k9, v9);
return map;
}

/**
* Returns a LinkedHashMap containing ten mappings.
*
* @param <K> the key type
* @param <V> the value type
* @param k1 the first mapping's key
* @param v1 the first mapping's value
* @param k2 the second mapping's key
* @param v2 the second mapping's value
* @param k3 the third mapping's key
* @param v3 the third mapping's value
* @param k4 the fourth mapping's key
* @param v4 the fourth mapping's value
* @param k5 the fifth mapping's key
* @param v5 the fifth mapping's value
* @param k6 the sixth mapping's key
* @param v6 the sixth mapping's value
* @param k7 the seventh mapping's key
* @param v7 the seventh mapping's value
* @param k8 the eighth mapping's key
* @param v8 the eighth mapping's value
* @param k9 the ninth mapping's key
* @param v9 the ninth mapping's value
* @param k10 the tenth mapping's key
* @param v10 the tenth mapping's value
* @return a LinkedHashMap containing the specified mappings
*/
public static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
Map<K, V> map = new LinkedHashMap<>(10);
map.put(k1, v1);
map.put(k2, v2);
map.put(k3, v3);
map.put(k4, v4);
map.put(k5, v5);
map.put(k6, v6);
map.put(k7, v7);
map.put(k8, v8);
map.put(k9, v9);
map.put(k10, v10);
return map;
}

/**
* Returns a LinkedHashMap containing mappings derived from the given arguments.
* <p>
* This method is provided for cases where more than 10 key-value pairs are needed.
* It accepts alternating keys and values.
*
* @param <K> the key type
* @param <V> the value type
* @param keyValues alternating keys and values
* @return a LinkedHashMap containing the specified mappings
* @throws IllegalArgumentException if an odd number of arguments is provided
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> ofEntries(Object... keyValues) {
if (keyValues.length % 2 != 0) {
throw new IllegalArgumentException("keyValues must contain an even number of arguments (key-value pairs)");
}

Map<K, V> map = new LinkedHashMap<>(keyValues.length / 2);
for (int i = 0; i < keyValues.length; i += 2) {
K key = (K) keyValues[i];
V value = (V) keyValues[i + 1];
map.put(key, value);
}
return map;
}
}
Loading