@@ -34,7 +34,8 @@ type Resolvable struct {
3434 astjsonArena * astjson.Arena
3535 parsers []* astjson.Parser
3636
37- print bool
37+ enableRender bool
38+ enableDeferRender bool
3839 out io.Writer
3940 printErr error
4041 path []fastjsonext.PathElement
@@ -90,7 +91,7 @@ func (r *Resolvable) Reset() {
9091 r .errors = nil
9192 r .valueCompletion = nil
9293 r .depth = 0
93- r .print = false
94+ r .enableRender = false
9495 r .out = nil
9596 r .printErr = nil
9697 r .path = r .path [:0 ]
@@ -167,7 +168,7 @@ func (r *Resolvable) InitSubscription(ctx *Context, initialData []byte, postProc
167168
168169func (r * Resolvable ) ResolveNode (node Node , data * astjson.Value , out io.Writer ) error {
169170 r .out = out
170- r .print = false
171+ r .enableRender = false
171172 r .printErr = nil
172173 r .authorizationError = nil
173174 r .errors = r .astjsonArena .NewArray ()
@@ -177,7 +178,7 @@ func (r *Resolvable) ResolveNode(node Node, data *astjson.Value, out io.Writer)
177178 return fmt .Errorf ("error resolving node" )
178179 }
179180
180- r .print = true
181+ r .enableRender = true
181182 hasErrors = r .walkNode (node , data )
182183 if hasErrors {
183184 return fmt .Errorf ("error resolving node: %w" , r .printErr )
@@ -187,7 +188,7 @@ func (r *Resolvable) ResolveNode(node Node, data *astjson.Value, out io.Writer)
187188
188189func (r * Resolvable ) Resolve (ctx context.Context , rootData * Object , fetchTree * FetchTreeNode , out io.Writer ) error {
189190 r .out = out
190- r .print = false
191+ r .enableRender = false
191192 r .printErr = nil
192193 r .authorizationError = nil
193194
@@ -247,6 +248,14 @@ func (r *Resolvable) err() bool {
247248 return true
248249}
249250
251+ func (r * Resolvable ) render () bool {
252+ if ! r .deferMode {
253+ return r .enableRender
254+ }
255+
256+ return r .enableRender && r .enableDeferRender
257+ }
258+
250259func (r * Resolvable ) printErrors () {
251260 r .printBytes (quote )
252261 r .printBytes (literalErrors )
@@ -263,9 +272,9 @@ func (r *Resolvable) printData(root *Object) {
263272 r .printBytes (quote )
264273 r .printBytes (colon )
265274 r .printBytes (lBrace )
266- r .print = true
275+ r .enableRender = true
267276 _ = r .walkObject (root , r .data )
268- r .print = false
277+ r .enableRender = false
269278 r .printBytes (rBrace )
270279 r .wroteData = true
271280}
@@ -592,7 +601,7 @@ func (r *Resolvable) walkObject(obj *Object, parent *astjson.Value) bool {
592601 // when we have a typename field present in a json object, we need to check if the type is valid
593602
594603 if _ , ok := obj .PossibleTypes [string (typeName )]; ! ok {
595- if ! r .print {
604+ if ! r .render () {
596605 // during pre-walk we need to add an error when the typename do not match a possible type
597606 if r .options .ApolloCompatibilityValueCompletionInExtensions {
598607 r .addValueCompletion (fmt .Sprintf ("Invalid __typename found for object at %s." , r .pathLastElementDescription (obj .TypeName )), errorcodes .InvalidGraphql )
@@ -617,7 +626,7 @@ func (r *Resolvable) walkObject(obj *Object, parent *astjson.Value) bool {
617626 }
618627 }
619628
620- if r .print && ! isRoot {
629+ if r .render () && ! isRoot {
621630 r .printBytes (lBrace )
622631 }
623632 addComma := false
@@ -637,7 +646,7 @@ func (r *Resolvable) walkObject(obj *Object, parent *astjson.Value) bool {
637646 continue
638647 }
639648 }
640- if ! r .print {
649+ if ! r .render () {
641650 skip := r .authorizeField (value , obj .Fields [i ])
642651 if skip {
643652 if obj .Fields [i ].Value .NodeNullable () {
@@ -661,7 +670,7 @@ func (r *Resolvable) walkObject(obj *Object, parent *astjson.Value) bool {
661670 continue
662671 }
663672 }
664- if r .print {
673+ if r .render () {
665674 if addComma {
666675 r .printBytes (comma )
667676 }
@@ -683,7 +692,7 @@ func (r *Resolvable) walkObject(obj *Object, parent *astjson.Value) bool {
683692 }
684693 addComma = true
685694 }
686- if r .print && ! isRoot {
695+ if r .render () && ! isRoot {
687696 r .printBytes (rBrace )
688697 }
689698 return false
@@ -828,23 +837,23 @@ func (r *Resolvable) walkArray(arr *Array, value *astjson.Value) bool {
828837 r .addError ("Array cannot represent non-array value." , arr .Path )
829838 return r .err ()
830839 }
831- if r .print {
840+ if r .render () {
832841 r .printBytes (lBrack )
833842 }
834843 values := value .GetArray ()
835844
836845 hasPrintedValue := false
837846 for i , arrayValue := range values {
838847 skip := false
839- if r .print && arr .SkipItem != nil {
848+ if r .render () && arr .SkipItem != nil {
840849 skip = arr .SkipItem (r .ctx , arrayValue )
841850 }
842851
843852 if skip {
844853 continue
845854 }
846855
847- if r .print && i != 0 && hasPrintedValue {
856+ if r .render () && i != 0 && hasPrintedValue {
848857 r .printBytes (comma )
849858 }
850859
@@ -865,21 +874,21 @@ func (r *Resolvable) walkArray(arr *Array, value *astjson.Value) bool {
865874 return err
866875 }
867876 }
868- if r .print {
877+ if r .render () {
869878 r .printBytes (rBrack )
870879 }
871880 return false
872881}
873882
874883func (r * Resolvable ) walkNull () bool {
875- if r .print {
884+ if r .render () {
876885 r .printBytes (null )
877886 }
878887 return false
879888}
880889
881890func (r * Resolvable ) walkStaticString (str * StaticString ) bool {
882- if r .print {
891+ if r .render () {
883892 r .printBytes (quote )
884893 r .printBytes ([]byte (str .Value ))
885894 r .printBytes (quote )
@@ -902,7 +911,7 @@ func (r *Resolvable) walkString(s *String, value *astjson.Value) bool {
902911 r .addError (fmt .Sprintf ("String cannot represent non-string value: \" %s\" " , string (r .marshalBuf )), s .Path )
903912 return r .err ()
904913 }
905- if r .print {
914+ if r .render () {
906915 if s .IsTypeName {
907916 content := value .GetStringBytes ()
908917 for i := range r .renameTypeNames {
@@ -948,7 +957,7 @@ func (r *Resolvable) walkBoolean(b *Boolean, value *astjson.Value) bool {
948957 r .addError (fmt .Sprintf ("Bool cannot represent non-boolean value: \" %s\" " , string (r .marshalBuf )), b .Path )
949958 return r .err ()
950959 }
951- if r .print {
960+ if r .render () {
952961 r .renderScalarFieldValue (value , b .Nullable )
953962 }
954963 return false
@@ -969,7 +978,7 @@ func (r *Resolvable) walkInteger(i *Integer, value *astjson.Value) bool {
969978 r .addError (fmt .Sprintf ("Int cannot represent non-integer value: \" %s\" " , string (r .marshalBuf )), i .Path )
970979 return r .err ()
971980 }
972- if r .print {
981+ if r .render () {
973982 r .renderScalarFieldValue (value , i .Nullable )
974983 }
975984 return false
@@ -985,14 +994,14 @@ func (r *Resolvable) walkFloat(f *Float, value *astjson.Value) bool {
985994 r .addNonNullableFieldError (f .Path , parent )
986995 return r .err ()
987996 }
988- if ! r .print {
997+ if ! r .render () {
989998 if value .Type () != astjson .TypeNumber {
990999 r .marshalBuf = value .MarshalTo (r .marshalBuf [:0 ])
9911000 r .addError (fmt .Sprintf ("Float cannot represent non-float value: \" %s\" " , string (r .marshalBuf )), f .Path )
9921001 return r .err ()
9931002 }
9941003 }
995- if r .print {
1004+ if r .render () {
9961005 if r .options .ApolloCompatibilityTruncateFloatValues {
9971006 floatValue := value .GetFloat64 ()
9981007 if floatValue == float64 (int64 (floatValue )) {
@@ -1015,7 +1024,7 @@ func (r *Resolvable) walkBigInt(b *BigInt, value *astjson.Value) bool {
10151024 r .addNonNullableFieldError (b .Path , parent )
10161025 return r .err ()
10171026 }
1018- if r .print {
1027+ if r .render () {
10191028 r .renderScalarFieldValue (value , b .Nullable )
10201029 }
10211030 return false
@@ -1031,22 +1040,22 @@ func (r *Resolvable) walkScalar(s *Scalar, value *astjson.Value) bool {
10311040 r .addNonNullableFieldError (s .Path , parent )
10321041 return r .err ()
10331042 }
1034- if r .print {
1043+ if r .render () {
10351044 r .renderScalarFieldValue (value , s .Nullable )
10361045 }
10371046 return false
10381047}
10391048
10401049func (r * Resolvable ) walkEmptyObject (_ * EmptyObject ) bool {
1041- if r .print {
1050+ if r .render () {
10421051 r .printBytes (lBrace )
10431052 r .printBytes (rBrace )
10441053 }
10451054 return false
10461055}
10471056
10481057func (r * Resolvable ) walkEmptyArray (_ * EmptyArray ) bool {
1049- if r .print {
1058+ if r .render () {
10501059 r .printBytes (lBrack )
10511060 r .printBytes (rBrack )
10521061 }
@@ -1069,7 +1078,7 @@ func (r *Resolvable) walkCustom(c *CustomNode, value *astjson.Value) bool {
10691078 r .addError (err .Error (), c .Path )
10701079 return r .err ()
10711080 }
1072- if r .print {
1081+ if r .render () {
10731082 r .renderScalarFieldBytes (resolved , c .Nullable )
10741083 }
10751084 return false
@@ -1154,7 +1163,7 @@ func (r *Resolvable) walkEnum(e *Enum, value *astjson.Value) bool {
11541163 * To avoid appending an error twice, the appending only happens on the first walk
11551164 * and not the second walk (which prints the data).
11561165 */
1157- if ! r .print {
1166+ if ! r .render () {
11581167 if r .options .ApolloCompatibilityValueCompletionInExtensions {
11591168 r .renderInaccessibleEnumValueError (e )
11601169 } else {
@@ -1172,7 +1181,7 @@ func (r *Resolvable) walkEnum(e *Enum, value *astjson.Value) bool {
11721181 * To avoid appending an error/value completion twice, the appending only happens on the first walk
11731182 * and not the second walk (which prints the data).
11741183 */
1175- if ! r .print {
1184+ if ! r .render () {
11761185 r .renderInaccessibleEnumValueError (e )
11771186 }
11781187 // Inaccessible enum values are always converted to null
@@ -1181,7 +1190,7 @@ func (r *Resolvable) walkEnum(e *Enum, value *astjson.Value) bool {
11811190 }
11821191 return r .err ()
11831192 }
1184- if r .print {
1193+ if r .render () {
11851194 r .renderEnumValue (value , e .Nullable )
11861195 }
11871196 return false
0 commit comments