@@ -22,6 +22,7 @@ var anonymousCounter = 1
22
22
var anonymousDecoders = []byte {}
23
23
var referencedImports = map [string ]string {}
24
24
var allImports = map [string ]string {}
25
+ var prefix string
25
26
26
27
func init () {
27
28
var err error
@@ -35,11 +36,12 @@ func init() {
35
36
func main () {
36
37
typeSpec := locateTypeSpec ()
37
38
typeName := typeSpec .Name .Name
39
+ prefix = typeName
38
40
switch x := typeSpec .Type .(type ) {
39
41
case * ast.ArrayType :
40
42
genArray (typeName , x )
41
43
case * ast.StructType :
42
- genStruct (x )
44
+ genStruct (typeName , x )
43
45
case * ast.MapType :
44
46
genMap (x )
45
47
default :
@@ -48,25 +50,35 @@ func main() {
48
50
}
49
51
mainDecoder := lines
50
52
lines = []byte {}
53
+ switch x := typeSpec .Type .(type ) {
54
+ case * ast.StructType :
55
+ genStructFields (x )
56
+ }
57
+ fieldsDecoder := lines
58
+ lines = []byte {}
51
59
_l (fmt .Sprintf ("package %s" , os .Getenv ("GOPACKAGE" )))
52
60
_n ()
53
61
_l (`import jsoniter "github.com/json-iterator/tinygo"` )
54
62
for alias , path := range referencedImports {
55
63
_f (`import %s "%s"` , alias , path )
56
64
}
57
65
_n ()
58
- _f ("func %s_json_unmarshal(iter *jsoniter.Iterator, out *%s) {" , escapeTypeName (typeName ), typeName )
59
- lines = append (lines , anonymousDecoders ... )
66
+ _f ("func %s_json_unmarshal(iter *jsoniter.Iterator, out *%s) {" , prefix , typeName )
60
67
lines = append (lines , mainDecoder ... )
61
68
_l ("}" )
69
+ _f ("func %s_json_unmarshal_field(iter *jsoniter.Iterator, field string, out *%s) bool {" , prefix , typeName )
70
+ lines = append (lines , fieldsDecoder ... )
71
+ _l (" return false" )
72
+ _l ("}" )
73
+ lines = append (lines , anonymousDecoders ... )
62
74
_f ("type %s_json struct {" , typeName )
63
75
_l ("}" )
64
76
_f ("func (json %s_json) Type() interface{} {" , typeName )
65
77
_f (" var val %s" , typeName )
66
78
_l (" return &val" )
67
79
_l ("}" )
68
80
_f ("func (json %s_json) Unmarshal(iter *jsoniter.Iterator, val interface{}) {" , typeName )
69
- _f (" %s_json_unmarshal(iter, val.(*%s))" , typeName , typeName )
81
+ _f (" %s_json_unmarshal(iter, val.(*%s))" , prefix , typeName )
70
82
_l ("}" )
71
83
outputPath := filepath .Join (cwd , fmt .Sprintf ("%s_json.go" , typeSpec .Name .Name ))
72
84
os .WriteFile (outputPath , lines , 0644 )
@@ -103,17 +115,13 @@ func nodeToString(node ast.Node) string {
103
115
return buf .String ()
104
116
}
105
117
106
- func escapeTypeName (typeName string ) string {
107
- return strings .ReplaceAll (typeName , "[]" , "array_" )
108
- }
109
-
110
118
func genAnonymousArray (arrayType * ast.ArrayType ) string {
111
- decoderName := fmt .Sprintf (`array%d` , anonymousCounter )
119
+ decoderName := fmt .Sprintf (`%s_array%d` , prefix , anonymousCounter )
112
120
typeName := nodeToString (arrayType )
113
121
anonymousCounter ++
114
122
oldLines := lines
115
123
lines = []byte {}
116
- _f ("%s_json_unmarshal := func (iter *jsoniter.Iterator, out *%s) {" , decoderName , typeName )
124
+ _f ("func %s_json_unmarshal (iter *jsoniter.Iterator, out *%s) {" , decoderName , typeName )
117
125
genArray (typeName , arrayType )
118
126
_l ("}" )
119
127
anonymousDecoders = append (anonymousDecoders , lines ... )
@@ -122,26 +130,29 @@ func genAnonymousArray(arrayType *ast.ArrayType) string {
122
130
}
123
131
124
132
func genAnonymousStruct (structType * ast.StructType ) string {
125
- decoderName := fmt .Sprintf (`struct%d` , anonymousCounter )
126
- typeName := nodeToString (structType )
133
+ decoderName := fmt .Sprintf (`%s_struct%d` , prefix , anonymousCounter )
127
134
anonymousCounter ++
128
135
oldLines := lines
129
136
lines = []byte {}
130
- _f ("%s_json_unmarshal := func (iter *jsoniter.Iterator, out *%s) {" , decoderName , typeName )
131
- genStruct (structType )
137
+ _f ("func %s_json_unmarshal_field (iter *jsoniter.Iterator, field string, out *%s) bool {" , decoderName , nodeToString (structType ))
138
+ genStructFields (structType )
139
+ _l (" return false" )
140
+ _l ("}" )
141
+ _f ("func %s_json_unmarshal (iter *jsoniter.Iterator, out *%s) {" , decoderName , nodeToString (structType ))
142
+ genStruct (decoderName , structType )
132
143
_l ("}" )
133
144
anonymousDecoders = append (anonymousDecoders , lines ... )
134
145
lines = oldLines
135
146
return decoderName + "_json_unmarshal(iter, %s)"
136
147
}
137
148
138
149
func genAnonymousMap (mapType * ast.MapType ) string {
139
- decoderName := fmt .Sprintf (`map%d` , anonymousCounter )
150
+ decoderName := fmt .Sprintf (`%s_map%d` , prefix , anonymousCounter )
140
151
typeName := nodeToString (mapType )
141
152
anonymousCounter ++
142
153
oldLines := lines
143
154
lines = []byte {}
144
- _f ("%s_json_unmarshal := func (iter *jsoniter.Iterator, out *%s) {" , decoderName , typeName )
155
+ _f ("func %s_json_unmarshal (iter *jsoniter.Iterator, out *%s) {" , decoderName , typeName )
145
156
genMap (mapType )
146
157
_l ("}" )
147
158
anonymousDecoders = append (anonymousDecoders , lines ... )
@@ -203,14 +214,38 @@ func genMap(mapType *ast.MapType) {
203
214
_l (" }" )
204
215
}
205
216
206
- func genStruct (structType * ast.StructType ) {
217
+ func genStructFields (structType * ast.StructType ) {
207
218
oldLines := lines
208
- _l (" more := iter.ReadObjectHead()" )
209
- _l (" for more {" )
210
- _l (" field := iter.ReadObjectField()" )
211
- _l (" switch {" )
212
219
isEmptyStruct := true
220
+ for i , field := range structType .Fields .List {
221
+ if len (field .Names ) != 0 {
222
+ continue
223
+ }
224
+ switch x := field .Type .(type ) {
225
+ case * ast.StarExpr :
226
+ if ident , ok := x .X .(* ast.Ident ); ok {
227
+ _f (" var val%d %s" , i , ident .Name )
228
+ _f (" if %s_json_unmarshal_field(iter, field, &val%d) {" , ident .Name , i )
229
+ _f (" out.%s = new(%s)" , ident .Name , ident .Name )
230
+ _f (" *out.%s = val%d" , ident .Name , i )
231
+ _l (" return true" )
232
+ _l (" }" )
233
+ } else {
234
+ reportError (fmt .Errorf ("unknown embed field type: %s" , field .Type ))
235
+ return
236
+ }
237
+ case * ast.Ident :
238
+ _f (" if %s_json_unmarshal_field(iter, field, &out.%s) { return true }" , x .Name , x .Name )
239
+ default :
240
+ reportError (fmt .Errorf ("unknown embed field type: %s" , field .Type ))
241
+ return
242
+ }
243
+ }
244
+ _l (" switch {" )
213
245
for _ , field := range structType .Fields .List {
246
+ if len (field .Names ) == 0 {
247
+ continue
248
+ }
214
249
fieldName := field .Names [0 ].Name
215
250
encodedFieldName := fieldName
216
251
if field .Tag != nil {
@@ -234,14 +269,22 @@ func genStruct(structType *ast.StructType) {
234
269
}
235
270
isEmptyStruct = false
236
271
ptr := fmt .Sprintf ("&(*out).%s" , fieldName )
237
- _f (" case field == `%s`:" , encodedFieldName )
272
+ _f (" case field == `%s`:" , encodedFieldName )
238
273
genDecodeStmt (field .Type , ptr )
274
+ _l (" return true" )
239
275
}
276
+ _l (" }" )
240
277
if isEmptyStruct {
241
278
lines = oldLines
242
279
return
243
280
}
244
- _l (" default:" )
281
+ }
282
+
283
+ func genStruct (typeName string , structType * ast.StructType ) {
284
+ _l (" more := iter.ReadObjectHead()" )
285
+ _l (" for more {" )
286
+ _l (" field := iter.ReadObjectField()" )
287
+ _f (" if !%s_json_unmarshal_field(iter, field, out) {" , typeName )
245
288
_l (" iter.Skip()" )
246
289
_l (" }" )
247
290
_l (" more = iter.ReadObjectMore()" )
0 commit comments