88package json
99
1010import (
11+ "context"
1112 "encoding"
1213 "encoding/base64"
1314 "fmt"
@@ -95,10 +96,15 @@ import (
9596// Instead, they are replaced by the Unicode replacement
9697// character U+FFFD.
9798func Unmarshal (data []byte , v any ) error {
99+ return UnmarshalContext (context .Background (), data , v )
100+ }
101+
102+ func UnmarshalContext (ctx context.Context , data []byte , v any ) error {
98103 // Check for well-formedness.
99104 // Avoids filling out half a data structure
100105 // before discovering a JSON syntax error.
101106 var d decodeState
107+ d .ctx = ctx
102108 err := checkValid (data , & d .scan )
103109 if err != nil {
104110 return err
@@ -209,6 +215,7 @@ type errorContext struct {
209215
210216// decodeState represents the state while decoding a JSON value.
211217type decodeState struct {
218+ ctx context.Context
212219 data []byte
213220 off int // next read offset in data
214221 opcode int // last read result
@@ -428,7 +435,7 @@ func (d *decodeState) valueQuoted() any {
428435// If it encounters an Unmarshaler, indirect stops and returns that.
429436// If decodingNull is true, indirect stops at the first settable pointer so it
430437// can be set to nil.
431- func indirect (v reflect.Value , decodingNull bool ) (Unmarshaler , encoding.TextUnmarshaler , reflect.Value ) {
438+ func indirect (v reflect.Value , decodingNull bool ) (Unmarshaler , ContextUnmarshaler , encoding.TextUnmarshaler , reflect.Value ) {
432439 // Issue #24153 indicates that it is generally not a guaranteed property
433440 // that you may round-trip a reflect.Value by calling Value.Addr().Elem()
434441 // and expect the value to still be settable for values derived from
@@ -482,11 +489,14 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm
482489 }
483490 if v .Type ().NumMethod () > 0 && v .CanInterface () {
484491 if u , ok := v .Interface ().(Unmarshaler ); ok {
485- return u , nil , reflect.Value {}
492+ return u , nil , nil , reflect.Value {}
493+ }
494+ if cu , ok := v .Interface ().(ContextUnmarshaler ); ok {
495+ return nil , cu , nil , reflect.Value {}
486496 }
487497 if ! decodingNull {
488498 if u , ok := v .Interface ().(encoding.TextUnmarshaler ); ok {
489- return nil , u , reflect.Value {}
499+ return nil , nil , u , reflect.Value {}
490500 }
491501 }
492502 }
@@ -498,14 +508,14 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm
498508 v = v .Elem ()
499509 }
500510 }
501- return nil , nil , v
511+ return nil , nil , nil , v
502512}
503513
504514// array consumes an array from d.data[d.off-1:], decoding into v.
505515// The first byte of the array ('[') has been read already.
506516func (d * decodeState ) array (v reflect.Value ) error {
507517 // Check for unmarshaler.
508- u , ut , pv := indirect (v , false )
518+ u , cu , ut , pv := indirect (v , false )
509519 if u != nil {
510520 start := d .readIndex ()
511521 d .skip ()
@@ -515,6 +525,15 @@ func (d *decodeState) array(v reflect.Value) error {
515525 }
516526 return nil
517527 }
528+ if cu != nil {
529+ start := d .readIndex ()
530+ d .skip ()
531+ err := cu .UnmarshalJSONContext (d .ctx , d .data [start :d .off ])
532+ if err != nil {
533+ d .saveError (err )
534+ }
535+ return nil
536+ }
518537 if ut != nil {
519538 d .saveError (& UnmarshalTypeError {Value : "array" , Type : v .Type (), Offset : int64 (d .off )})
520539 d .skip ()
@@ -612,7 +631,7 @@ var (
612631// The first byte ('{') of the object has been read already.
613632func (d * decodeState ) object (v reflect.Value ) error {
614633 // Check for unmarshaler.
615- u , ut , pv := indirect (v , false )
634+ u , cu , ut , pv := indirect (v , false )
616635 if u != nil {
617636 start := d .readIndex ()
618637 d .skip ()
@@ -622,6 +641,15 @@ func (d *decodeState) object(v reflect.Value) error {
622641 }
623642 return nil
624643 }
644+ if cu != nil {
645+ start := d .readIndex ()
646+ d .skip ()
647+ err := cu .UnmarshalJSONContext (d .ctx , d .data [start :d .off ])
648+ if err != nil {
649+ d .saveError (err )
650+ }
651+ return nil
652+ }
625653 if ut != nil {
626654 d .saveError (& UnmarshalTypeError {Value : "object" , Type : v .Type (), Offset : int64 (d .off )})
627655 d .skip ()
@@ -870,14 +898,21 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
870898 return nil
871899 }
872900 isNull := item [0 ] == 'n' // null
873- u , ut , pv := indirect (v , isNull )
901+ u , cu , ut , pv := indirect (v , isNull )
874902 if u != nil {
875903 err := u .UnmarshalJSON (item )
876904 if err != nil {
877905 d .saveError (err )
878906 }
879907 return nil
880908 }
909+ if cu != nil {
910+ err := cu .UnmarshalJSONContext (d .ctx , item )
911+ if err != nil {
912+ d .saveError (err )
913+ }
914+ return nil
915+ }
881916 if ut != nil {
882917 if item [0 ] != '"' {
883918 if fromQuoted {
0 commit comments