11package graphql .execution .directives ;
22
3+ import com .google .common .collect .BiMap ;
4+ import com .google .common .collect .HashBiMap ;
35import com .google .common .collect .ImmutableList ;
46import com .google .common .collect .ImmutableMap ;
57import graphql .GraphQLContext ;
68import graphql .Internal ;
7- import graphql .collect .ImmutableKit ;
89import graphql .execution .MergedField ;
10+ import graphql .execution .ValuesResolver ;
911import graphql .language .Directive ;
1012import graphql .language .Field ;
13+ import graphql .normalized .NormalizedInputValue ;
1114import graphql .schema .GraphQLArgument ;
1215import graphql .schema .GraphQLDirective ;
1316import graphql .schema .GraphQLSchema ;
@@ -33,7 +36,8 @@ public class QueryDirectivesImpl implements QueryDirectives {
3336 private final DirectivesResolver directivesResolver = new DirectivesResolver ();
3437 private final MergedField mergedField ;
3538 private final GraphQLSchema schema ;
36- private final Map <String , Object > variables ;
39+ private final Map <String , Object > coercedVariables ;
40+ private final Map <String , NormalizedInputValue > normalizedVariableValues ;
3741 private final GraphQLContext graphQLContext ;
3842 private final Locale locale ;
3943
@@ -42,11 +46,13 @@ public class QueryDirectivesImpl implements QueryDirectives {
4246 private volatile ImmutableMap <String , List <GraphQLDirective >> fieldDirectivesByName ;
4347 private volatile ImmutableMap <Field , List <QueryAppliedDirective >> fieldAppliedDirectivesByField ;
4448 private volatile ImmutableMap <String , List <QueryAppliedDirective >> fieldAppliedDirectivesByName ;
49+ private volatile ImmutableMap <QueryAppliedDirective , Map <String , NormalizedInputValue >> normalizedValuesByAppliedDirective ;
4550
46- public QueryDirectivesImpl (MergedField mergedField , GraphQLSchema schema , Map <String , Object > variables , GraphQLContext graphQLContext , Locale locale ) {
51+ public QueryDirectivesImpl (MergedField mergedField , GraphQLSchema schema , Map <String , Object > coercedVariables , Map < String , NormalizedInputValue > normalizedVariableValues , GraphQLContext graphQLContext , Locale locale ) {
4752 this .mergedField = mergedField ;
4853 this .schema = schema ;
49- this .variables = variables ;
54+ this .coercedVariables = coercedVariables ;
55+ this .normalizedVariableValues = normalizedVariableValues ;
5056 this .graphQLContext = graphQLContext ;
5157 this .locale = locale ;
5258 }
@@ -56,16 +62,32 @@ private void computeValuesLazily() {
5662
5763 final Map <Field , List <GraphQLDirective >> byField = new LinkedHashMap <>();
5864 final Map <Field , List <QueryAppliedDirective >> byFieldApplied = new LinkedHashMap <>();
65+
66+ BiMap <GraphQLDirective , Directive > directiveCounterParts = HashBiMap .create ();
67+ BiMap <GraphQLDirective , QueryAppliedDirective > gqlDirectiveCounterParts = HashBiMap .create ();
68+ BiMap <QueryAppliedDirective , GraphQLDirective > gqlDirectiveCounterPartsInverse = gqlDirectiveCounterParts .inverse ();
5969 mergedField .getFields ().forEach (field -> {
6070 List <Directive > directives = field .getDirectives ();
6171 ImmutableList <GraphQLDirective > resolvedDirectives = ImmutableList .copyOf (FpKit .flatList (
6272 directivesResolver
63- .resolveDirectives (directives , schema , variables , graphQLContext , locale )
73+ .resolveDirectives (directives , schema , coercedVariables , graphQLContext , locale )
6474 .values ()
6575 ));
76+ for (int i = 0 ; i < directives .size (); i ++) {
77+ Directive directive = directives .get (i );
78+ GraphQLDirective graphQLDirective = resolvedDirectives .get (i );
79+ directiveCounterParts .put (graphQLDirective , directive );
80+ }
81+
82+ ImmutableList .Builder <QueryAppliedDirective > appliedDirectiveBuilder = ImmutableList .builder ();
83+ for (GraphQLDirective resolvedDirective : resolvedDirectives ) {
84+ QueryAppliedDirective appliedDirective = toAppliedDirective (resolvedDirective );
85+ gqlDirectiveCounterParts .put (resolvedDirective , appliedDirective );
86+ appliedDirectiveBuilder .add (appliedDirective );
87+ }
6688 byField .put (field , resolvedDirectives );
6789 // at some point we will only use applied
68- byFieldApplied .put (field , ImmutableKit . map ( resolvedDirectives , this :: toAppliedDirective ));
90+ byFieldApplied .put (field , appliedDirectiveBuilder . build ( ));
6991 });
7092
7193 Map <String , List <GraphQLDirective >> byName = new LinkedHashMap <>();
@@ -74,13 +96,29 @@ private void computeValuesLazily() {
7496 String name = directive .getName ();
7597 byName .computeIfAbsent (name , k -> new ArrayList <>()).add (directive );
7698 // at some point we will only use applied
77- byNameApplied .computeIfAbsent (name , k -> new ArrayList <>()).add (toAppliedDirective (directive ));
99+ QueryAppliedDirective appliedDirective = gqlDirectiveCounterParts .get (directive );
100+ byNameApplied .computeIfAbsent (name , k -> new ArrayList <>()).add (appliedDirective );
78101 }));
79102
103+ // create NormalizedInputValue values for directive arguments
104+ Map <QueryAppliedDirective , Map <String , NormalizedInputValue >> normalizedValuesByAppliedDirective = new LinkedHashMap <>();
105+ if (this .normalizedVariableValues != null ) {
106+ byNameApplied .values ().forEach (directiveList -> {
107+ for (QueryAppliedDirective queryAppliedDirective : directiveList ) {
108+ GraphQLDirective graphQLDirective = gqlDirectiveCounterPartsInverse .get (queryAppliedDirective );
109+ Directive directive = directiveCounterParts .get (graphQLDirective );
110+
111+ Map <String , NormalizedInputValue > normalizedArgumentValues = ValuesResolver .getNormalizedArgumentValues (graphQLDirective .getArguments (), directive .getArguments (), this .normalizedVariableValues );
112+ normalizedValuesByAppliedDirective .put (queryAppliedDirective , normalizedArgumentValues );
113+ }
114+ });
115+ }
116+
80117 this .fieldDirectivesByName = ImmutableMap .copyOf (byName );
81118 this .fieldDirectivesByField = ImmutableMap .copyOf (byField );
82119 this .fieldAppliedDirectivesByName = ImmutableMap .copyOf (byNameApplied );
83120 this .fieldAppliedDirectivesByField = ImmutableMap .copyOf (byFieldApplied );
121+ this .normalizedValuesByAppliedDirective = ImmutableMap .copyOf (normalizedValuesByAppliedDirective );
84122 });
85123 }
86124
@@ -114,6 +152,12 @@ public Map<Field, List<QueryAppliedDirective>> getImmediateAppliedDirectivesByFi
114152 return fieldAppliedDirectivesByField ;
115153 }
116154
155+ @ Override
156+ public Map <QueryAppliedDirective , Map <String , NormalizedInputValue >> getNormalizedInputValueByImmediateAppliedDirectives () {
157+ computeValuesLazily ();
158+ return normalizedValuesByAppliedDirective ;
159+ }
160+
117161 @ Override
118162 public Map <String , List <GraphQLDirective >> getImmediateDirectivesByName () {
119163 computeValuesLazily ();
0 commit comments