1
2
3
4
5
6
7 package json
8
9 import (
10 "errors"
11 "fmt"
12 "io"
13 "reflect"
14 "sync"
15
16 "encoding/json/internal"
17 "encoding/json/internal/jsonflags"
18 "encoding/json/internal/jsonopts"
19 "encoding/json/jsontext"
20 )
21
22 var errUnsupportedMutation = errors.New("unsupported calls must not read or write any tokens")
23 var errNonSingularValue = errors.New("must read or write exactly one value")
24
25
26
27
28
29
30 type Marshalers = typedMarshalers
31
32
33
34
35
36
37
38
39
40
41
42
43
44 func JoinMarshalers(ms ...*Marshalers) *Marshalers {
45 return newMarshalers(ms...)
46 }
47
48
49
50
51
52
53 type Unmarshalers = typedUnmarshalers
54
55
56
57
58
59
60
61
62
63
64
65
66
67 func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers {
68 return newUnmarshalers(us...)
69 }
70
71 type typedMarshalers = typedArshalers[jsontext.Encoder]
72 type typedUnmarshalers = typedArshalers[jsontext.Decoder]
73 type typedArshalers[Coder any] struct {
74 nonComparable
75
76 fncVals []typedArshaler[Coder]
77 fncCache sync.Map
78
79
80
81
82
83
84
85
86
87
88 fromAny bool
89 }
90 type typedMarshaler = typedArshaler[jsontext.Encoder]
91 type typedUnmarshaler = typedArshaler[jsontext.Decoder]
92 type typedArshaler[Coder any] struct {
93 typ reflect.Type
94 fnc func(*Coder, addressableValue, *jsonopts.Struct) error
95 maySkip bool
96 }
97
98 func newMarshalers(ms ...*Marshalers) *Marshalers { return newTypedArshalers(ms...) }
99 func newUnmarshalers(us ...*Unmarshalers) *Unmarshalers { return newTypedArshalers(us...) }
100 func newTypedArshalers[Coder any](as ...*typedArshalers[Coder]) *typedArshalers[Coder] {
101 var a typedArshalers[Coder]
102 for _, a2 := range as {
103 if a2 != nil {
104 a.fncVals = append(a.fncVals, a2.fncVals...)
105 a.fromAny = a.fromAny || a2.fromAny
106 }
107 }
108 if len(a.fncVals) == 0 {
109 return nil
110 }
111 return &a
112 }
113
114 func (a *typedArshalers[Coder]) lookup(fnc func(*Coder, addressableValue, *jsonopts.Struct) error, t reflect.Type) (func(*Coder, addressableValue, *jsonopts.Struct) error, bool) {
115 if a == nil {
116 return fnc, false
117 }
118 if v, ok := a.fncCache.Load(t); ok {
119 if v == nil {
120 return fnc, false
121 }
122 return v.(func(*Coder, addressableValue, *jsonopts.Struct) error), true
123 }
124
125
126
127 var fncs []func(*Coder, addressableValue, *jsonopts.Struct) error
128 for _, fncVal := range a.fncVals {
129 if !castableTo(t, fncVal.typ) {
130 continue
131 }
132 fncs = append(fncs, fncVal.fnc)
133 if !fncVal.maySkip {
134 break
135 }
136 }
137
138 if len(fncs) == 0 {
139 a.fncCache.Store(t, nil)
140 return fnc, false
141 }
142
143
144 fncDefault := fnc
145 fnc = func(c *Coder, v addressableValue, o *jsonopts.Struct) error {
146 for _, fnc := range fncs {
147 if err := fnc(c, v, o); !errors.Is(err, errors.ErrUnsupported) {
148 return err
149 }
150 }
151 return fncDefault(c, v, o)
152 }
153
154
155 v, _ := a.fncCache.LoadOrStore(t, fnc)
156 return v.(func(*Coder, addressableValue, *jsonopts.Struct) error), true
157 }
158
159
160
161
162
163
164
165
166
167
168 func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers {
169 t := reflect.TypeFor[T]()
170 assertCastableTo(t, true)
171 typFnc := typedMarshaler{
172 typ: t,
173 fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
174 v, _ := reflect.TypeAssert[T](va.castTo(t))
175 val, err := fn(v)
176 if err != nil {
177 err = wrapErrUnsupported(err, "marshal function of type func(T) ([]byte, error)")
178 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
179 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc")
180 }
181 err = newMarshalErrorBefore(enc, t, err)
182 return collapseSemanticErrors(err)
183 }
184 if err := enc.WriteValue(val); err != nil {
185 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
186 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc")
187 }
188 if isSyntacticError(err) {
189 err = newMarshalErrorBefore(enc, t, err)
190 }
191 return err
192 }
193 return nil
194 },
195 }
196 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)}
197 }
198
199
200
201
202
203
204
205
206
207
208
209 func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers {
210 t := reflect.TypeFor[T]()
211 assertCastableTo(t, true)
212 typFnc := typedMarshaler{
213 typ: t,
214 fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
215 xe := export.Encoder(enc)
216 prevDepth, prevLength := xe.Tokens.DepthLength()
217 xe.Flags.Set(jsonflags.WithinArshalCall | 1)
218 v, _ := reflect.TypeAssert[T](va.castTo(t))
219 err := fn(enc, v)
220 xe.Flags.Set(jsonflags.WithinArshalCall | 0)
221 currDepth, currLength := xe.Tokens.DepthLength()
222 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {
223 err = errNonSingularValue
224 }
225 if err != nil {
226 if errors.Is(err, errors.ErrUnsupported) {
227 if prevDepth == currDepth && prevLength == currLength {
228 return err
229 }
230 err = errUnsupportedMutation
231 }
232 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
233 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalToFunc")
234 }
235 if !export.IsIOError(err) {
236 err = newSemanticErrorWithPosition(enc, t, prevDepth, prevLength, err)
237 }
238 return err
239 }
240 return nil
241 },
242 maySkip: true,
243 }
244 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)}
245 }
246
247
248
249
250
251
252
253
254
255 func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers {
256 t := reflect.TypeFor[T]()
257 assertCastableTo(t, false)
258 typFnc := typedUnmarshaler{
259 typ: t,
260 fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
261 val, err := dec.ReadValue()
262 if err != nil {
263 return err
264 }
265 v, _ := reflect.TypeAssert[T](va.castTo(t))
266 err = fn(val, v)
267 if err != nil {
268 err = wrapErrUnsupported(err, "unmarshal function of type func([]byte, T) error")
269 if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
270 return err
271 }
272 err = newUnmarshalErrorAfter(dec, t, err)
273 return collapseSemanticErrors(err)
274 }
275 return nil
276 },
277 }
278 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)}
279 }
280
281
282
283
284
285
286
287
288
289
290 func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers {
291 t := reflect.TypeFor[T]()
292 assertCastableTo(t, false)
293 typFnc := typedUnmarshaler{
294 typ: t,
295 fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
296 xd := export.Decoder(dec)
297 prevDepth, prevLength := xd.Tokens.DepthLength()
298 if prevDepth == 1 && xd.AtEOF() {
299 return io.EOF
300 }
301 xd.Flags.Set(jsonflags.WithinArshalCall | 1)
302 v, _ := reflect.TypeAssert[T](va.castTo(t))
303 err := fn(dec, v)
304 xd.Flags.Set(jsonflags.WithinArshalCall | 0)
305 currDepth, currLength := xd.Tokens.DepthLength()
306 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {
307 err = errNonSingularValue
308 }
309 if err != nil {
310 if errors.Is(err, errors.ErrUnsupported) {
311 if prevDepth == currDepth && prevLength == currLength {
312 return err
313 }
314 err = errUnsupportedMutation
315 }
316 if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
317 if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil {
318 return err2
319 }
320 return err
321 }
322 if !isSyntacticError(err) && !export.IsIOError(err) {
323 err = newSemanticErrorWithPosition(dec, t, prevDepth, prevLength, err)
324 }
325 return err
326 }
327 return nil
328 },
329 maySkip: true,
330 }
331 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)}
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348 func assertCastableTo(to reflect.Type, marshal bool) {
349 switch to.Kind() {
350 case reflect.Interface:
351 return
352 case reflect.Pointer:
353
354
355 if to.Name() == "" {
356 return
357 }
358 default:
359
360
361
362 if marshal {
363 return
364 }
365 }
366 if marshal {
367 panic(fmt.Sprintf("input type %v must be an interface type, an unnamed pointer type, or a non-pointer type", to))
368 } else {
369 panic(fmt.Sprintf("input type %v must be an interface type or an unnamed pointer type", to))
370 }
371 }
372
373
374
375
376
377 func castableTo(from, to reflect.Type) bool {
378 switch to.Kind() {
379 case reflect.Interface:
380
381
382
383
384 return reflect.PointerTo(from).Implements(to)
385 case reflect.Pointer:
386
387
388 return reflect.PointerTo(from) == to
389 default:
390
391
392 return from == to
393 }
394 }
395
396
397
398
399
400
401 func (va addressableValue) castTo(to reflect.Type) reflect.Value {
402 switch to.Kind() {
403 case reflect.Interface:
404 return va.Addr().Convert(to)
405 case reflect.Pointer:
406 return va.Addr()
407 default:
408 return va.Value
409 }
410 }
411
412
413
414 func castableToFromAny(to reflect.Type) bool {
415 for _, from := range []reflect.Type{anyType, boolType, stringType, float64Type, mapStringAnyType, sliceAnyType} {
416 if castableTo(from, to) {
417 return true
418 }
419 }
420 return false
421 }
422
View as plain text