55import graphql .Assert ;
66import graphql .Internal ;
77import graphql .Mutable ;
8+ import graphql .PublicApi ;
89import graphql .collect .ImmutableKit ;
910import graphql .introspection .Introspection ;
1011import graphql .language .Argument ;
3839import static java .util .stream .Collectors .toSet ;
3940
4041/**
41- * Intentionally Mutable
42+ * An {@link ExecutableNormalizedField} represents a field in an executable graphql operation. Its models what
43+ * could be executed during a given operation.
44+ * <p>
45+ * This class is intentionally mutable for performance reasons since building immutable parent child
46+ * objects is too expensive.
4247 */
43- @ Internal
48+ @ PublicApi
4449@ Mutable
4550public class ExecutableNormalizedField {
4651 private final String alias ;
@@ -164,7 +169,7 @@ public boolean isConditional(@NotNull GraphQLSchema schema) {
164169 }
165170 }
166171
167- /**
172+ /*
168173 *__typename is the only field in a union type that CAN be NOT conditional
169174 */
170175 List <GraphQLFieldDefinition > fieldDefinitions = parent .getFieldDefinitions (schema );
@@ -175,7 +180,7 @@ public boolean isConditional(@NotNull GraphQLSchema schema) {
175180 }
176181 }
177182
178- /**
183+ /*
179184 * This means there is no Union or Interface which could serve as unconditional parent
180185 */
181186 if (objectTypeNames .size () > 1 ) {
@@ -232,39 +237,58 @@ private static GraphQLFieldDefinition resolveIntrospectionField(GraphQLSchema sc
232237 return null ;
233238 }
234239
240+ @ Internal
235241 public void addObjectTypeNames (Collection <String > objectTypeNames ) {
236242 this .objectTypeNames .addAll (objectTypeNames );
237243 }
238244
245+ @ Internal
239246 public void setObjectTypeNames (Collection <String > objectTypeNames ) {
240247 this .objectTypeNames .clear ();
241248 this .objectTypeNames .addAll (objectTypeNames );
242249 }
243250
251+ @ Internal
244252 public void addChild (ExecutableNormalizedField executableNormalizedField ) {
245253 this .children .add (executableNormalizedField );
246254 }
247255
256+ @ Internal
248257 public void clearChildren () {
249258 this .children .clear ();
250259 }
251260
252261 /**
253- * All merged fields have the same name.
262+ * All merged fields have the same name so this is the name of the {@link ExecutableNormalizedField} .
254263 * <p>
255- * WARNING: This is not always the key in the execution result, because of possible aliases. See {@link #getResultKey()}
264+ * WARNING: This is not always the key in the execution result, because of possible field aliases.
265+ *
266+ * @return the name of this {@link ExecutableNormalizedField}
256267 *
257- * @return the name of of the merged fields.
268+ * @see #getResultKey()
269+ * @see #getAlias()
258270 */
259271 public String getName () {
260272 return getFieldName ();
261273 }
262274
263275 /**
264- * Returns the key of this MergedFieldWithType for the overall result.
265- * This is either an alias or the FieldWTC name.
276+ * @return the same value as {@link #getName()}
277+ *
278+ * @see #getResultKey()
279+ * @see #getAlias()
280+ */
281+ public String getFieldName () {
282+ return fieldName ;
283+ }
284+
285+ /**
286+ * Returns the result key of this {@link ExecutableNormalizedField} within the overall result.
287+ * This is either a field alias or the value of {@link #getName()}
288+ *
289+ * @return the result key for this {@link ExecutableNormalizedField}.
266290 *
267- * @return the key for this MergedFieldWithType.
291+ * @see #getName()
268292 */
269293 public String getResultKey () {
270294 if (alias != null ) {
@@ -273,56 +297,80 @@ public String getResultKey() {
273297 return getName ();
274298 }
275299
300+ /**
301+ * @return the field alias used or null if there is none
302+ *
303+ * @see #getResultKey()
304+ * @see #getName()
305+ */
276306 public String getAlias () {
277307 return alias ;
278308 }
279309
310+ /**
311+ * @return a list of the {@link Argument}s on the field
312+ */
280313 public ImmutableList <Argument > getAstArguments () {
281314 return astArguments ;
282315 }
283316
317+ /**
318+ * Returns an argument value as a {@link NormalizedInputValue} which contains its type name and its current value
319+ *
320+ * @param name the name of the argument
321+ *
322+ * @return an argument value
323+ */
284324 public NormalizedInputValue getNormalizedArgument (String name ) {
285325 return normalizedArguments .get (name );
286326 }
287327
328+ /**
329+ * @return a map of all the arguments in {@link NormalizedInputValue} form
330+ */
288331 public ImmutableMap <String , NormalizedInputValue > getNormalizedArguments () {
289332 return normalizedArguments ;
290333 }
291334
335+ /**
336+ * @return a map of the resolved argument values
337+ */
292338 public LinkedHashMap <String , Object > getResolvedArguments () {
293339 return resolvedArguments ;
294340 }
295341
296342
297- public static Builder newNormalizedField () {
298- return new Builder ();
299- }
300-
301-
302- public String getFieldName () {
303- return fieldName ;
304- }
305-
306-
307- public ExecutableNormalizedField transform (Consumer <Builder > builderConsumer ) {
308- Builder builder = new Builder (this );
309- builderConsumer .accept (builder );
310- return builder .build ();
311- }
312-
313-
314343 /**
315- * @return Warning: returns a Mutable Set. No defensive copy is made for performance reasons.
344+ * A {@link ExecutableNormalizedField} can sometimes (for non-concrete types like interfaces and unions)
345+ * have more than one object type it could be when executed. There is no way to know what it will be until
346+ * the field is executed over data and the type is resolved via a {@link graphql.schema.TypeResolver}.
347+ * <p>
348+ * This method returns all the possible types a field can be which is one or more {@link GraphQLObjectType}
349+ * names.
350+ * <p>
351+ * Warning: This returns a Mutable Set. No defensive copy is made for performance reasons.
352+ *
353+ * @return a set of the possible type names this field could be.
316354 */
317355 public Set <String > getObjectTypeNames () {
318356 return objectTypeNames ;
319357 }
320358
359+
360+ /**
361+ * This returns the first entry in {@link #getObjectTypeNames()}. Sometimes you know a field cant be more than one
362+ * type and this method is a shortcut one to help you.
363+ *
364+ * @return the first entry from
365+ */
321366 public String getSingleObjectTypeName () {
322367 return objectTypeNames .iterator ().next ();
323368 }
324369
325370
371+ /**
372+ * @return a helper method show field details
373+ */
326374 public String printDetails () {
327375 StringBuilder result = new StringBuilder ();
328376 if (getAlias () != null ) {
@@ -331,6 +379,9 @@ public String printDetails() {
331379 return result + objectTypeNamesToString () + "." + fieldName ;
332380 }
333381
382+ /**
383+ * @return a helper method to show the object types names as a string
384+ */
334385 public String objectTypeNamesToString () {
335386 if (objectTypeNames .size () == 1 ) {
336387 return objectTypeNames .iterator ().next ();
@@ -339,6 +390,12 @@ public String objectTypeNamesToString() {
339390 }
340391 }
341392
393+ /**
394+ * This returns the list of the result keys (see {@link #getResultKey()} that lead from this field upwards to
395+ * its parent field
396+ *
397+ * @return a list of the result keys from this {@link ExecutableNormalizedField} to the top of the operation via parent fields
398+ */
342399 public List <String > getListOfResultKeys () {
343400 LinkedList <String > list = new LinkedList <>();
344401 ExecutableNormalizedField current = this ;
@@ -349,10 +406,20 @@ public List<String> getListOfResultKeys() {
349406 return list ;
350407 }
351408
409+ /**
410+ * @return the children of the {@link ExecutableNormalizedField}
411+ */
352412 public List <ExecutableNormalizedField > getChildren () {
353413 return children ;
354414 }
355415
416+ /**
417+ * Returns the list of child fields that would have the same result key
418+ *
419+ * @param resultKey the result key to check
420+ *
421+ * @return a list of all direct {@link ExecutableNormalizedField} children with the specified result key
422+ */
356423 public List <ExecutableNormalizedField > getChildrenWithSameResultKey (String resultKey ) {
357424 return FpKit .filterList (children , child -> child .getResultKey ().equals (resultKey ));
358425 }
@@ -380,14 +447,24 @@ public List<ExecutableNormalizedField> getChildren(String objectTypeName) {
380447 .collect (toList ());
381448 }
382449
450+ /**
451+ * the level of the {@link ExecutableNormalizedField} in the operation hierarchy with top level fields
452+ * starting at 1
453+ *
454+ * @return the level of the {@link ExecutableNormalizedField} in the operation hierarchy
455+ */
383456 public int getLevel () {
384457 return level ;
385458 }
386459
460+ /**
461+ * @return the parent of this {@link ExecutableNormalizedField} or null if it's a top level field
462+ */
387463 public ExecutableNormalizedField getParent () {
388464 return parent ;
389465 }
390466
467+ @ Internal
391468 public void replaceParent (ExecutableNormalizedField newParent ) {
392469 this .parent = newParent ;
393470 }
@@ -404,6 +481,11 @@ public String toString() {
404481 }
405482
406483
484+ /**
485+ * Traverse from this {@link ExecutableNormalizedField} down into itself and all of its children
486+ *
487+ * @param consumer the callback for each {@link ExecutableNormalizedField} in the hierarchy.
488+ */
407489 public void traverseSubTree (Consumer <ExecutableNormalizedField > consumer ) {
408490 this .getChildren ().forEach (child -> {
409491 traverseImpl (child , consumer , 1 , Integer .MAX_VALUE );
@@ -423,6 +505,27 @@ private void traverseImpl(ExecutableNormalizedField root,
423505 });
424506 }
425507
508+ /**
509+ * @return a {@link Builder} of {@link ExecutableNormalizedField}s
510+ */
511+ public static Builder newNormalizedField () {
512+ return new Builder ();
513+ }
514+
515+
516+ /**
517+ * Allows this {@link ExecutableNormalizedField} to be transformed via a {@link Builder} consumer callback
518+ *
519+ * @param builderConsumer the consumer given a builder
520+ *
521+ * @return a new transformed {@link ExecutableNormalizedField}
522+ */
523+ public ExecutableNormalizedField transform (Consumer <Builder > builderConsumer ) {
524+ Builder builder = new Builder (this );
525+ builderConsumer .accept (builder );
526+ return builder .build ();
527+ }
528+
426529 public static class Builder {
427530 private LinkedHashSet <String > objectTypeNames = new LinkedHashSet <>();
428531 private String fieldName ;
0 commit comments