Skip to content
This repository was archived by the owner on Dec 15, 2025. It is now read-only.

Commit a9b9c73

Browse files
committed
fix #207 delay unsupported type error reporting
1 parent e0df39f commit a9b9c73

11 files changed

+503
-464
lines changed

feature_reflect.go

Lines changed: 233 additions & 357 deletions
Large diffs are not rendered by default.

feature_reflect_array.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ import (
77
"unsafe"
88
)
99

10-
func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
11-
decoder, err := decoderOfType(cfg, typ.Elem())
12-
if err != nil {
13-
return nil, err
14-
}
15-
return &arrayDecoder{typ, typ.Elem(), decoder}, nil
10+
func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
11+
decoder := decoderOfType(cfg, prefix+"[array]->", typ.Elem())
12+
return &arrayDecoder{typ, typ.Elem(), decoder}
1613
}
1714

18-
func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
19-
encoder, err := encoderOfType(cfg, typ.Elem())
20-
if err != nil {
21-
return nil, err
22-
}
15+
func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
16+
encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem())
2317
if typ.Elem().Kind() == reflect.Map {
2418
encoder = &OptionalEncoder{encoder}
2519
}
26-
return &arrayEncoder{typ, typ.Elem(), encoder}, nil
20+
return &arrayEncoder{typ, typ.Elem(), encoder}
2721
}
2822

2923
type arrayEncoder struct {

feature_reflect_extension.go

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func _getTypeEncoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValEncode
240240
return nil
241241
}
242242

243-
func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
243+
func describeStruct(cfg *frozenConfig, prefix string, typ reflect.Type) *StructDescriptor {
244244
embeddedBindings := []*Binding{}
245245
bindings := []*Binding{}
246246
for i := 0; i < typ.NumField(); i++ {
@@ -252,10 +252,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
252252
}
253253
if field.Anonymous && (tag == "" || tagParts[0] == "") {
254254
if field.Type.Kind() == reflect.Struct {
255-
structDescriptor, err := describeStruct(cfg, field.Type)
256-
if err != nil {
257-
return nil, err
258-
}
255+
structDescriptor := describeStruct(cfg, prefix, field.Type)
259256
for _, binding := range structDescriptor.Fields {
260257
binding.levels = append([]int{i}, binding.levels...)
261258
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
@@ -265,10 +262,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
265262
}
266263
continue
267264
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
268-
structDescriptor, err := describeStruct(cfg, field.Type.Elem())
269-
if err != nil {
270-
return nil, err
271-
}
265+
structDescriptor := describeStruct(cfg, prefix, field.Type.Elem())
272266
for _, binding := range structDescriptor.Fields {
273267
binding.levels = append([]int{i}, binding.levels...)
274268
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
@@ -285,19 +279,11 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
285279
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
286280
decoder := fieldDecoders[fieldCacheKey]
287281
if decoder == nil {
288-
var err error
289-
decoder, err = decoderOfType(cfg, field.Type)
290-
if len(fieldNames) > 0 && err != nil {
291-
return nil, err
292-
}
282+
decoder = decoderOfType(cfg, prefix+typ.String()+"."+field.Name+"->", field.Type)
293283
}
294284
encoder := fieldEncoders[fieldCacheKey]
295285
if encoder == nil {
296-
var err error
297-
encoder, err = encoderOfType(cfg, field.Type)
298-
if len(fieldNames) > 0 && err != nil {
299-
return nil, err
300-
}
286+
encoder = encoderOfType(cfg, prefix+typ.String()+"."+field.Name+"->", field.Type)
301287
// map is stored as pointer in the struct,
302288
// and treat nil or empty map as empty field
303289
if encoder != nil && field.Type.Kind() == reflect.Map {
@@ -314,7 +300,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
314300
binding.levels = []int{i}
315301
bindings = append(bindings, binding)
316302
}
317-
return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil
303+
return createStructDescriptor(cfg, typ, bindings, embeddedBindings)
318304
}
319305
func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
320306
onePtrEmbedded := false

feature_reflect_map.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ import (
99
"unsafe"
1010
)
1111

12+
func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
13+
decoder := decoderOfType(cfg, prefix+"[map]->", typ.Elem())
14+
mapInterface := reflect.New(typ).Interface()
15+
return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}
16+
}
17+
18+
func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
19+
elemType := typ.Elem()
20+
encoder := encoderOfType(cfg, prefix+"[map]->", elemType)
21+
mapInterface := reflect.New(typ).Elem().Interface()
22+
if cfg.sortMapKeys {
23+
return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
24+
}
25+
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
26+
}
27+
1228
type mapDecoder struct {
1329
mapType reflect.Type
1430
keyType reflect.Type

feature_reflect_object.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ import (
88
"unsafe"
99
)
1010

11-
func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
11+
func encoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
1212
type bindingTo struct {
1313
binding *Binding
1414
toName string
1515
ignored bool
1616
}
1717
orderedBindings := []*bindingTo{}
18-
structDescriptor, err := describeStruct(cfg, typ)
19-
if err != nil {
20-
return nil, err
21-
}
18+
structDescriptor := describeStruct(cfg, prefix, typ)
2219
for _, binding := range structDescriptor.Fields {
2320
for _, toName := range binding.ToNames {
2421
new := &bindingTo{
@@ -35,7 +32,7 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
3532
}
3633
}
3734
if len(orderedBindings) == 0 {
38-
return &emptyStructEncoder{}, nil
35+
return &emptyStructEncoder{}
3936
}
4037
finalOrderedFields := []structFieldTo{}
4138
for _, bindingTo := range orderedBindings {
@@ -46,7 +43,8 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
4643
})
4744
}
4845
}
49-
return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil
46+
return &structEncoder{typ, structDescriptor.onePtrEmbedded,
47+
structDescriptor.onePtrOptimization, finalOrderedFields}
5048
}
5149

