1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-20 11:28:49 +02:00
json-iterator/feature_reflect.go

478 lines
13 KiB
Go
Raw Normal View History

2016-12-04 11:06:38 +08:00
package jsoniter
import (
2016-12-04 12:27:34 +08:00
"fmt"
"reflect"
"sync/atomic"
"unsafe"
2017-01-25 23:25:25 +08:00
"errors"
2016-12-04 11:06:38 +08: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 11:06:38 +08:00
type Decoder interface {
2016-12-04 12:27:34 +08:00
decode(ptr unsafe.Pointer, iter *Iterator)
2016-12-04 11:06:38 +08:00
}
2017-01-26 00:25:17 +08:00
2017-01-09 17:47:21 +08:00
type Encoder interface {
encode(ptr unsafe.Pointer, stream *Stream)
2017-01-26 00:25:17 +08:00
encodeInterface(val interface{}, stream *Stream)
}
func WriteToStream(val interface{}, stream *Stream, encoder Encoder) {
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 17:47:21 +08:00
}
2016-12-04 11:06:38 +08:00
2017-01-07 07:49:50 +08:00
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
2017-01-25 22:43:57 +08:00
type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
2017-01-07 07:49:50 +08:00
type ExtensionFunc func(typ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc)
2016-12-04 20:50:55 +08:00
2017-01-07 07:49:50 +08:00
type funcDecoder struct {
fun DecoderFunc
2016-12-04 20:50:55 +08:00
}
2017-01-07 07:49:50 +08:00
func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.fun(ptr, iter)
2016-12-07 08:49:52 +08:00
}
2017-01-25 22:43:57 +08:00
type funcEncoder struct {
fun EncoderFunc
}
func (encoder *funcEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
encoder.fun(ptr, stream)
}
2017-01-26 00:25:17 +08:00
func (encoder *funcEncoder) encodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
2017-01-07 07:49:50 +08:00
var DECODERS unsafe.Pointer
2017-01-09 17:47:21 +08:00
var ENCODERS unsafe.Pointer
2016-12-04 20:50:55 +08:00
2017-01-07 07:49:50 +08:00
var typeDecoders map[string]Decoder
var fieldDecoders map[string]Decoder
2017-01-25 22:43:57 +08:00
var typeEncoders map[string]Encoder
var fieldEncoders map[string]Encoder
2017-01-07 07:49:50 +08:00
var extensions []ExtensionFunc
2017-01-26 00:25:17 +08:00
var anyType reflect.Type
2016-12-04 20:50:55 +08:00
2017-01-07 07:49:50 +08:00
func init() {
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
2017-01-25 22:43:57 +08:00
typeEncoders = map[string]Encoder{}
fieldEncoders = map[string]Encoder{}
2017-01-07 07:49:50 +08:00
extensions = []ExtensionFunc{}
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
2017-01-09 17:47:21 +08:00
atomic.StorePointer(&ENCODERS, unsafe.Pointer(&map[string]Encoder{}))
2017-01-26 00:25:17 +08:00
anyType = reflect.TypeOf((*Any)(nil)).Elem()
2016-12-07 08:49:52 +08:00
}
2016-12-11 10:04:26 +08:00
func addDecoderToCache(cacheKey reflect.Type, decoder Decoder) {
2017-01-09 17:47:21 +08:00
done := false
for !done {
2016-12-04 20:50:55 +08:00
ptr := atomic.LoadPointer(&DECODERS)
2016-12-11 10:04:26 +08:00
cache := *(*map[reflect.Type]Decoder)(ptr)
2017-01-09 17:47:21 +08:00
copied := map[reflect.Type]Decoder{}
2016-12-04 13:13:38 +08:00
for k, v := range cache {
2017-01-09 17:47:21 +08:00
copied[k] = v
2016-12-04 13:13:38 +08:00
}
2017-01-09 17:47:21 +08: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 13:13:38 +08:00
}
}
2016-12-11 10:04:26 +08:00
func getDecoderFromCache(cacheKey reflect.Type) Decoder {
2016-12-04 20:50:55 +08:00
ptr := atomic.LoadPointer(&DECODERS)
2016-12-11 10:04:26 +08:00
cache := *(*map[reflect.Type]Decoder)(ptr)
2016-12-04 13:13:38 +08:00
return cache[cacheKey]
}
2017-01-09 17:47:21 +08: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 13:20:27 +08: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 13:20:27 +08:00
}
2017-01-25 22:43:57 +08: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 17:38:13 +08:00
func RegisterExtension(extension ExtensionFunc) {
extensions = append(extensions, extension)
2016-12-12 19:06:33 +08:00
}
// CleanDecoders cleans decoders registered
func CleanDecoders() {
2016-12-05 13:20:27 +08:00
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
}
2017-01-07 07:49:50 +08: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 20:51:09 +08:00
type optionalEncoder struct {
valueType reflect.Type
valueEncoder Encoder
}
func (encoder *optionalEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil {
2017-01-18 23:33:40 +08:00
stream.WriteNil()
2017-01-09 20:51:09 +08:00
} else {
encoder.valueEncoder.encode(*((*unsafe.Pointer)(ptr)), stream)
}
}
2017-01-26 00:25:17 +08:00
func (encoder *optionalEncoder) encodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
2017-01-07 07:49:50 +08:00
type mapDecoder struct {
mapType reflect.Type
elemType reflect.Type
elemDecoder Decoder
mapInterface emptyInterface
}
func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
mapInterface := decoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface).Elem()
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
elem := reflect.New(decoder.elemType)
decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)
// to put into map, we have to use reflection
realVal.SetMapIndex(reflect.ValueOf(string([]byte(field))), elem.Elem())
}
}
2017-01-09 20:51:09 +08:00
type mapEncoder struct {
mapType reflect.Type
elemType reflect.Type
elemEncoder Encoder
mapInterface emptyInterface
}
func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
stream.WriteObjectStart()
for i, key := range realVal.MapKeys() {
if i != 0 {
stream.WriteMore()
}
stream.WriteObjectField(key.String())
val := realVal.MapIndex(key).Interface()
2017-01-26 00:25:17 +08:00
encoder.elemEncoder.encodeInterface(val, stream)
2017-01-09 20:51:09 +08:00
}
stream.WriteObjectEnd()
}
2017-01-26 00:25:17 +08:00
func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
2017-01-25 22:43:57 +08:00
type mapInterfaceEncoder struct {
mapType reflect.Type
elemType reflect.Type
elemEncoder Encoder
mapInterface emptyInterface
}
func (encoder *mapInterfaceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
stream.WriteObjectStart()
for i, key := range realVal.MapKeys() {
if i != 0 {
stream.WriteMore()
}
stream.WriteObjectField(key.String())
val := realVal.MapIndex(key).Interface()
encoder.elemEncoder.encode(unsafe.Pointer(&val), stream)
}
stream.WriteObjectEnd()
}
2017-01-26 00:25:17 +08:00
func (encoder *mapInterfaceEncoder) encodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
2016-12-04 12:27:34 +08:00
// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
typ *struct{}
word unsafe.Pointer
2016-12-04 11:06:38 +08:00
}
// Read converts an Iterator instance into go interface, same as json.Unmarshal
2017-01-09 17:47:21 +08:00
func (iter *Iterator) ReadVal(obj interface{}) {
typ := reflect.TypeOf(obj)
cacheKey := typ.Elem()
2016-12-04 20:50:55 +08:00
cachedDecoder := getDecoderFromCache(cacheKey)
if cachedDecoder == nil {
2017-01-09 17:47:21 +08:00
decoder, err := decoderOfType(cacheKey)
2016-12-04 20:50:55 +08:00
if err != nil {
iter.Error = err
return
}
cachedDecoder = decoder
addDecoderToCache(cacheKey, decoder)
2016-12-04 11:06:38 +08:00
}
2016-12-04 12:27:34 +08:00
e := (*emptyInterface)(unsafe.Pointer(&obj))
2016-12-04 20:50:55 +08:00
cachedDecoder.decode(e.word, iter)
2016-12-04 12:27:34 +08:00
}
2017-01-09 17:47:21 +08:00
func (stream *Stream) WriteVal(val interface{}) {
2017-01-18 23:33:40 +08:00
if nil == val {
stream.WriteNil()
return
}
2017-01-09 17:47:21 +08: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-26 00:25:17 +08:00
cachedEncoder.encodeInterface(val, stream)
2017-01-09 17:47:21 +08:00
}
2016-12-04 12:27:34 +08:00
type prefix string
2017-01-09 19:19:48 +08:00
func (p prefix) addToDecoder(decoder Decoder, err error) (Decoder, error) {
2016-12-04 12:27:34 +08:00
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return decoder, err
2016-12-04 11:06:38 +08:00
}
2017-01-09 19:19:48 +08: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 10:04:26 +08:00
typeDecoder := typeDecoders[typeName]
2016-12-05 13:20:27 +08:00
if typeDecoder != nil {
return typeDecoder, nil
}
switch typ.Kind() {
2016-12-04 11:06:38 +08:00
case reflect.String:
2017-01-09 17:47:21 +08:00
return &stringCodec{}, nil
2016-12-04 21:19:54 +08:00
case reflect.Int:
2017-01-09 17:47:21 +08:00
return &intCodec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Int8:
2017-01-09 19:19:48 +08:00
return &int8Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Int16:
2017-01-09 19:19:48 +08:00
return &int16Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Int32:
2017-01-09 19:19:48 +08:00
return &int32Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Int64:
2017-01-09 19:19:48 +08:00
return &int64Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Uint:
2017-01-09 19:19:48 +08:00
return &uintCodec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Uint8:
2017-01-09 19:19:48 +08:00
return &uint8Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Uint16:
2017-01-09 19:19:48 +08:00
return &uint16Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Uint32:
2017-01-09 19:19:48 +08:00
return &uint32Codec{}, nil
2016-12-04 21:32:43 +08:00
case reflect.Uint64:
2017-01-09 19:19:48 +08:00
return &uint64Codec{}, nil
2016-12-04 22:15:12 +08:00
case reflect.Float32:
2017-01-09 19:19:48 +08:00
return &float32Codec{}, nil
2016-12-04 22:15:12 +08:00
case reflect.Float64:
2017-01-09 19:19:48 +08:00
return &float64Codec{}, nil
2016-12-04 22:15:12 +08:00
case reflect.Bool:
2017-01-09 19:19:48 +08:00
return &boolCodec{}, nil
2016-12-11 10:04:26 +08:00
case reflect.Interface:
2017-01-25 23:25:25 +08:00
if typ.NumMethod() == 0 {
return &interfaceCodec{}, nil
} else {
return nil, errors.New("unsupportd type: " + typ.String())
}
2016-12-04 12:27:34 +08:00
case reflect.Struct:
2017-01-09 19:48:57 +08:00
return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(typ))
2016-12-04 13:13:38 +08:00
case reflect.Slice:
2017-01-09 19:19:48 +08:00
return prefix("[slice]").addToDecoder(decoderOfSlice(typ))
2016-12-11 00:38:07 +08:00
case reflect.Map:
2017-01-09 19:19:48 +08:00
return prefix("[map]").addToDecoder(decoderOfMap(typ))
2016-12-04 13:13:38 +08:00
case reflect.Ptr:
2017-01-09 20:51:09 +08:00
return prefix("[optional]").addToDecoder(decoderOfOptional(typ))
2016-12-04 13:13:38 +08:00
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
2016-12-04 13:13:38 +08:00
}
}
2017-01-09 17:47:21 +08:00
func encoderOfType(typ reflect.Type) (Encoder, error) {
2017-01-26 00:25:17 +08:00
if typ.ConvertibleTo(anyType) {
return &anyCodec{}, nil
}
2017-01-09 19:48:57 +08:00
typeName := typ.String()
2017-01-25 22:43:57 +08:00
typeEncoder := typeEncoders[typeName]
if typeEncoder != nil {
return typeEncoder, nil
}
2017-01-09 17:47:21 +08:00
switch typ.Kind() {
case reflect.String:
return &stringCodec{}, nil
case reflect.Int:
return &intCodec{}, nil
2017-01-09 19:19:48 +08: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 21:00:01 +08:00
case reflect.Interface:
return &interfaceCodec{}, nil
2017-01-09 19:19:48 +08:00
case reflect.Struct:
2017-01-09 19:48:57 +08:00
return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(typ))
case reflect.Slice:
return prefix("[slice]").addToEncoder(encoderOfSlice(typ))
2017-01-09 20:51:09 +08:00
case reflect.Map:
return prefix("[map]").addToEncoder(encoderOfMap(typ))
case reflect.Ptr:
return prefix("[optional]").addToEncoder(encoderOfOptional(typ))
2017-01-09 17:47:21 +08:00
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
}
}
func decoderOfOptional(typ reflect.Type) (Decoder, error) {
2017-01-09 20:51:09 +08:00
elemType := typ.Elem()
decoder, err := decoderOfType(elemType)
2016-12-04 21:19:54 +08:00
if err != nil {
return nil, err
2016-12-04 11:06:38 +08:00
}
2017-01-09 20:51:09 +08: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
}
return &optionalEncoder{elemType, decoder}, nil
2016-12-04 11:06:38 +08:00
}
func decoderOfMap(typ reflect.Type) (Decoder, error) {
2017-01-09 17:47:21 +08:00
decoder, err := decoderOfType(typ.Elem())
2016-12-11 00:38:07 +08:00
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Interface()
return &mapDecoder{typ, typ.Elem(), decoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
2016-12-11 00:38:07 +08:00
}
2017-01-09 20:51:09 +08:00
func encoderOfMap(typ reflect.Type) (Encoder, error) {
2017-01-26 00:25:17 +08:00
elemType := typ.Elem()
encoder, err := encoderOfType(elemType)
2017-01-09 20:51:09 +08:00
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Elem().Interface()
2017-01-26 00:25:17 +08:00
if elemType.Kind() == reflect.Interface && elemType.NumMethod() == 0 {
return &mapInterfaceEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
2017-01-25 22:43:57 +08:00
} else {
2017-01-26 00:25:17 +08:00
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
2017-01-25 22:43:57 +08:00
}
2017-01-09 20:51:09 +08:00
}