1package jsoniter 2 3import ( 4 "fmt" 5 "github.com/modern-go/reflect2" 6 "reflect" 7 "sort" 8 "strings" 9 "unicode" 10 "unsafe" 11) 12 13var typeDecoders = map[string]ValDecoder{} 14var fieldDecoders = map[string]ValDecoder{} 15var typeEncoders = map[string]ValEncoder{} 16var fieldEncoders = map[string]ValEncoder{} 17var extensions = []Extension{} 18 19// StructDescriptor describe how should we encode/decode the struct 20type StructDescriptor struct { 21 Type reflect2.Type 22 Fields []*Binding 23} 24 25// GetField get one field from the descriptor by its name. 26// Can not use map here to keep field orders. 27func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { 28 for _, binding := range structDescriptor.Fields { 29 if binding.Field.Name() == fieldName { 30 return binding 31 } 32 } 33 return nil 34} 35 36// Binding describe how should we encode/decode the struct field 37type Binding struct { 38 levels []int 39 Field reflect2.StructField 40 FromNames []string 41 ToNames []string 42 Encoder ValEncoder 43 Decoder ValDecoder 44} 45 46// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. 47// Can also rename fields by UpdateStructDescriptor. 48type Extension interface { 49 UpdateStructDescriptor(structDescriptor *StructDescriptor) 50 CreateMapKeyDecoder(typ reflect2.Type) ValDecoder 51 CreateMapKeyEncoder(typ reflect2.Type) ValEncoder 52 CreateDecoder(typ reflect2.Type) ValDecoder 53 CreateEncoder(typ reflect2.Type) ValEncoder 54 DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder 55 DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder 56} 57 58// DummyExtension embed this type get dummy implementation for all methods of Extension 59type DummyExtension struct { 60} 61 62// UpdateStructDescriptor No-op 63func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { 64} 65 66// CreateMapKeyDecoder No-op 67func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { 68 return nil 69} 70 71// CreateMapKeyEncoder No-op 72func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { 73 return nil 74} 75 76// CreateDecoder No-op 77func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { 78 return nil 79} 80 81// CreateEncoder No-op 82func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { 83 return nil 84} 85 86// DecorateDecoder No-op 87func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { 88 return decoder 89} 90 91// DecorateEncoder No-op 92func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { 93 return encoder 94} 95 96type EncoderExtension map[reflect2.Type]ValEncoder 97 98// UpdateStructDescriptor No-op 99func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { 100} 101 102// CreateDecoder No-op 103func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { 104 return nil 105} 106 107// CreateEncoder get encoder from map 108func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { 109 return extension[typ] 110} 111 112// CreateMapKeyDecoder No-op 113func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { 114 return nil 115} 116 117// CreateMapKeyEncoder No-op 118func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { 119 return nil 120} 121 122// DecorateDecoder No-op 123func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { 124 return decoder 125} 126 127// DecorateEncoder No-op 128func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { 129 return encoder 130} 131 132type DecoderExtension map[reflect2.Type]ValDecoder 133 134// UpdateStructDescriptor No-op 135func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { 136} 137 138// CreateMapKeyDecoder No-op 139func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { 140 return nil 141} 142 143// CreateMapKeyEncoder No-op 144func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { 145 return nil 146} 147 148// CreateDecoder get decoder from map 149func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { 150 return extension[typ] 151} 152 153// CreateEncoder No-op 154func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { 155 return nil 156} 157 158// DecorateDecoder No-op 159func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { 160 return decoder 161} 162 163// DecorateEncoder No-op 164func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { 165 return encoder 166} 167 168type funcDecoder struct { 169 fun DecoderFunc 170} 171 172func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { 173 decoder.fun(ptr, iter) 174} 175 176type funcEncoder struct { 177 fun EncoderFunc 178 isEmptyFunc func(ptr unsafe.Pointer) bool 179} 180 181func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { 182 encoder.fun(ptr, stream) 183} 184 185func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { 186 if encoder.isEmptyFunc == nil { 187 return false 188 } 189 return encoder.isEmptyFunc(ptr) 190} 191 192// DecoderFunc the function form of TypeDecoder 193type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) 194 195// EncoderFunc the function form of TypeEncoder 196type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) 197 198// RegisterTypeDecoderFunc register TypeDecoder for a type with function 199func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { 200 typeDecoders[typ] = &funcDecoder{fun} 201} 202 203// RegisterTypeDecoder register TypeDecoder for a typ 204func RegisterTypeDecoder(typ string, decoder ValDecoder) { 205 typeDecoders[typ] = decoder 206} 207 208// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function 209func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { 210 RegisterFieldDecoder(typ, field, &funcDecoder{fun}) 211} 212 213// RegisterFieldDecoder register TypeDecoder for a struct field 214func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { 215 fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder 216} 217 218// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function 219func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { 220 typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} 221} 222 223// RegisterTypeEncoder register TypeEncoder for a type 224func RegisterTypeEncoder(typ string, encoder ValEncoder) { 225 typeEncoders[typ] = encoder 226} 227 228// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function 229func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { 230 RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) 231} 232 233// RegisterFieldEncoder register TypeEncoder for a struct field 234func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { 235 fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder 236} 237 238// RegisterExtension register extension 239func RegisterExtension(extension Extension) { 240 extensions = append(extensions, extension) 241} 242 243func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { 244 decoder := _getTypeDecoderFromExtension(ctx, typ) 245 if decoder != nil { 246 for _, extension := range extensions { 247 decoder = extension.DecorateDecoder(typ, decoder) 248 } 249 decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) 250 for _, extension := range ctx.extraExtensions { 251 decoder = extension.DecorateDecoder(typ, decoder) 252 } 253 } 254 return decoder 255} 256func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { 257 for _, extension := range extensions { 258 decoder := extension.CreateDecoder(typ) 259 if decoder != nil { 260 return decoder 261 } 262 } 263 decoder := ctx.decoderExtension.CreateDecoder(typ) 264 if decoder != nil { 265 return decoder 266 } 267 for _, extension := range ctx.extraExtensions { 268 decoder := extension.CreateDecoder(typ) 269 if decoder != nil { 270 return decoder 271 } 272 } 273 typeName := typ.String() 274 decoder = typeDecoders[typeName] 275 if decoder != nil { 276 return decoder 277 } 278 if typ.Kind() == reflect.Ptr { 279 ptrType := typ.(*reflect2.UnsafePtrType) 280 decoder := typeDecoders[ptrType.Elem().String()] 281 if decoder != nil { 282 return &OptionalDecoder{ptrType.Elem(), decoder} 283 } 284 } 285 return nil 286} 287 288func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { 289 encoder := _getTypeEncoderFromExtension(ctx, typ) 290 if encoder != nil { 291 for _, extension := range extensions { 292 encoder = extension.DecorateEncoder(typ, encoder) 293 } 294 encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) 295 for _, extension := range ctx.extraExtensions { 296 encoder = extension.DecorateEncoder(typ, encoder) 297 } 298 } 299 return encoder 300} 301 302func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { 303 for _, extension := range extensions { 304 encoder := extension.CreateEncoder(typ) 305 if encoder != nil { 306 return encoder 307 } 308 } 309 encoder := ctx.encoderExtension.CreateEncoder(typ) 310 if encoder != nil { 311 return encoder 312 } 313 for _, extension := range ctx.extraExtensions { 314 encoder := extension.CreateEncoder(typ) 315 if encoder != nil { 316 return encoder 317 } 318 } 319 typeName := typ.String() 320 encoder = typeEncoders[typeName] 321 if encoder != nil { 322 return encoder 323 } 324 if typ.Kind() == reflect.Ptr { 325 typePtr := typ.(*reflect2.UnsafePtrType) 326 encoder := typeEncoders[typePtr.Elem().String()] 327 if encoder != nil { 328 return &OptionalEncoder{encoder} 329 } 330 } 331 return nil 332} 333 334func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { 335 structType := typ.(*reflect2.UnsafeStructType) 336 embeddedBindings := []*Binding{} 337 bindings := []*Binding{} 338 for i := 0; i < structType.NumField(); i++ { 339 field := structType.Field(i) 340 tag, hastag := field.Tag().Lookup(ctx.getTagKey()) 341 if ctx.onlyTaggedField && !hastag && !field.Anonymous() { 342 continue 343 } 344 tagParts := strings.Split(tag, ",") 345 if tag == "-" { 346 continue 347 } 348 if field.Anonymous() && (tag == "" || tagParts[0] == "") { 349 if field.Type().Kind() == reflect.Struct { 350 structDescriptor := describeStruct(ctx, field.Type()) 351 for _, binding := range structDescriptor.Fields { 352 binding.levels = append([]int{i}, binding.levels...) 353 omitempty := binding.Encoder.(*structFieldEncoder).omitempty 354 binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} 355 binding.Decoder = &structFieldDecoder{field, binding.Decoder} 356 embeddedBindings = append(embeddedBindings, binding) 357 } 358 continue 359 } else if field.Type().Kind() == reflect.Ptr { 360 ptrType := field.Type().(*reflect2.UnsafePtrType) 361 if ptrType.Elem().Kind() == reflect.Struct { 362 structDescriptor := describeStruct(ctx, ptrType.Elem()) 363 for _, binding := range structDescriptor.Fields { 364 binding.levels = append([]int{i}, binding.levels...) 365 omitempty := binding.Encoder.(*structFieldEncoder).omitempty 366 binding.Encoder = &dereferenceEncoder{binding.Encoder} 367 binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} 368 binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} 369 binding.Decoder = &structFieldDecoder{field, binding.Decoder} 370 embeddedBindings = append(embeddedBindings, binding) 371 } 372 continue 373 } 374 } 375 } 376 fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) 377 fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) 378 decoder := fieldDecoders[fieldCacheKey] 379 if decoder == nil { 380 decoder = decoderOfType(ctx.append(field.Name()), field.Type()) 381 } 382 encoder := fieldEncoders[fieldCacheKey] 383 if encoder == nil { 384 encoder = encoderOfType(ctx.append(field.Name()), field.Type()) 385 } 386 binding := &Binding{ 387 Field: field, 388 FromNames: fieldNames, 389 ToNames: fieldNames, 390 Decoder: decoder, 391 Encoder: encoder, 392 } 393 binding.levels = []int{i} 394 bindings = append(bindings, binding) 395 } 396 return createStructDescriptor(ctx, typ, bindings, embeddedBindings) 397} 398func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { 399 structDescriptor := &StructDescriptor{ 400 Type: typ, 401 Fields: bindings, 402 } 403 for _, extension := range extensions { 404 extension.UpdateStructDescriptor(structDescriptor) 405 } 406 ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) 407 ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) 408 for _, extension := range ctx.extraExtensions { 409 extension.UpdateStructDescriptor(structDescriptor) 410 } 411 processTags(structDescriptor, ctx.frozenConfig) 412 // merge normal & embedded bindings & sort with original order 413 allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) 414 sort.Sort(allBindings) 415 structDescriptor.Fields = allBindings 416 return structDescriptor 417} 418 419type sortableBindings []*Binding 420 421func (bindings sortableBindings) Len() int { 422 return len(bindings) 423} 424 425func (bindings sortableBindings) Less(i, j int) bool { 426 left := bindings[i].levels 427 right := bindings[j].levels 428 k := 0 429 for { 430 if left[k] < right[k] { 431 return true 432 } else if left[k] > right[k] { 433 return false 434 } 435 k++ 436 } 437} 438 439func (bindings sortableBindings) Swap(i, j int) { 440 bindings[i], bindings[j] = bindings[j], bindings[i] 441} 442 443func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { 444 for _, binding := range structDescriptor.Fields { 445 shouldOmitEmpty := false 446 tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") 447 for _, tagPart := range tagParts[1:] { 448 if tagPart == "omitempty" { 449 shouldOmitEmpty = true 450 } else if tagPart == "string" { 451 if binding.Field.Type().Kind() == reflect.String { 452 binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} 453 binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} 454 } else { 455 binding.Decoder = &stringModeNumberDecoder{binding.Decoder} 456 binding.Encoder = &stringModeNumberEncoder{binding.Encoder} 457 } 458 } 459 } 460 binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} 461 binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} 462 } 463} 464 465func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { 466 // ignore? 467 if wholeTag == "-" { 468 return []string{} 469 } 470 // rename? 471 var fieldNames []string 472 if tagProvidedFieldName == "" { 473 fieldNames = []string{originalFieldName} 474 } else { 475 fieldNames = []string{tagProvidedFieldName} 476 } 477 // private? 478 isNotExported := unicode.IsLower(rune(originalFieldName[0])) 479 if isNotExported { 480 fieldNames = []string{} 481 } 482 return fieldNames 483} 484