5250
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
@@ -78,12 +76,9 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
7876
}
7977
}
8078

81-
func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
79+
func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
8280
bindings := map[string]*Binding{}
83-
structDescriptor, err := describeStruct(cfg, typ)
84-
if err != nil {
85-
return nil, err
86-
}
81+
structDescriptor := describeStruct(cfg, prefix, typ)
8782
for _, binding := range structDescriptor.Fields {
8883
for _, fromName := range binding.FromNames {
8984
old := bindings[fromName]
@@ -131,6 +126,7 @@ func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
131126
}
132127

133128
type structEncoder struct {
129+
typ reflect.Type
134130
onePtrEmbedded bool
135131
onePtrOptimization bool
136132
fields []structFieldTo
@@ -156,6 +152,9 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
156152
isNotFirst = true
157153
}
158154
stream.WriteObjectEnd()
155+
if stream.Error != nil && stream.Error != io.EOF {
156+
stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
157+
}
159158
}
160159

161160
func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {

feature_reflect_optional.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package jsoniter
2+
3+
import (
4+
"reflect"
5+
"unsafe"
6+
)
7+
8+
func decoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
9+
elemType := typ.Elem()
10+
decoder := decoderOfType(cfg, prefix, elemType)
11+
return &OptionalDecoder{elemType, decoder}
12+
}
13+
14+
func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
15+
elemType := typ.Elem()
16+
elemEncoder := encoderOfType(cfg, prefix, elemType)
17+
encoder := &OptionalEncoder{elemEncoder}
18+
if elemType.Kind() == reflect.Map {
19+
encoder = &OptionalEncoder{encoder}
20+
}
21+
return encoder
22+
}
23+
24+
type OptionalDecoder struct {
25+
ValueType reflect.Type
26+
ValueDecoder ValDecoder
27+
}
28+
29+
func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
30+
if iter.ReadNil() {
31+
*((*unsafe.Pointer)(ptr)) = nil
32+
} else {
33+
if *((*unsafe.Pointer)(ptr)) == nil {
34+
//pointer to null, we have to allocate memory to hold the value
35+
value := reflect.New(decoder.ValueType)
36+
newPtr := extractInterface(value.Interface()).word
37+
decoder.ValueDecoder.Decode(newPtr, iter)
38+
*((*uintptr)(ptr)) = uintptr(newPtr)
39+
} else {
40+
//reuse existing instance
41+
decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
42+
}
43+
}
44+
}
45+
46+
type deferenceDecoder struct {
47+
// only to deference a pointer
48+
valueType reflect.Type
49+
valueDecoder ValDecoder
50+
}
51+
52+
func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
53+
if *((*unsafe.Pointer)(ptr)) == nil {
54+
//pointer to null, we have to allocate memory to hold the value
55+
value := reflect.New(decoder.valueType)
56+
newPtr := extractInterface(value.Interface()).word
57+
decoder.valueDecoder.Decode(newPtr, iter)
58+
*((*uintptr)(ptr)) = uintptr(newPtr)
59+
} else {
60+
//reuse existing instance
61+
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
62+
}
63+
}
64+
65+
type OptionalEncoder struct {
66+
ValueEncoder ValEncoder
67+
}
68+
69+
func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
70+
if *((*unsafe.Pointer)(ptr)) == nil {
71+
stream.WriteNil()
72+
} else {
73+
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
74+
}
75+
}
76+
77+
func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
78+
WriteToStream(val, stream, encoder)
79+
}
80+
81+
func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
82+
return *((*unsafe.Pointer)(ptr)) == nil
83+
}
84+
85+
type optionalMapEncoder struct {
86+
valueEncoder ValEncoder
87+
}
88+
89+
func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
90+
if *((*unsafe.Pointer)(ptr)) == nil {
91+
stream.WriteNil()
92+
} else {
93+
encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
94+
}
95+
}
96+
97+
func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
98+
WriteToStream(val, stream, encoder)
99+
}
100+
101+
func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
102+
p := *((*unsafe.Pointer)(ptr))
103+
return p == nil || encoder.valueEncoder.IsEmpty(p)
104+
}

feature_reflect_slice.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ import (
77
"unsafe"
88
)
99

10-
func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
11-
decoder, err := decoderOfType(cfg, typ.Elem())
12-
if err != nil {
13-
return nil, err
14-
}
15-
return &sliceDecoder{typ, typ.Elem(), decoder}, nil
10+
func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
11+
decoder := decoderOfType(cfg, prefix+"[slice]->", typ.Elem())
12+
return &sliceDecoder{typ, typ.Elem(), decoder}
1613
}
1714

18-
func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
19-
encoder, err := encoderOfType(cfg, typ.Elem())
20-
if err != nil {
21-
return nil, err
22-
}
15+
func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
16+
encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem())
2317
if typ.Elem().Kind() == reflect.Map {
2418
encoder = &OptionalEncoder{encoder}
2519
}
26-
return &sliceEncoder{typ, typ.Elem(), encoder}, nil
20+
return &sliceEncoder{typ, typ.Elem(), encoder}
2721
}
2822

2923
type sliceEncoder struct {

0 commit comments

Comments
 (0)