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
169
170 func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers {
171 t := reflect.TypeFor[T]()
172 assertCastableTo(t, true)
173 typFnc := typedMarshaler{
174 typ: t,
175 fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
176 v, _ := reflect.TypeAssert[T](va.castTo(t))
177 val, err := fn(v)
178 if err != nil {
179 err = wrapErrUnsupported(err, "marshal function of type func(T) ([]byte, error)")
180 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
181 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc")
182 }
183 err = newMarshalErrorBefore(enc, t, err)
184 return collapseSemanticErrors(err)
185 }
186 if err := enc.WriteValue(val); err != nil {
187 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
188 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc")
189 }
190 if isSyntacticError(err) {
191 err = newMarshalErrorBefore(enc, t, err)
192 }
193 return err
194 }
195 return nil
196 },
197 }
198 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)}
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213 func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers {
214 t := reflect.TypeFor[T]()
215 assertCastableTo(t, true)
216 typFnc := typedMarshaler{
217 typ: t,
218 fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
219 xe := export.Encoder(enc)
220 prevDepth, prevLength := xe.Tokens.DepthLength()
221 xe.Flags.Set(jsonflags.WithinArshalCall | 1)
222 v, _ := reflect.TypeAssert[T](va.castTo(t))
223 err := fn(enc, v)
224 xe.Flags.Set(jsonflags.WithinArshalCall | 0)
225 currDepth, currLength := xe.Tokens.DepthLength()
226 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {
227 err = errNonSingularValue
228 }
229 if err != nil {
230 if errors.Is(err, errors.ErrUnsupported) {
231 if prevDepth == currDepth && prevLength == currLength {
232 return err
233 }
234 err = errUnsupportedMutation
235 }
236 if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
237 return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalToFunc")
238 }
239 if !export.IsIOError(err) {
240 err = newSemanticErrorWithPosition(enc, t, prevDepth, prevLength, err)
241 }
242 return err
243 }
244 return nil
245 },
246 maySkip: true,
247 }
248 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)}
249 }
250
251
252
253
254
255
256
257
258
259
260 func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers {
261 t := reflect.TypeFor[T]()
262 assertCastableTo(t, false)
263 typFnc := typedUnmarshaler{
264 typ: t,
265 fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
266 val, err := dec.ReadValue()
267 if err != nil {
268 return err
269 }
270 v, _ := reflect.TypeAssert[T](va.castTo(t))
271 err = fn(val, v)
272 if err != nil {
273 err = wrapErrUnsupported(err, "unmarshal function of type func([]byte, T) error")
274 if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
275 return err
276 }
277 err = newUnmarshalErrorAfter(dec, t, err)
278 return collapseSemanticErrors(err)
279 }
280 return nil
281 },
282 }
283 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)}
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297 func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers {
298 t := reflect.TypeFor[T]()
299 assertCastableTo(t, false)
300 typFnc := typedUnmarshaler{
301 typ: t,
302 fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
303 xd := export.Decoder(dec)
304 prevDepth, prevLength := xd.Tokens.DepthLength()
305 if prevDepth == 1 && xd.AtEOF() {
306 return io.EOF
307 }
308 xd.Flags.Set(jsonflags.WithinArshalCall | 1)
309 v, _ := reflect.TypeAssert[T](va.castTo(t))
310 err := fn(dec, v)
311 xd.Flags.Set(jsonflags.WithinArshalCall | 0)
312 currDepth, currLength := xd.Tokens.DepthLength()
313 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {
314 err = errNonSingularValue
315 }
316 if err != nil {
317 if errors.Is(err, errors.ErrUnsupported) {
318 if prevDepth == currDepth && prevLength == currLength {
319 return err
320 }
321 err = errUnsupportedMutation
322 }
323 if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
324 if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil {
325 return err2
326 }
327 return err
328 }
329 if !isSyntacticError(err) && !export.IsIOError(err) {
330 err = newSemanticErrorWithPosition(dec, t, prevDepth, prevLength, err)
331 }
332 return err
333 }
334 return nil
335 },
336 maySkip: true,
337 }
338 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)}
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 func assertCastableTo(to reflect.Type, marshal bool) {
356 switch to.Kind() {
357 case reflect.Interface:
358 return
359 case reflect.Pointer:
360
361
362 if to.Name() == "" {
363 return
364 }
365 default:
366
367
368
369 if marshal {
370 return
371 }
372 }
373 if marshal {
374 panic(fmt.Sprintf("input type %v must be an interface type, an unnamed pointer type, or a non-pointer type", to))
375 } else {
376 panic(fmt.Sprintf("input type %v must be an interface type or an unnamed pointer type", to))
377 }
378 }
379
380
381
382
383
384 func castableTo(from, to reflect.Type) bool {
385 switch to.Kind() {
386 case reflect.Interface:
387
388
389
390
391 return reflect.PointerTo(from).Implements(to)
392 case reflect.Pointer:
393
394
395 return reflect.PointerTo(from) == to
396 default:
397
398
399 return from == to
400 }
401 }
402
403
404
405
406
407
408 func (va addressableValue) castTo(to reflect.Type) reflect.Value {
409 switch to.Kind() {
410 case reflect.Interface:
411 return va.Addr().Convert(to)
412 case reflect.Pointer:
413 return va.Addr()
414 default:
415 return va.Value
416 }
417 }
418
419
420
421 func castableToFromAny(to reflect.Type) bool {
422 for _, from := range []reflect.Type{anyType, boolType, stringType, float64Type, mapStringAnyType, sliceAnyType} {
423 if castableTo(from, to) {
424 return true
425 }
426 }
427 return false
428 }
429
View as plain text