1package jsoniter
2
3import (
4	"encoding"
5	"encoding/json"
6	"fmt"
7	"reflect"
8	"time"
9	"unsafe"
10)
11
12// ValDecoder is an internal type registered to cache as needed.
13// Don't confuse jsoniter.ValDecoder with json.Decoder.
14// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
15//
16// Reflection on type to create decoders, which is then cached
17// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
18// 1. create instance of new value, for example *int will need a int to be allocated
19// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
20// 3. assignment to map, both key and value will be reflect.Value
21// For a simple struct binding, it will be reflect.Value free and allocation free
22type ValDecoder interface {
23	Decode(ptr unsafe.Pointer, iter *Iterator)
24}
25
26// ValEncoder is an internal type registered to cache as needed.
27// Don't confuse jsoniter.ValEncoder with json.Encoder.
28// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
29type ValEncoder interface {
30	IsEmpty(ptr unsafe.Pointer) bool
31	Encode(ptr unsafe.Pointer, stream *Stream)
32	EncodeInterface(val interface{}, stream *Stream)
33}
34
35type checkIsEmpty interface {
36	IsEmpty(ptr unsafe.Pointer) bool
37}
38
39// WriteToStream the default implementation for TypeEncoder method EncodeInterface
40func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
41	e := (*emptyInterface)(unsafe.Pointer(&val))
42	if e.word == nil {
43		stream.WriteNil()
44		return
45	}
46	if reflect.TypeOf(val).Kind() == reflect.Ptr {
47		encoder.Encode(unsafe.Pointer(&e.word), stream)
48	} else {
49		encoder.Encode(e.word, stream)
50	}
51}
52
53var jsonNumberType reflect.Type
54var jsoniterNumberType reflect.Type
55var jsonRawMessageType reflect.Type
56var jsoniterRawMessageType reflect.Type
57var anyType reflect.Type
58var marshalerType reflect.Type
59var unmarshalerType reflect.Type
60var textMarshalerType reflect.Type
61var textUnmarshalerType reflect.Type
62
63func init() {
64	jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
65	jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
66	jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
67	jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
68	anyType = reflect.TypeOf((*Any)(nil)).Elem()
69	marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
70	unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
71	textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
72	textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
73}
74
75type optionalDecoder struct {
76	valueType    reflect.Type
77	valueDecoder ValDecoder
78}
79
80func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
81	if iter.ReadNil() {
82		*((*unsafe.Pointer)(ptr)) = nil
83	} else {
84		if *((*unsafe.Pointer)(ptr)) == nil {
85			//pointer to null, we have to allocate memory to hold the value
86			value := reflect.New(decoder.valueType)
87			newPtr := extractInterface(value.Interface()).word
88			decoder.valueDecoder.Decode(newPtr, iter)
89			*((*uintptr)(ptr)) = uintptr(newPtr)
90		} else {
91			//reuse existing instance
92			decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
93		}
94	}
95}
96
97type deferenceDecoder struct {
98	// only to deference a pointer
99	valueType    reflect.Type
100	valueDecoder ValDecoder
101}
102
103func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
104	if *((*unsafe.Pointer)(ptr)) == nil {
105		//pointer to null, we have to allocate memory to hold the value
106		value := reflect.New(decoder.valueType)
107		newPtr := extractInterface(value.Interface()).word
108		decoder.valueDecoder.Decode(newPtr, iter)
109		*((*uintptr)(ptr)) = uintptr(newPtr)
110	} else {
111		//reuse existing instance
112		decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
113	}
114}
115
116type optionalEncoder struct {
117	valueEncoder ValEncoder
118}
119
120func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
121	if *((*unsafe.Pointer)(ptr)) == nil {
122		stream.WriteNil()
123	} else {
124		encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
125	}
126}
127
128func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
129	WriteToStream(val, stream, encoder)
130}
131
132func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
133	if *((*unsafe.Pointer)(ptr)) == nil {
134		return true
135	}
136	return false
137}
138
139type placeholderEncoder struct {
140	cfg      *frozenConfig
141	cacheKey reflect.Type
142}
143
144func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
145	encoder.getRealEncoder().Encode(ptr, stream)
146}
147
148func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) {
149	WriteToStream(val, stream, encoder)
150}
151
152func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
153	return encoder.getRealEncoder().IsEmpty(ptr)
154}
155
156func (encoder *placeholderEncoder) getRealEncoder() ValEncoder {
157	for i := 0; i < 30; i++ {
158		realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey)
159		_, isPlaceholder := realDecoder.(*placeholderEncoder)
160		if isPlaceholder {
161			time.Sleep(time.Second)
162		} else {
163			return realDecoder
164		}
165	}
166	panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey))
167}
168
169type placeholderDecoder struct {
170	cfg      *frozenConfig
171	cacheKey reflect.Type
172}
173
174func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
175	for i := 0; i < 30; i++ {
176		realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey)
177		_, isPlaceholder := realDecoder.(*placeholderDecoder)
178		if isPlaceholder {
179			time.Sleep(time.Second)
180		} else {
181			realDecoder.Decode(ptr, iter)
182			return
183		}
184	}
185	panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey))
186}
187
188// emptyInterface is the header for an interface{} value.
189type emptyInterface struct {
190	typ  unsafe.Pointer
191	word unsafe.Pointer
192}
193
194// emptyInterface is the header for an interface with method (not interface{})
195type nonEmptyInterface struct {
196	// see ../runtime/iface.go:/Itab
197	itab *struct {
198		ityp   unsafe.Pointer // static interface type
199		typ    unsafe.Pointer // dynamic concrete type
200		link   unsafe.Pointer
201		bad    int32
202		unused int32
203		fun    [100000]unsafe.Pointer // method table
204	}
205	word unsafe.Pointer
206}
207
208// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
209func (iter *Iterator) ReadVal(obj interface{}) {
210	typ := reflect.TypeOf(obj)
211	cacheKey := typ.Elem()
212	decoder, err := decoderOfType(iter.cfg, cacheKey)
213	if err != nil {
214		iter.Error = err
215		return
216	}
217	e := (*emptyInterface)(unsafe.Pointer(&obj))
218	decoder.Decode(e.word, iter)
219}
220
221// WriteVal copy the go interface into underlying JSON, same as json.Marshal
222func (stream *Stream) WriteVal(val interface{}) {
223	if nil == val {
224		stream.WriteNil()
225		return
226	}
227	typ := reflect.TypeOf(val)
228	cacheKey := typ
229	encoder, err := encoderOfType(stream.cfg, cacheKey)
230	if err != nil {
231		stream.Error = err
232		return
233	}
234	encoder.EncodeInterface(val, stream)
235}
236
237type prefix string
238
239func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) {
240	if err != nil {
241		return nil, fmt.Errorf("%s: %s", p, err.Error())
242	}
243	return decoder, err
244}
245
246func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) {
247	if err != nil {
248		return nil, fmt.Errorf("%s: %s", p, err.Error())
249	}
250	return encoder, err
251}
252
253func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
254	cacheKey := typ
255	decoder := cfg.getDecoderFromCache(cacheKey)
256	if decoder != nil {
257		return decoder, nil
258	}
259	decoder = getTypeDecoderFromExtension(typ)
260	if decoder != nil {
261		cfg.addDecoderToCache(cacheKey, decoder)
262		return decoder, nil
263	}
264	decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
265	cfg.addDecoderToCache(cacheKey, decoder)
266	decoder, err := createDecoderOfType(cfg, typ)
267	for _, extension := range extensions {
268		decoder = extension.DecorateDecoder(typ, decoder)
269	}
270	cfg.addDecoderToCache(cacheKey, decoder)
271	return decoder, err
272}
273
274func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
275	typeName := typ.String()
276	if typ == jsonRawMessageType {
277		return &jsonRawMessageCodec{}, nil
278	}
279	if typ == jsoniterRawMessageType {
280		return &jsoniterRawMessageCodec{}, nil
281	}
282	if typ.AssignableTo(jsonNumberType) {
283		return &jsonNumberCodec{}, nil
284	}
285	if typ.AssignableTo(jsoniterNumberType) {
286		return &jsoniterNumberCodec{}, nil
287	}
288	if typ.Implements(unmarshalerType) {
289		templateInterface := reflect.New(typ).Elem().Interface()
290		var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
291		if typ.Kind() == reflect.Ptr {
292			decoder = &optionalDecoder{typ.Elem(), decoder}
293		}
294		return decoder, nil
295	}
296	if reflect.PtrTo(typ).Implements(unmarshalerType) {
297		templateInterface := reflect.New(typ).Interface()
298		var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
299		return decoder, nil
300	}
301	if typ.Implements(textUnmarshalerType) {
302		templateInterface := reflect.New(typ).Elem().Interface()
303		var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
304		if typ.Kind() == reflect.Ptr {
305			decoder = &optionalDecoder{typ.Elem(), decoder}
306		}
307		return decoder, nil
308	}
309	if reflect.PtrTo(typ).Implements(textUnmarshalerType) {
310		templateInterface := reflect.New(typ).Interface()
311		var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
312		return decoder, nil
313	}
314	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
315		sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
316		if err != nil {
317			return nil, err
318		}
319		return &base64Codec{sliceDecoder: sliceDecoder}, nil
320	}
321	if typ.Implements(anyType) {
322		return &anyCodec{}, nil
323	}
324	switch typ.Kind() {
325	case reflect.String:
326		if typeName != "string" {
327			return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
328		}
329		return &stringCodec{}, nil
330	case reflect.Int:
331		if typeName != "int" {
332			return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
333		}
334		return &intCodec{}, nil
335	case reflect.Int8:
336		if typeName != "int8" {
337			return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
338		}
339		return &int8Codec{}, nil
340	case reflect.Int16:
341		if typeName != "int16" {
342			return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
343		}
344		return &int16Codec{}, nil
345	case reflect.Int32:
346		if typeName != "int32" {
347			return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
348		}
349		return &int32Codec{}, nil
350	case reflect.Int64:
351		if typeName != "int64" {
352			return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
353		}
354		return &int64Codec{}, nil
355	case reflect.Uint:
356		if typeName != "uint" {
357			return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
358		}
359		return &uintCodec{}, nil
360	case reflect.Uint8:
361		if typeName != "uint8" {
362			return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
363		}
364		return &uint8Codec{}, nil
365	case reflect.Uint16:
366		if typeName != "uint16" {
367			return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
368		}
369		return &uint16Codec{}, nil
370	case reflect.Uint32:
371		if typeName != "uint32" {
372			return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
373		}
374		return &uint32Codec{}, nil
375	case reflect.Uintptr:
376		if typeName != "uintptr" {
377			return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
378		}
379		return &uintptrCodec{}, nil
380	case reflect.Uint64:
381		if typeName != "uint64" {
382			return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
383		}
384		return &uint64Codec{}, nil
385	case reflect.Float32:
386		if typeName != "float32" {
387			return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
388		}
389		return &float32Codec{}, nil
390	case reflect.Float64:
391		if typeName != "float64" {
392			return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
393		}
394		return &float64Codec{}, nil
395	case reflect.Bool:
396		if typeName != "bool" {
397			return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
398		}
399		return &boolCodec{}, nil
400	case reflect.Interface:
401		if typ.NumMethod() == 0 {
402			return &emptyInterfaceCodec{}, nil
403		}
404		return &nonEmptyInterfaceCodec{}, nil
405	case reflect.Struct:
406		return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ))
407	case reflect.Array:
408		return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ))
409	case reflect.Slice:
410		return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
411	case reflect.Map:
412		return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ))
413	case reflect.Ptr:
414		return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ))
415	default:
416		return nil, fmt.Errorf("unsupported type: %v", typ)
417	}
418}
419
420func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
421	cacheKey := typ
422	encoder := cfg.getEncoderFromCache(cacheKey)
423	if encoder != nil {
424		return encoder, nil
425	}
426	encoder = getTypeEncoderFromExtension(typ)
427	if encoder != nil {
428		cfg.addEncoderToCache(cacheKey, encoder)
429		return encoder, nil
430	}
431	encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
432	cfg.addEncoderToCache(cacheKey, encoder)
433	encoder, err := createEncoderOfType(cfg, typ)
434	for _, extension := range extensions {
435		encoder = extension.DecorateEncoder(typ, encoder)
436	}
437	cfg.addEncoderToCache(cacheKey, encoder)
438	return encoder, err
439}
440
441func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
442	if typ == jsonRawMessageType {
443		return &jsonRawMessageCodec{}, nil
444	}
445	if typ == jsoniterRawMessageType {
446		return &jsoniterRawMessageCodec{}, nil
447	}
448	if typ.AssignableTo(jsonNumberType) {
449		return &jsonNumberCodec{}, nil
450	}
451	if typ.AssignableTo(jsoniterNumberType) {
452		return &jsoniterNumberCodec{}, nil
453	}
454	if typ.Implements(marshalerType) {
455		checkIsEmpty, err := createCheckIsEmpty(typ)
456		if err != nil {
457			return nil, err
458		}
459		templateInterface := reflect.New(typ).Elem().Interface()
460		var encoder ValEncoder = &marshalerEncoder{
461			templateInterface: extractInterface(templateInterface),
462			checkIsEmpty:      checkIsEmpty,
463		}
464		if typ.Kind() == reflect.Ptr {
465			encoder = &optionalEncoder{encoder}
466		}
467		return encoder, nil
468	}
469	if typ.Implements(textMarshalerType) {
470		checkIsEmpty, err := createCheckIsEmpty(typ)
471		if err != nil {
472			return nil, err
473		}
474		templateInterface := reflect.New(typ).Elem().Interface()
475		var encoder ValEncoder = &textMarshalerEncoder{
476			templateInterface: extractInterface(templateInterface),
477			checkIsEmpty:      checkIsEmpty,
478		}
479		if typ.Kind() == reflect.Ptr {
480			encoder = &optionalEncoder{encoder}
481		}
482		return encoder, nil
483	}
484	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
485		return &base64Codec{}, nil
486	}
487	if typ.Implements(anyType) {
488		return &anyCodec{}, nil
489	}
490	return createEncoderOfSimpleType(cfg, typ)
491}
492
493func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) {
494	kind := typ.Kind()
495	switch kind {
496	case reflect.String:
497		return &stringCodec{}, nil
498	case reflect.Int:
499		return &intCodec{}, nil
500	case reflect.Int8:
501		return &int8Codec{}, nil
502	case reflect.Int16:
503		return &int16Codec{}, nil
504	case reflect.Int32:
505		return &int32Codec{}, nil
506	case reflect.Int64:
507		return &int64Codec{}, nil
508	case reflect.Uint:
509		return &uintCodec{}, nil
510	case reflect.Uint8:
511		return &uint8Codec{}, nil
512	case reflect.Uint16:
513		return &uint16Codec{}, nil
514	case reflect.Uint32:
515		return &uint32Codec{}, nil
516	case reflect.Uintptr:
517		return &uintptrCodec{}, nil
518	case reflect.Uint64:
519		return &uint64Codec{}, nil
520	case reflect.Float32:
521		return &float32Codec{}, nil
522	case reflect.Float64:
523		return &float64Codec{}, nil
524	case reflect.Bool:
525		return &boolCodec{}, nil
526	case reflect.Interface:
527		if typ.NumMethod() == 0 {
528			return &emptyInterfaceCodec{}, nil
529		}
530		return &nonEmptyInterfaceCodec{}, nil
531	case reflect.Struct:
532		return &structEncoder{}, nil
533	case reflect.Array:
534		return &arrayEncoder{}, nil
535	case reflect.Slice:
536		return &sliceEncoder{}, nil
537	case reflect.Map:
538		return &mapEncoder{}, nil
539	case reflect.Ptr:
540		return &optionalEncoder{}, nil
541	default:
542		return nil, fmt.Errorf("unsupported type: %v", typ)
543	}
544}
545
546func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
547	typeName := typ.String()
548	kind := typ.Kind()
549	switch kind {
550	case reflect.String:
551		if typeName != "string" {
552			return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
553		}
554		return &stringCodec{}, nil
555	case reflect.Int:
556		if typeName != "int" {
557			return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
558		}
559		return &intCodec{}, nil
560	case reflect.Int8:
561		if typeName != "int8" {
562			return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
563		}
564		return &int8Codec{}, nil
565	case reflect.Int16:
566		if typeName != "int16" {
567			return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
568		}
569		return &int16Codec{}, nil
570	case reflect.Int32:
571		if typeName != "int32" {
572			return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
573		}
574		return &int32Codec{}, nil
575	case reflect.Int64:
576		if typeName != "int64" {
577			return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
578		}
579		return &int64Codec{}, nil
580	case reflect.Uint:
581		if typeName != "uint" {
582			return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
583		}
584		return &uintCodec{}, nil
585	case reflect.Uint8:
586		if typeName != "uint8" {
587			return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
588		}
589		return &uint8Codec{}, nil
590	case reflect.Uint16:
591		if typeName != "uint16" {
592			return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
593		}
594		return &uint16Codec{}, nil
595	case reflect.Uint32:
596		if typeName != "uint32" {
597			return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
598		}
599		return &uint32Codec{}, nil
600	case reflect.Uintptr:
601		if typeName != "uintptr" {
602			return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
603		}
604		return &uintptrCodec{}, nil
605	case reflect.Uint64:
606		if typeName != "uint64" {
607			return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
608		}
609		return &uint64Codec{}, nil
610	case reflect.Float32:
611		if typeName != "float32" {
612			return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
613		}
614		return &float32Codec{}, nil
615	case reflect.Float64:
616		if typeName != "float64" {
617			return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
618		}
619		return &float64Codec{}, nil
620	case reflect.Bool:
621		if typeName != "bool" {
622			return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
623		}
624		return &boolCodec{}, nil
625	case reflect.Interface:
626		if typ.NumMethod() == 0 {
627			return &emptyInterfaceCodec{}, nil
628		}
629		return &nonEmptyInterfaceCodec{}, nil
630	case reflect.Struct:
631		return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ))
632	case reflect.Array:
633		return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ))
634	case reflect.Slice:
635		return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ))
636	case reflect.Map:
637		return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ))
638	case reflect.Ptr:
639		return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ))
640	default:
641		return nil, fmt.Errorf("unsupported type: %v", typ)
642	}
643}
644
645func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
646	elemType := typ.Elem()
647	decoder, err := decoderOfType(cfg, elemType)
648	if err != nil {
649		return nil, err
650	}
651	return &optionalDecoder{elemType, decoder}, nil
652}
653
654func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
655	elemType := typ.Elem()
656	elemEncoder, err := encoderOfType(cfg, elemType)
657	if err != nil {
658		return nil, err
659	}
660	encoder := &optionalEncoder{elemEncoder}
661	if elemType.Kind() == reflect.Map {
662		encoder = &optionalEncoder{encoder}
663	}
664	return encoder, nil
665}
666
667func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
668	decoder, err := decoderOfType(cfg, typ.Elem())
669	if err != nil {
670		return nil, err
671	}
672	mapInterface := reflect.New(typ).Interface()
673	return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil
674}
675
676func extractInterface(val interface{}) emptyInterface {
677	return *((*emptyInterface)(unsafe.Pointer(&val)))
678}
679
680func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
681	elemType := typ.Elem()
682	encoder, err := encoderOfType(cfg, elemType)
683	if err != nil {
684		return nil, err
685	}
686	mapInterface := reflect.New(typ).Elem().Interface()
687	if cfg.sortMapKeys {
688		return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
689	}
690	return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
691}
692