11package graphql .execution ;
22
33
4+ import graphql .Assert ;
45import graphql .Internal ;
56import graphql .language .Argument ;
67import graphql .language .ArrayValue ;
1718import graphql .schema .GraphQLEnumType ;
1819import graphql .schema .GraphQLInputObjectField ;
1920import graphql .schema .GraphQLInputObjectType ;
21+ import graphql .schema .GraphQLInputType ;
2022import graphql .schema .GraphQLList ;
2123import graphql .schema .GraphQLScalarType ;
2224import graphql .schema .GraphQLSchema ;
@@ -48,6 +50,7 @@ public class ValuesResolver {
4850 * @param schema the schema
4951 * @param variableDefinitions the variable definitions
5052 * @param variableValues the supplied variables
53+ *
5154 * @return coerced variable values as a map
5255 */
5356 public Map <String , Object > coerceVariableValues (GraphQLSchema schema , List <VariableDefinition > variableDefinitions , Map <String , Object > variableValues ) {
@@ -57,19 +60,26 @@ public Map<String, Object> coerceVariableValues(GraphQLSchema schema, List<Varia
5760 String variableName = variableDefinition .getName ();
5861 List <Object > nameStack = new ArrayList <>();
5962 GraphQLType variableType = TypeFromAST .getTypeFromAST (schema , variableDefinition .getType ());
60-
61- if (!variableValues .containsKey (variableName )) {
62- Value defaultValue = variableDefinition .getDefaultValue ();
63- if (defaultValue != null ) {
64- Object coercedValue = coerceValueAst (fieldVisibility , variableType , defaultValue , null );
63+ Assert .assertTrue (variableType instanceof GraphQLInputType );
64+ // can be NullValue
65+ Value defaultValue = variableDefinition .getDefaultValue ();
66+ boolean hasValue = variableValues .containsKey (variableName );
67+ Object value = variableValues .get (variableName );
68+ if (!hasValue && defaultValue != null ) {
69+ Object coercedDefaultValue = coerceValueAst (fieldVisibility , variableType , defaultValue , null );
70+ coercedValues .put (variableName , coercedDefaultValue );
71+ } else if (isNonNull (variableType ) && (!hasValue || value == null )) {
72+ throw new NonNullableValueCoercedAsNullException (variableDefinition , variableType );
73+ } else if (hasValue ) {
74+ if (value == null ) {
75+ coercedValues .put (variableName , null );
76+ } else {
77+ Object coercedValue = coerceValue (fieldVisibility , variableDefinition , variableDefinition .getName (), variableType , value , nameStack );
6578 coercedValues .put (variableName , coercedValue );
66- } else if (isNonNull (variableType )) {
67- throw new NonNullableValueCoercedAsNullException (variableDefinition , variableType );
6879 }
6980 } else {
70- Object value = variableValues .get (variableName );
71- Object coercedValue = coerceValue (fieldVisibility , variableDefinition , variableDefinition .getName (), variableType , value , nameStack );
72- coercedValues .put (variableName , coercedValue );
81+ // hasValue = false && no defaultValue for a nullable type
82+ // meaning no value was provided for variableName
7383 }
7484 }
7585
@@ -85,42 +95,51 @@ public Map<String, Object> getArgumentValues(GraphQLCodeRegistry codeRegistry, L
8595 return getArgumentValuesImpl (codeRegistry , argumentTypes , arguments , variables );
8696 }
8797
88- private Map <String , Object > getArgumentValuesImpl (GraphQLCodeRegistry codeRegistry , List <GraphQLArgument > argumentTypes , List <Argument > arguments , Map <String , Object > variables ) {
98+ private Map <String , Object > getArgumentValuesImpl (GraphQLCodeRegistry codeRegistry , List <GraphQLArgument > argumentTypes , List <Argument > arguments ,
99+ Map <String , Object > coercedVariableValues ) {
89100 if (argumentTypes .isEmpty ()) {
90101 return Collections .emptyMap ();
91102 }
92103
93- Map <String , Object > result = new LinkedHashMap <>();
104+ Map <String , Object > coercedValues = new LinkedHashMap <>();
94105 Map <String , Argument > argumentMap = argumentMap (arguments );
95- for (GraphQLArgument fieldArgument : argumentTypes ) {
96- String argName = fieldArgument .getName ();
97- Argument argument = argumentMap .get (argName );
98- Object value = null ;
99- if (argument != null ) {
100- value = coerceValueAst (codeRegistry .getFieldVisibility (), fieldArgument .getType (), argument .getValue (), variables );
101- }
102- if (value == null
103- && !(argument != null && argument .getValue () instanceof NullValue )
104- && !(argument != null && argument .getValue () instanceof VariableReference && variables .containsKey (((VariableReference ) argument .getValue ()).getName ()))
105- ) {
106- value = fieldArgument .getDefaultValue ();
106+ for (GraphQLArgument argumentDefinition : argumentTypes ) {
107+ GraphQLInputType argumentType = argumentDefinition .getType ();
108+ String argumentName = argumentDefinition .getName ();
109+ Argument argument = argumentMap .get (argumentName );
110+ Object defaultValue = argumentDefinition .getDefaultValue ();
111+ boolean hasValue = argument != null ;
112+ Object value ;
113+ Value argumentValue = argument != null ? argument .getValue () : null ;
114+ if (argumentValue instanceof VariableReference ) {
115+ String variableName = ((VariableReference ) argumentValue ).getName ();
116+ hasValue = coercedVariableValues .containsKey (variableName );
117+ value = coercedVariableValues .get (variableName );
118+ } else {
119+ value = argumentValue ;
107120 }
108- boolean wasValueProvided = false ;
109- if (argumentMap .containsKey (argName )) {
110- if (argument .getValue () instanceof VariableReference ) {
111- wasValueProvided = variables .containsKey (((VariableReference ) argument .getValue ()).getName ());
121+ if (!hasValue && argumentDefinition .hasSetDefaultValue ()) {
122+ //TODO: default value needs to be coerced
123+ coercedValues .put (argumentName , defaultValue );
124+ } else if (isNonNull (argumentType ) && (!hasValue || value == null )) {
125+ throw new RuntimeException ();
126+ } else if (hasValue ) {
127+ if (value == null ) {
128+ coercedValues .put (argumentName , null );
129+ } else if (argumentValue instanceof VariableReference ) {
130+ coercedValues .put (argumentName , value );
112131 } else {
113- wasValueProvided = true ;
132+ value = coerceValueAst (codeRegistry .getFieldVisibility (), argumentType , argument .getValue (), coercedVariableValues );
133+ coercedValues .put (argumentName , value );
114134 }
135+ } else {
136+ // nullable type && hasValue == false && hasDefaultValue == false
137+ // meaning no value was provided for argumentName
115138 }
116- if (fieldArgument .hasSetDefaultValue ()) {
117- wasValueProvided = true ;
118- }
119- if (wasValueProvided ) {
120- result .put (argName , value );
121- }
139+
122140 }
123- return result ;
141+ return coercedValues ;
142+
124143 }
125144
126145
@@ -279,48 +298,51 @@ private Object coerceValueAstForList(GraphqlFieldVisibility fieldVisibility, Gra
279298 }
280299 }
281300
282- private Object coerceValueAstForInputObject (GraphqlFieldVisibility fieldVisibility , GraphQLInputObjectType type , ObjectValue inputValue , Map <String , Object > variables ) {
283- Map <String , Object > result = new LinkedHashMap <>();
284-
285- Map <String , ObjectField > inputValueFieldsByName = mapObjectValueFieldsByName (inputValue );
286-
287- List <GraphQLInputObjectField > inputFields = fieldVisibility .getFieldDefinitions (type );
288- for (GraphQLInputObjectField inputTypeField : inputFields ) {
289- if (inputValueFieldsByName .containsKey (inputTypeField .getName ())) {
290- boolean putObjectInMap = true ;
291-
292- ObjectField field = inputValueFieldsByName .get (inputTypeField .getName ());
293- Value fieldInputValue = field .getValue ();
294-
295- Object fieldObject = null ;
296- if (fieldInputValue instanceof VariableReference ) {
297- String varName = ((VariableReference ) fieldInputValue ).getName ();
298- if (!variables .containsKey (varName )) {
299- putObjectInMap = false ;
300- } else {
301- fieldObject = variables .get (varName );
302- }
303- } else {
304- fieldObject = coerceValueAst (fieldVisibility , inputTypeField .getType (), fieldInputValue , variables );
305- }
301+ private Object coerceValueAstForInputObject (GraphqlFieldVisibility fieldVisibility ,
302+ GraphQLInputObjectType type ,
303+ ObjectValue inputValue ,
304+ Map <String , Object > coercedVariableValues ) {
305+ Map <String , Object > coercedValues = new LinkedHashMap <>();
306306
307- if (fieldObject == null ) {
308- if (!(field .getValue () instanceof NullValue )) {
309- fieldObject = inputTypeField .getDefaultValue ();
310- }
311- }
312- if (putObjectInMap ) {
313- result .put (field .getName (), fieldObject );
307+ Map <String , ObjectField > inputFieldsByName = mapObjectValueFieldsByName (inputValue );
308+
309+ List <GraphQLInputObjectField > inputFieldTypes = fieldVisibility .getFieldDefinitions (type );
310+ for (GraphQLInputObjectField inputFieldType : inputFieldTypes ) {
311+
312+ GraphQLInputType fieldType = inputFieldType .getType ();
313+ String fieldName = inputFieldType .getName ();
314+ ObjectField field = inputFieldsByName .get (fieldName );
315+ Object defaultValue = inputFieldType .getDefaultValue ();
316+ boolean hasValue = field != null ;
317+ Object value ;
318+ Value fieldValue = field != null ? field .getValue () : null ;
319+ if (fieldValue instanceof VariableReference ) {
320+ String variableName = ((VariableReference ) fieldValue ).getName ();
321+ hasValue = coercedVariableValues .containsKey (variableName );
322+ value = coercedVariableValues .get (variableName );
323+ } else {
324+ value = fieldValue ;
325+ }
326+ if (!hasValue && inputFieldType .hasSetDefaultValue ()) {
327+ //TODO: default value should be coerced
328+ coercedValues .put (fieldName , defaultValue );
329+ } else if (isNonNull (fieldType ) && (!hasValue || value == null )) {
330+ throw new NonNullableValueCoercedAsNullException (inputFieldType );
331+ } else if (hasValue ) {
332+ if (value == null ) {
333+ coercedValues .put (fieldName , null );
334+ } else if (fieldValue instanceof VariableReference ) {
335+ coercedValues .put (fieldName , value );
314336 } else {
315- assertNonNullInputField (inputTypeField );
337+ value = coerceValueAst (fieldVisibility , fieldType , fieldValue , coercedVariableValues );
338+ coercedValues .put (fieldName , value );
316339 }
317- } else if (inputTypeField .getDefaultValue () != null ) {
318- result .put (inputTypeField .getName (), inputTypeField .getDefaultValue ());
319340 } else {
320- assertNonNullInputField (inputTypeField );
341+ // nullable type && hasValue == false && hasDefaultValue == false
342+ // meaning no value was provided for this field
321343 }
322344 }
323- return result ;
345+ return coercedValues ;
324346 }
325347
326348 private void assertNonNullInputField (GraphQLInputObjectField inputTypeField ) {
0 commit comments