1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-27 08:30:57 +02:00
json-iterator/feature_reflect.go

499 lines
13 KiB
Go
Raw Normal View History

2016-12-04 05:06:38 +02:00
package jsoniter
import (
2016-12-04 06:27:34 +02:00
"fmt"
"reflect"
"sync/atomic"
"unsafe"
2017-01-25 17:25:25 +02:00
"errors"
2017-05-24 08:34:00 +02:00
"encoding/json"
2016-12-04 05:06:38 +02:00
)
/*
Reflection on type to create decoders, which is then cached
Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
1. create instance of new value, for example *int will need a int to be allocated
2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
3. assignment to map, both key and value will be reflect.Value
For a simple struct binding, it will be reflect.Value free and allocation free
*/
2016-12-04 05:06:38 +02:00
type Decoder interface {
2016-12-04 06:27:34 +02:00
decode(ptr unsafe.Pointer, iter *Iterator)
2016-12-04 05:06:38 +02:00
}
2017-01-25 18:25:17 +02:00
2017-01-09 11:47:21 +02:00
type Encoder interface {
2017-03-08 17:38:25 +02:00
isEmpty(ptr unsafe.Pointer) bool
2017-01-09 11:47:21 +02:00
encode(ptr unsafe.Pointer, stream *Stream)
2017-01-25 18:25:17 +02:00
encodeInterface(val interface{}, stream *Stream)
}
func writeToStream(val interface{}, stream *Stream, encoder Encoder) {
2017-01-25 18:25:17 +02:00
e := (*emptyInterface)(unsafe.Pointer(&val))
if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.encode(unsafe.Pointer(&e.word), stream)
} else {
encoder.encode(e.word, stream)
}
2017-01-09 11:47:21 +02:00
}
2016-12-04 05:06:38 +02:00
2017-01-07 01:49:50 +02:00
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
2017-01-25 16:43:57 +02:00
type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
type ExtensionFunc func(typ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc)
2016-12-04 14:50:55 +02:00
2017-01-07 01:49:50 +02:00
type funcDecoder struct {
fun DecoderFunc
2016-12-04 14:50:55 +02:00
}
2017-01-07 01:49:50 +02:00
func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.fun(ptr, iter)
2016-12-07 02:49:52 +02:00
}
2017-01-25 16:43:57 +02:00
type funcEncoder struct {
fun EncoderFunc
}
func (encoder *funcEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
encoder.fun(ptr, stream)
}
2017-01-25 18:25:17 +02:00
func (encoder *funcEncoder) encodeInterface(val interface{}, stream *Stream) {
writeToStream(val, stream, encoder)
2017-01-25 18:25:17 +02:00
}
2017-03-08 17:38:25 +02:00
func (encoder *funcEncoder) isEmpty(ptr unsafe.Pointer) bool {
return false
}
2017-01-07 01:49:50 +02:00
var DECODERS unsafe.Pointer
2017-01-09 11:47:21 +02:00
var ENCODERS unsafe.Pointer
2016-12-04 14:50:55 +02:00
2017-01-07 01:49:50 +02:00
var typeDecoders map[string]Decoder
var fieldDecoders map[string]Decoder
2017-01-25 16:43:57 +02:00
var typeEncoders map[string]Encoder
var fieldEncoders map[string]Encoder
2017-01-07 01:49:50 +02:00
var extensions []ExtensionFunc
2017-01-25 18:25:17 +02:00
var anyType reflect.Type
2017-05-24 08:34:00 +02:00
var marshalerType reflect.Type
2017-05-24 10:04:11 +02:00
var unmarshalerType reflect.Type
2016-12-04 14:50:55 +02:00
2017-01-07 01:49:50 +02:00
func init() {
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
2017-01-25 16:43:57 +02:00
typeEncoders = map[string]Encoder{}
fieldEncoders = map[string]Encoder{}
2017-01-07 01:49:50 +02:00
extensions = []ExtensionFunc{}
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
2017-01-09 11:47:21 +02:00
atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
2017-01-25 18:25:17 +02:00
anyType = reflect.TypeOf((*Any)(nil)).Elem()
2017-05-24 08:34:00 +02:00
marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
2017-05-24 10:04:11 +02:00
unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
2016-12-07 02:49:52 +02:00
}
2016-12-11 04:04:26 +02:00
func addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
2017-01-09 11:47:21 +02:00
done := false
for !done {
2016-12-04 14:50:55 +02:00
ptr := atomic.LoadPointer(&DECODERS)
2016-12-11 04:04:26 +02:00
cache := *(*map[reflect.Type]Decoder)(ptr)
2017-01-09 11:47:21 +02:00
copied := map[reflect.Type]Decoder{}
2016-12-04 07:13:38 +02:00
for k, v := range cache {
2017-01-09 11:47:21 +02:00
copied[k] = v
2016-12-04 07:13:38 +02:00
}
2017-01-09 11:47:21 +02:00
copied[cacheKey] = decoder
done = atomic.CompareAndSwapPointer(&DECODERS, ptr, unsafe.Pointer(&copied))
}
}
func addEncoderToCache(cacheKey reflect.Type, encoder Encoder) {
done := false
for !done {
ptr := atomic.LoadPointer(&ENCODERS)
cache := *(*map[reflect.Type]Encoder)(ptr)
copied := map[reflect.Type]Encoder{}
for k, v := range cache {
copied[k] = v
}
copied[cacheKey] = encoder
done = atomic.CompareAndSwapPointer(&ENCODERS, ptr, unsafe.Pointer(&copied))
2016-12-04 07:13:38 +02:00
}
}
2016-12-11 04:04:26 +02:00
func getDecoderFromCache(cacheKey reflect.Type) Decoder {
2016-12-04 14:50:55 +02:00
ptr := atomic.LoadPointer(&DECODERS)
2016-12-11 04:04:26 +02:00
cache := *(*map[reflect.Type]Decoder)(ptr)
2016-12-04 07:13:38 +02:00
return cache[cacheKey]
}
2017-01-09 11:47:21 +02:00
func getEncoderFromCache(cacheKey reflect.Type) Encoder {
ptr := atomic.LoadPointer(&ENCODERS)
cache := *(*map[reflect.Type]Encoder)(ptr)
return cache[cacheKey]
}
// RegisterTypeDecoder can register a type for json object
func RegisterTypeDecoder(typ string, fun DecoderFunc) {
typeDecoders[typ] = &funcDecoder{fun}
2016-12-05 07:20:27 +02:00
}
// RegisterFieldDecoder can register a type for json field
func RegisterFieldDecoder(typ string, field string, fun DecoderFunc) {
fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = &funcDecoder{fun}
2016-12-05 07:20:27 +02:00
}
2017-01-25 16:43:57 +02:00
func RegisterTypeEncoder(typ string, fun EncoderFunc) {
typeEncoders[typ] = &funcEncoder{fun}
}
func RegisterFieldEncoder(typ string, field string, fun EncoderFunc) {
fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = &funcEncoder{fun}
}
// RegisterExtension can register a custom extension
2016-12-17 11:38:13 +02:00
func RegisterExtension(extension ExtensionFunc) {
extensions = append(extensions, extension)
2016-12-12 13:06:33 +02:00
}
// CleanDecoders cleans decoders registered
func CleanDecoders() {
2016-12-05 07:20:27 +02:00
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
}
2017-05-05 02:22:19 +02:00
func CleanEncoders() {
typeEncoders = map[string]Encoder{}
fieldEncoders = map[string]Encoder{}
}
2017-01-07 01:49:50 +02:00
type optionalDecoder struct {
valueType reflect.Type
valueDecoder Decoder
}
func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
*((*unsafe.Pointer)(ptr)) = nil
} else {
if *((*unsafe.Pointer)(ptr)) == nil {
// pointer to null, we have to allocate memory to hold the value
value := reflect.New(decoder.valueType)
decoder.valueDecoder.decode(unsafe.Pointer(value.Pointer()), iter)
*((*uintptr)(ptr)) = value.Pointer()
} else {
// reuse existing instance
decoder.valueDecoder.decode(*((*unsafe.Pointer)(ptr)), iter)
}
}
}
2017-01-09 14:51:09 +02:00
type optionalEncoder struct {
valueEncoder Encoder
}
func (encoder *optionalEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil {
2017-01-18 17:33:40 +02:00
stream.WriteNil()
2017-01-09 14:51:09 +02:00
} else {
encoder.valueEncoder.encode(*((*unsafe.Pointer)(ptr)), stream)
}
}
2017-01-25 18:25:17 +02:00
func (encoder *optionalEncoder) encodeInterface(val interface{}, stream *Stream) {
writeToStream(val, stream, encoder)
2017-01-25 18:25:17 +02:00
}
2017-03-08 17:38:25 +02:00
func (encoder *optionalEncoder) isEmpty(ptr unsafe.Pointer) bool {
if *((*unsafe.Pointer)(ptr)) == nil {
return true
} else {
return encoder.valueEncoder.isEmpty(*((*unsafe.Pointer)(ptr)))
}
}
2017-05-05 10:51:05 +02:00
type placeholderEncoder struct {
valueEncoder Encoder
}
func (encoder *placeholderEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
encoder.valueEncoder.encode(ptr, stream)
}
func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stream) {
writeToStream(val, stream, encoder)
2017-05-05 10:51:05 +02:00
}
func (encoder *placeholderEncoder) isEmpty(ptr unsafe.Pointer) bool {
return encoder.valueEncoder.isEmpty(ptr)
}
type placeholderDecoder struct {
valueDecoder Decoder
}
func (decoder *placeholderDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.valueDecoder.decode(ptr, iter)
}
2016-12-04 06:27:34 +02:00
// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
typ *struct{}
word unsafe.Pointer
2016-12-04 05:06:38 +02:00
}
// Read converts an Iterator instance into go interface, same as json.Unmarshal
2017-01-09 11:47:21 +02:00
func (iter *Iterator) ReadVal(obj interface{}) {
typ := reflect.TypeOf(obj)
cacheKey := typ.Elem()
2016-12-04 14:50:55 +02:00
cachedDecoder := getDecoderFromCache(cacheKey)
if cachedDecoder == nil {
2017-01-09 11:47:21 +02:00
decoder, err := decoderOfType(cacheKey)
2016-12-04 14:50:55 +02:00
if err != nil {
iter.Error = err
return
}
cachedDecoder = decoder
addDecoderToCache(cacheKey, decoder)
2016-12-04 05:06:38 +02:00
}
2016-12-04 06:27:34 +02:00
e := (*emptyInterface)(unsafe.Pointer(&obj))
2016-12-04 14:50:55 +02:00
cachedDecoder.decode(e.word, iter)
2016-12-04 06:27:34 +02:00
}
2017-01-09 11:47:21 +02:00
func (stream *Stream) WriteVal(val interface{}) {
2017-01-18 17:33:40 +02:00
if nil == val {
stream.WriteNil()
return
}
2017-01-09 11:47:21 +02:00
typ := reflect.TypeOf(val)
cacheKey := typ
cachedEncoder := getEncoderFromCache(cacheKey)
if cachedEncoder == nil {
encoder, err := encoderOfType(cacheKey)
if err != nil {
stream.Error = err
return
}
cachedEncoder = encoder
addEncoderToCache(cacheKey, encoder)
}
2017-01-25 18:25:17 +02:00
cachedEncoder.encodeInterface(val, stream)
2017-01-09 11:47:21 +02:00
}
2016-12-04 06:27:34 +02:00
type prefix string
2017-01-09 13:19:48 +02:00
func (p prefix) addToDecoder(decoder Decoder, err error) (Decoder, error) {
2016-12-04 06:27:34 +02:00
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return decoder, err
2016-12-04 05:06:38 +02:00
}
2017-01-09 13:19:48 +02:00
func (p prefix) addToEncoder(encoder Encoder, err error) (Encoder, error) {
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return encoder, err
}
func decoderOfType(typ reflect.Type) (Decoder, error) {
typeName := typ.String()
2016-12-11 04:04:26 +02:00
typeDecoder := typeDecoders[typeName]
2016-12-05 07:20:27 +02:00
if typeDecoder != nil {
return typeDecoder, nil
}
if typ.Kind() == reflect.Ptr {
typeDecoder := typeDecoders[typ.Elem().String()]
if typeDecoder != nil {
return &optionalDecoder{typ.Elem(),typeDecoder}, nil
}
}
2017-05-05 10:51:05 +02:00
cacheKey := typ
cachedDecoder := getDecoderFromCache(cacheKey)
if cachedDecoder != nil {
return cachedDecoder, nil
}
placeholder := &placeholderDecoder{}
addDecoderToCache(cacheKey, placeholder)
newDecoder, err := createDecoderOfType(typ)
placeholder.valueDecoder = newDecoder
addDecoderToCache(cacheKey, newDecoder)
return newDecoder, err
}
func createDecoderOfType(typ reflect.Type) (Decoder, error) {
2017-05-24 10:04:11 +02:00
if typ.ConvertibleTo(anyType) {
return &anyCodec{}, nil
}
if typ.ConvertibleTo(unmarshalerType) {
templateInterface := reflect.New(typ).Elem().Interface()
return &optionalDecoder{typ, &unmarshalerDecoder{extractInterface(templateInterface)}}, nil
}
switch typ.Kind() {
2016-12-04 05:06:38 +02:00
case reflect.String:
2017-01-09 11:47:21 +02:00
return &stringCodec{}, nil
2016-12-04 15:19:54 +02:00
case reflect.Int:
2017-01-09 11:47:21 +02:00
return &intCodec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Int8:
2017-01-09 13:19:48 +02:00
return &int8Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Int16:
2017-01-09 13:19:48 +02:00
return &int16Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Int32:
2017-01-09 13:19:48 +02:00
return &int32Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Int64:
2017-01-09 13:19:48 +02:00
return &int64Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Uint:
2017-01-09 13:19:48 +02:00
return &uintCodec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Uint8:
2017-01-09 13:19:48 +02:00
return &uint8Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Uint16:
2017-01-09 13:19:48 +02:00
return &uint16Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Uint32:
2017-01-09 13:19:48 +02:00
return &uint32Codec{}, nil
2016-12-04 15:32:43 +02:00
case reflect.Uint64:
2017-01-09 13:19:48 +02:00
return &uint64Codec{}, nil
2016-12-04 16:15:12 +02:00
case reflect.Float32:
2017-01-09 13:19:48 +02:00
return &float32Codec{}, nil
2016-12-04 16:15:12 +02:00
case reflect.Float64:
2017-01-09 13:19:48 +02:00
return &float64Codec{}, nil
2016-12-04 16:15:12 +02:00
case reflect.Bool:
2017-01-09 13:19:48 +02:00
return &boolCodec{}, nil
2016-12-11 04:04:26 +02:00
case reflect.Interface:
2017-01-25 17:25:25 +02:00
if typ.NumMethod() == 0 {
return &interfaceCodec{}, nil
} else {
return nil, errors.New("unsupportd type: " + typ.String())
}
2016-12-04 06:27:34 +02:00
case reflect.Struct:
2017-05-05 10:51:05 +02:00
return prefix(fmt.Sprintf("[%s]", typ.String())).addToDecoder(decoderOfStruct(typ))
2016-12-04 07:13:38 +02:00
case reflect.Slice:
2017-01-09 13:19:48 +02:00
return prefix("[slice]").addToDecoder(decoderOfSlice(typ))
2016-12-10 18:38:07 +02:00
case reflect.Map:
2017-01-09 13:19:48 +02:00
return prefix("[map]").addToDecoder(decoderOfMap(typ))
2016-12-04 07:13:38 +02:00
case reflect.Ptr:
2017-01-09 14:51:09 +02:00
return prefix("[optional]").addToDecoder(decoderOfOptional(typ))
2016-12-04 07:13:38 +02:00
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
2016-12-04 07:13:38 +02:00
}
}
2017-01-09 11:47:21 +02:00
func encoderOfType(typ reflect.Type) (Encoder, error) {
2017-01-09 13:48:57 +02:00
typeName := typ.String()
2017-01-25 16:43:57 +02:00
typeEncoder := typeEncoders[typeName]
if typeEncoder != nil {
return typeEncoder, nil
}
if typ.Kind() == reflect.Ptr {
typeEncoder := typeEncoders[typ.Elem().String()]
if typeEncoder != nil {
return &optionalEncoder{typeEncoder}, nil
}
}
2017-05-05 10:51:05 +02:00
cacheKey := typ
cachedEncoder := getEncoderFromCache(cacheKey)
if cachedEncoder != nil {
return cachedEncoder, nil
}
placeholder := &placeholderEncoder{}
addEncoderToCache(cacheKey, placeholder)
newEncoder, err := createEncoderOfType(typ)
placeholder.valueEncoder = newEncoder
addEncoderToCache(cacheKey, newEncoder)
return newEncoder, err
}
func createEncoderOfType(typ reflect.Type) (Encoder, error) {
2017-05-24 08:34:00 +02:00
if typ.ConvertibleTo(anyType) {
return &anyCodec{}, nil
}
if typ.ConvertibleTo(marshalerType) {
templateInterface := reflect.New(typ).Elem().Interface()
return &marshalerEncoder{extractInterface(templateInterface)}, nil
}
2017-01-09 11:47:21 +02:00
switch typ.Kind() {
case reflect.String:
return &stringCodec{}, nil
case reflect.Int:
return &intCodec{}, nil
2017-01-09 13:19:48 +02:00
case reflect.Int8:
return &int8Codec{}, nil
case reflect.Int16:
return &int16Codec{}, nil
case reflect.Int32:
return &int32Codec{}, nil
case reflect.Int64:
return &int64Codec{}, nil
case reflect.Uint:
return &uintCodec{}, nil
case reflect.Uint8:
return &uint8Codec{}, nil
case reflect.Uint16:
return &uint16Codec{}, nil
case reflect.Uint32:
return &uint32Codec{}, nil
case reflect.Uint64:
return &uint64Codec{}, nil
case reflect.Float32:
return &float32Codec{}, nil
case reflect.Float64:
return &float64Codec{}, nil
case reflect.Bool:
return &boolCodec{}, nil
2017-01-09 15:00:01 +02:00
case reflect.Interface:
return &interfaceCodec{}, nil
2017-01-09 13:19:48 +02:00
case reflect.Struct:
2017-05-05 10:51:05 +02:00
return prefix(fmt.Sprintf("[%s]", typ.String())).addToEncoder(encoderOfStruct(typ))
2017-01-09 13:48:57 +02:00
case reflect.Slice:
return prefix("[slice]").addToEncoder(encoderOfSlice(typ))
2017-01-09 14:51:09 +02:00
case reflect.Map:
return prefix("[map]").addToEncoder(encoderOfMap(typ))
case reflect.Ptr:
return prefix("[optional]").addToEncoder(encoderOfOptional(typ))
2017-01-09 11:47:21 +02:00
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
}
}
func decoderOfOptional(typ reflect.Type) (Decoder, error) {
2017-01-09 14:51:09 +02:00
elemType := typ.Elem()
decoder, err := decoderOfType(elemType)
2016-12-04 15:19:54 +02:00
if err != nil {
return nil, err
2016-12-04 05:06:38 +02:00
}
2017-01-09 14:51:09 +02:00
return &optionalDecoder{elemType, decoder}, nil
}
func encoderOfOptional(typ reflect.Type) (Encoder, error) {
elemType := typ.Elem()
decoder, err := encoderOfType(elemType)
if err != nil {
return nil, err
}
2017-05-05 10:51:05 +02:00
return &optionalEncoder{ decoder}, nil
2016-12-04 05:06:38 +02:00
}
func decoderOfMap(typ reflect.Type) (Decoder, error) {
2017-01-09 11:47:21 +02:00
decoder, err := decoderOfType(typ.Elem())
2016-12-10 18:38:07 +02:00
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Interface()
2017-05-24 08:34:00 +02:00
return &mapDecoder{typ, typ.Elem(), decoder, extractInterface(mapInterface)}, nil
}
func extractInterface(val interface{}) emptyInterface {
return *((*emptyInterface)(unsafe.Pointer(&val)))
2016-12-10 18:38:07 +02:00
}
2017-01-09 14:51:09 +02:00
func encoderOfMap(typ reflect.Type) (Encoder, error) {
2017-01-25 18:25:17 +02:00
elemType := typ.Elem()
encoder, err := encoderOfType(elemType)
2017-01-09 14:51:09 +02:00
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Elem().Interface()
2017-01-25 18:25:17 +02:00
if elemType.Kind() == reflect.Interface && elemType.NumMethod() == 0 {
return &mapInterfaceEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
2017-01-25 16:43:57 +02:00
} else {
2017-01-25 18:25:17 +02:00
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
2017-01-25 16:43:57 +02:00
}
2017-01-09 14:51:09 +02:00
}