1package decoder
2
3import (
4	"encoding/json"
5	"fmt"
6	"reflect"
7	"strings"
8	"sync/atomic"
9	"unicode"
10	"unsafe"
11
12	"github.com/goccy/go-json/internal/errors"
13	"github.com/goccy/go-json/internal/runtime"
14)
15
16var (
17	jsonNumberType   = reflect.TypeOf(json.Number(""))
18	typeAddr         *runtime.TypeAddr
19	cachedDecoderMap unsafe.Pointer // map[uintptr]decoder
20	cachedDecoder    []Decoder
21)
22
23func init() {
24	typeAddr = runtime.AnalyzeTypeAddr()
25	if typeAddr == nil {
26		typeAddr = &runtime.TypeAddr{}
27	}
28	cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift)
29}
30
31func loadDecoderMap() map[uintptr]Decoder {
32	p := atomic.LoadPointer(&cachedDecoderMap)
33	return *(*map[uintptr]Decoder)(unsafe.Pointer(&p))
34}
35
36func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) {
37	newDecoderMap := make(map[uintptr]Decoder, len(m)+1)
38	newDecoderMap[typ] = dec
39
40	for k, v := range m {
41		newDecoderMap[k] = v
42	}
43
44	atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap)))
45}
46
47func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) {
48	decoderMap := loadDecoderMap()
49	if dec, exists := decoderMap[typeptr]; exists {
50		return dec, nil
51	}
52
53	dec, err := compileHead(typ, map[uintptr]Decoder{})
54	if err != nil {
55		return nil, err
56	}
57	storeDecoder(typeptr, dec, decoderMap)
58	return dec, nil
59}
60
61func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
62	switch {
63	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
64		return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil
65	case runtime.PtrTo(typ).Implements(unmarshalTextType):
66		return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil
67	}
68	return compile(typ.Elem(), "", "", structTypeToDecoder)
69}
70
71func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
72	switch {
73	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
74		return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil
75	case runtime.PtrTo(typ).Implements(unmarshalTextType):
76		return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
77	}
78
79	switch typ.Kind() {
80	case reflect.Ptr:
81		return compilePtr(typ, structName, fieldName, structTypeToDecoder)
82	case reflect.Struct:
83		return compileStruct(typ, structName, fieldName, structTypeToDecoder)
84	case reflect.Slice:
85		elem := typ.Elem()
86		if elem.Kind() == reflect.Uint8 {
87			return compileBytes(elem, structName, fieldName)
88		}
89		return compileSlice(typ, structName, fieldName, structTypeToDecoder)
90	case reflect.Array:
91		return compileArray(typ, structName, fieldName, structTypeToDecoder)
92	case reflect.Map:
93		return compileMap(typ, structName, fieldName, structTypeToDecoder)
94	case reflect.Interface:
95		return compileInterface(typ, structName, fieldName)
96	case reflect.Uintptr:
97		return compileUint(typ, structName, fieldName)
98	case reflect.Int:
99		return compileInt(typ, structName, fieldName)
100	case reflect.Int8:
101		return compileInt8(typ, structName, fieldName)
102	case reflect.Int16:
103		return compileInt16(typ, structName, fieldName)
104	case reflect.Int32:
105		return compileInt32(typ, structName, fieldName)
106	case reflect.Int64:
107		return compileInt64(typ, structName, fieldName)
108	case reflect.Uint:
109		return compileUint(typ, structName, fieldName)
110	case reflect.Uint8:
111		return compileUint8(typ, structName, fieldName)
112	case reflect.Uint16:
113		return compileUint16(typ, structName, fieldName)
114	case reflect.Uint32:
115		return compileUint32(typ, structName, fieldName)
116	case reflect.Uint64:
117		return compileUint64(typ, structName, fieldName)
118	case reflect.String:
119		return compileString(typ, structName, fieldName)
120	case reflect.Bool:
121		return compileBool(structName, fieldName)
122	case reflect.Float32:
123		return compileFloat32(structName, fieldName)
124	case reflect.Float64:
125		return compileFloat64(structName, fieldName)
126	case reflect.Func:
127		return compileFunc(typ, structName, fieldName)
128	}
129	return nil, &errors.UnmarshalTypeError{
130		Value:  "object",
131		Type:   runtime.RType2Type(typ),
132		Offset: 0,
133		Struct: structName,
134		Field:  fieldName,
135	}
136}
137
138func isStringTagSupportedType(typ *runtime.Type) bool {
139	switch {
140	case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
141		return false
142	case runtime.PtrTo(typ).Implements(unmarshalTextType):
143		return false
144	}
145	switch typ.Kind() {
146	case reflect.Map:
147		return false
148	case reflect.Slice:
149		return false
150	case reflect.Array:
151		return false
152	case reflect.Struct:
153		return false
154	case reflect.Interface:
155		return false
156	}
157	return true
158}
159
160func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
161	if runtime.PtrTo(typ).Implements(unmarshalTextType) {
162		return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
163	}
164	dec, err := compile(typ, structName, fieldName, structTypeToDecoder)
165	if err != nil {
166		return nil, err
167	}
168	for {
169		switch t := dec.(type) {
170		case *stringDecoder, *interfaceDecoder:
171			return dec, nil
172		case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder:
173			return newWrappedStringDecoder(typ, dec, structName, fieldName), nil
174		case *ptrDecoder:
175			dec = t.dec
176		default:
177			goto ERROR
178		}
179	}
180ERROR:
181	return nil, &errors.UnmarshalTypeError{
182		Value:  "object",
183		Type:   runtime.RType2Type(typ),
184		Offset: 0,
185		Struct: structName,
186		Field:  fieldName,
187	}
188}
189
190func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
191	dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
192	if err != nil {
193		return nil, err
194	}
195	return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil
196}
197
198func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
199	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
200		*(*int)(p) = int(v)
201	}), nil
202}
203
204func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
205	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
206		*(*int8)(p) = int8(v)
207	}), nil
208}
209
210func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
211	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
212		*(*int16)(p) = int16(v)
213	}), nil
214}
215
216func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
217	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
218		*(*int32)(p) = int32(v)
219	}), nil
220}
221
222func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
223	return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
224		*(*int64)(p) = v
225	}), nil
226}
227
228func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
229	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
230		*(*uint)(p) = uint(v)
231	}), nil
232}
233
234func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
235	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
236		*(*uint8)(p) = uint8(v)
237	}), nil
238}
239
240func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
241	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
242		*(*uint16)(p) = uint16(v)
243	}), nil
244}
245
246func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
247	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
248		*(*uint32)(p) = uint32(v)
249	}), nil
250}
251
252func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
253	return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
254		*(*uint64)(p) = v
255	}), nil
256}
257
258func compileFloat32(structName, fieldName string) (Decoder, error) {
259	return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
260		*(*float32)(p) = float32(v)
261	}), nil
262}
263
264func compileFloat64(structName, fieldName string) (Decoder, error) {
265	return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
266		*(*float64)(p) = v
267	}), nil
268}
269
270func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
271	if typ == runtime.Type2RType(jsonNumberType) {
272		return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
273			*(*json.Number)(p) = v
274		}), nil
275	}
276	return newStringDecoder(structName, fieldName), nil
277}
278
279func compileBool(structName, fieldName string) (Decoder, error) {
280	return newBoolDecoder(structName, fieldName), nil
281}
282
283func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
284	return newBytesDecoder(typ, structName, fieldName), nil
285}
286
287func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
288	elem := typ.Elem()
289	decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
290	if err != nil {
291		return nil, err
292	}
293	return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil
294}
295
296func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
297	elem := typ.Elem()
298	decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
299	if err != nil {
300		return nil, err
301	}
302	return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil
303}
304
305func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
306	keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder)
307	if err != nil {
308		return nil, err
309	}
310	valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
311	if err != nil {
312		return nil, err
313	}
314	return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil
315}
316
317func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
318	return newInterfaceDecoder(typ, structName, fieldName), nil
319}
320
321func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) {
322	return newFuncDecoder(typ, strutName, fieldName), nil
323}
324
325func removeConflictFields(fieldMap map[string]*structFieldSet, conflictedMap map[string]struct{}, dec *structDecoder, field reflect.StructField) {
326	for k, v := range dec.fieldMap {
327		if _, exists := conflictedMap[k]; exists {
328			// already conflicted key
329			continue
330		}
331		set, exists := fieldMap[k]
332		if !exists {
333			fieldSet := &structFieldSet{
334				dec:         v.dec,
335				offset:      field.Offset + v.offset,
336				isTaggedKey: v.isTaggedKey,
337				key:         k,
338				keyLen:      int64(len(k)),
339			}
340			fieldMap[k] = fieldSet
341			lower := strings.ToLower(k)
342			if _, exists := fieldMap[lower]; !exists {
343				fieldMap[lower] = fieldSet
344			}
345			continue
346		}
347		if set.isTaggedKey {
348			if v.isTaggedKey {
349				// conflict tag key
350				delete(fieldMap, k)
351				delete(fieldMap, strings.ToLower(k))
352				conflictedMap[k] = struct{}{}
353				conflictedMap[strings.ToLower(k)] = struct{}{}
354			}
355		} else {
356			if v.isTaggedKey {
357				fieldSet := &structFieldSet{
358					dec:         v.dec,
359					offset:      field.Offset + v.offset,
360					isTaggedKey: v.isTaggedKey,
361					key:         k,
362					keyLen:      int64(len(k)),
363				}
364				fieldMap[k] = fieldSet
365				lower := strings.ToLower(k)
366				if _, exists := fieldMap[lower]; !exists {
367					fieldMap[lower] = fieldSet
368				}
369			} else {
370				// conflict tag key
371				delete(fieldMap, k)
372				delete(fieldMap, strings.ToLower(k))
373				conflictedMap[k] = struct{}{}
374				conflictedMap[strings.ToLower(k)] = struct{}{}
375			}
376		}
377	}
378}
379
380func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
381	fieldNum := typ.NumField()
382	conflictedMap := map[string]struct{}{}
383	fieldMap := map[string]*structFieldSet{}
384	typeptr := uintptr(unsafe.Pointer(typ))
385	if dec, exists := structTypeToDecoder[typeptr]; exists {
386		return dec, nil
387	}
388	structDec := newStructDecoder(structName, fieldName, fieldMap)
389	structTypeToDecoder[typeptr] = structDec
390	structName = typ.Name()
391	for i := 0; i < fieldNum; i++ {
392		field := typ.Field(i)
393		if runtime.IsIgnoredStructField(field) {
394			continue
395		}
396		isUnexportedField := unicode.IsLower([]rune(field.Name)[0])
397		tag := runtime.StructTagFromField(field)
398		dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder)
399		if err != nil {
400			return nil, err
401		}
402		if field.Anonymous && !tag.IsTaggedKey {
403			if stDec, ok := dec.(*structDecoder); ok {
404				if runtime.Type2RType(field.Type) == typ {
405					// recursive definition
406					continue
407				}
408				removeConflictFields(fieldMap, conflictedMap, stDec, field)
409			} else if pdec, ok := dec.(*ptrDecoder); ok {
410				contentDec := pdec.contentDecoder()
411				if pdec.typ == typ {
412					// recursive definition
413					continue
414				}
415				var fieldSetErr error
416				if isUnexportedField {
417					fieldSetErr = fmt.Errorf(
418						"json: cannot set embedded pointer to unexported struct: %v",
419						field.Type.Elem(),
420					)
421				}
422				if dec, ok := contentDec.(*structDecoder); ok {
423					for k, v := range dec.fieldMap {
424						if _, exists := conflictedMap[k]; exists {
425							// already conflicted key
426							continue
427						}
428						set, exists := fieldMap[k]
429						if !exists {
430							fieldSet := &structFieldSet{
431								dec:         newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
432								offset:      field.Offset,
433								isTaggedKey: v.isTaggedKey,
434								key:         k,
435								keyLen:      int64(len(k)),
436								err:         fieldSetErr,
437							}
438							fieldMap[k] = fieldSet
439							lower := strings.ToLower(k)
440							if _, exists := fieldMap[lower]; !exists {
441								fieldMap[lower] = fieldSet
442							}
443							continue
444						}
445						if set.isTaggedKey {
446							if v.isTaggedKey {
447								// conflict tag key
448								delete(fieldMap, k)
449								delete(fieldMap, strings.ToLower(k))
450								conflictedMap[k] = struct{}{}
451								conflictedMap[strings.ToLower(k)] = struct{}{}
452							}
453						} else {
454							if v.isTaggedKey {
455								fieldSet := &structFieldSet{
456									dec:         newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
457									offset:      field.Offset,
458									isTaggedKey: v.isTaggedKey,
459									key:         k,
460									keyLen:      int64(len(k)),
461									err:         fieldSetErr,
462								}
463								fieldMap[k] = fieldSet
464								lower := strings.ToLower(k)
465								if _, exists := fieldMap[lower]; !exists {
466									fieldMap[lower] = fieldSet
467								}
468							} else {
469								// conflict tag key
470								delete(fieldMap, k)
471								delete(fieldMap, strings.ToLower(k))
472								conflictedMap[k] = struct{}{}
473								conflictedMap[strings.ToLower(k)] = struct{}{}
474							}
475						}
476					}
477				}
478			}
479		} else {
480			if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) {
481				dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name)
482			}
483			var key string
484			if tag.Key != "" {
485				key = tag.Key
486			} else {
487				key = field.Name
488			}
489			fieldSet := &structFieldSet{
490				dec:         dec,
491				offset:      field.Offset,
492				isTaggedKey: tag.IsTaggedKey,
493				key:         key,
494				keyLen:      int64(len(key)),
495			}
496			fieldMap[key] = fieldSet
497			lower := strings.ToLower(key)
498			if _, exists := fieldMap[lower]; !exists {
499				fieldMap[lower] = fieldSet
500			}
501		}
502	}
503	delete(structTypeToDecoder, typeptr)
504	structDec.tryOptimize()
505	return structDec, nil
506}
507
508func implementsUnmarshalJSONType(typ *runtime.Type) bool {
509	return typ.Implements(unmarshalJSONType) || typ.Implements(unmarshalJSONContextType)
510}
511