github.com/3JoB/go-json@v0.10.4/internal/decoder/compile.go (about) 1 package decoder 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "sync/atomic" 8 "unicode" 9 "unsafe" 10 11 "github.com/3JoB/go-reflect" 12 13 "github.com/3JoB/go-json/internal/runtime" 14 ) 15 16 var ( 17 jsonNumberType = reflect.TypeOf(json.Number("")) 18 typeAddr *runtime.TypeAddr 19 cachedDecoderMap unsafe.Pointer // map[uintptr]decoder 20 cachedDecoder []Decoder 21 ) 22 23 func init() { 24 typeAddr = runtime.AnalyzeTypeAddr() 25 if typeAddr == nil { 26 typeAddr = &runtime.TypeAddr{} 27 } 28 cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift+1) 29 } 30 31 func loadDecoderMap() map[uintptr]Decoder { 32 p := atomic.LoadPointer(&cachedDecoderMap) 33 return *(*map[uintptr]Decoder)(unsafe.Pointer(&p)) 34 } 35 36 func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) { 37 newDecoderMap := make(map[uintptr]Decoder, len(m)+1) 38 newDecoderMap[typ] = dec 39 40 for k, v := range m { 41 newDecoderMap[k] = v 42 } 43 44 atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap))) 45 } 46 47 func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) { 48 decoderMap := loadDecoderMap() 49 if dec, exists := decoderMap[typeptr]; exists { 50 return dec, nil 51 } 52 53 dec, err := compileHead(typ, map[uintptr]Decoder{}) 54 if err != nil { 55 return nil, err 56 } 57 storeDecoder(typeptr, dec, decoderMap) 58 return dec, nil 59 } 60 61 func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 62 switch { 63 case implementsUnmarshalJSONType(runtime.PtrTo(typ)): 64 return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil 65 case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)): 66 return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil 67 } 68 return compile(typ.Elem(), "", "", structTypeToDecoder) 69 } 70 71 func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 72 switch { 73 case implementsUnmarshalJSONType(runtime.PtrTo(typ)): 74 return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil 75 case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)): 76 return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil 77 } 78 79 switch typ.Kind() { 80 case reflect.Ptr: 81 return compilePtr(typ, structName, fieldName, structTypeToDecoder) 82 case reflect.Struct: 83 return compileStruct(typ, structName, fieldName, structTypeToDecoder) 84 case reflect.Slice: 85 elem := typ.Elem() 86 if elem.Kind() == reflect.Uint8 { 87 return compileBytes(elem, structName, fieldName) 88 } 89 return compileSlice(typ, structName, fieldName, structTypeToDecoder) 90 case reflect.Array: 91 return compileArray(typ, structName, fieldName, structTypeToDecoder) 92 case reflect.Map: 93 return compileMap(typ, structName, fieldName, structTypeToDecoder) 94 case reflect.Interface: 95 return compileInterface(typ, structName, fieldName) 96 case reflect.Uintptr: 97 return compileUint(typ, structName, fieldName) 98 case reflect.Int: 99 return compileInt(typ, structName, fieldName) 100 case reflect.Int8: 101 return compileInt8(typ, structName, fieldName) 102 case reflect.Int16: 103 return compileInt16(typ, structName, fieldName) 104 case reflect.Int32: 105 return compileInt32(typ, structName, fieldName) 106 case reflect.Int64: 107 return compileInt64(typ, structName, fieldName) 108 case reflect.Uint: 109 return compileUint(typ, structName, fieldName) 110 case reflect.Uint8: 111 return compileUint8(typ, structName, fieldName) 112 case reflect.Uint16: 113 return compileUint16(typ, structName, fieldName) 114 case reflect.Uint32: 115 return compileUint32(typ, structName, fieldName) 116 case reflect.Uint64: 117 return compileUint64(typ, structName, fieldName) 118 case reflect.String: 119 return compileString(typ, structName, fieldName) 120 case reflect.Bool: 121 return compileBool(structName, fieldName) 122 case reflect.Float32: 123 return compileFloat32(structName, fieldName) 124 case reflect.Float64: 125 return compileFloat64(structName, fieldName) 126 case reflect.Func: 127 return compileFunc(typ, structName, fieldName) 128 } 129 return newInvalidDecoder(typ, structName, fieldName), nil 130 } 131 132 func isStringTagSupportedType(typ *runtime.Type) bool { 133 switch { 134 case implementsUnmarshalJSONType(runtime.PtrTo(typ)): 135 return false 136 case runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)): 137 return false 138 } 139 switch typ.Kind() { 140 case reflect.Map: 141 return false 142 case reflect.Slice: 143 return false 144 case reflect.Array: 145 return false 146 case reflect.Struct: 147 return false 148 case reflect.Interface: 149 return false 150 } 151 return true 152 } 153 154 func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 155 if runtime.PtrTo(typ).Implements(reflect.ToRT(unmarshalTextType)) { 156 return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil 157 } 158 if typ.Kind() == reflect.String { 159 return newStringDecoder(structName, fieldName), nil 160 } 161 dec, err := compile(typ, structName, fieldName, structTypeToDecoder) 162 if err != nil { 163 return nil, err 164 } 165 for { 166 switch t := dec.(type) { 167 case *stringDecoder, *interfaceDecoder: 168 return dec, nil 169 case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder: 170 return newWrappedStringDecoder(typ, dec, structName, fieldName), nil 171 case *ptrDecoder: 172 dec = t.dec 173 default: 174 return newInvalidDecoder(typ, structName, fieldName), nil 175 } 176 } 177 } 178 179 func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 180 dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) 181 if err != nil { 182 return nil, err 183 } 184 return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil 185 } 186 187 func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 188 return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { 189 *(*int)(p) = int(v) 190 }), nil 191 } 192 193 func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 194 return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { 195 *(*int8)(p) = int8(v) 196 }), nil 197 } 198 199 func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 200 return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { 201 *(*int16)(p) = int16(v) 202 }), nil 203 } 204 205 func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 206 return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { 207 *(*int32)(p) = int32(v) 208 }), nil 209 } 210 211 func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 212 return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { 213 *(*int64)(p) = v 214 }), nil 215 } 216 217 func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 218 return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { 219 *(*uint)(p) = uint(v) 220 }), nil 221 } 222 223 func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 224 return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { 225 *(*uint8)(p) = uint8(v) 226 }), nil 227 } 228 229 func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 230 return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { 231 *(*uint16)(p) = uint16(v) 232 }), nil 233 } 234 235 func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 236 return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { 237 *(*uint32)(p) = uint32(v) 238 }), nil 239 } 240 241 func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 242 return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { 243 *(*uint64)(p) = v 244 }), nil 245 } 246 247 func compileFloat32(structName, fieldName string) (Decoder, error) { 248 return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 249 *(*float32)(p) = float32(v) 250 }), nil 251 } 252 253 func compileFloat64(structName, fieldName string) (Decoder, error) { 254 return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 255 *(*float64)(p) = v 256 }), nil 257 } 258 259 func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 260 if typ == runtime.Type2RType(reflect.ToRT(jsonNumberType)) { 261 return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { 262 *(*json.Number)(p) = v 263 }), nil 264 } 265 return newStringDecoder(structName, fieldName), nil 266 } 267 268 func compileBool(structName, fieldName string) (Decoder, error) { 269 return newBoolDecoder(structName, fieldName), nil 270 } 271 272 func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 273 return newBytesDecoder(typ, structName, fieldName), nil 274 } 275 276 func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 277 elem := typ.Elem() 278 decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) 279 if err != nil { 280 return nil, err 281 } 282 return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil 283 } 284 285 func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 286 elem := typ.Elem() 287 decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) 288 if err != nil { 289 return nil, err 290 } 291 return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil 292 } 293 294 func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 295 keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder) 296 if err != nil { 297 return nil, err 298 } 299 valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) 300 if err != nil { 301 return nil, err 302 } 303 return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil 304 } 305 306 func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) { 307 return newInterfaceDecoder(typ, structName, fieldName), nil 308 } 309 310 func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) { 311 return newFuncDecoder(typ, strutName, fieldName), nil 312 } 313 314 func typeToStructTags(typ *runtime.Type) runtime.StructTags { 315 tags := runtime.StructTags{} 316 fieldNum := typ.NumField() 317 for i := 0; i < fieldNum; i++ { 318 field := typ.Field(i) 319 if runtime.IsIgnoredStructField(field) { 320 continue 321 } 322 tags = append(tags, runtime.StructTagFromField(field)) 323 } 324 return tags 325 } 326 327 func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { 328 fieldNum := typ.NumField() 329 fieldMap := map[string]*structFieldSet{} 330 typeptr := uintptr(unsafe.Pointer(typ)) 331 if dec, exists := structTypeToDecoder[typeptr]; exists { 332 return dec, nil 333 } 334 structDec := newStructDecoder(structName, fieldName, fieldMap) 335 structTypeToDecoder[typeptr] = structDec 336 structName = typ.Name() 337 tags := typeToStructTags(typ) 338 allFields := []*structFieldSet{} 339 for i := 0; i < fieldNum; i++ { 340 field := typ.Field(i) 341 if runtime.IsIgnoredStructField(field) { 342 continue 343 } 344 isUnexportedField := unicode.IsLower([]rune(field.Name)[0]) 345 tag := runtime.StructTagFromField(field) 346 dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder) 347 if err != nil { 348 return nil, err 349 } 350 if field.Anonymous && !tag.IsTaggedKey { 351 if stDec, ok := dec.(*structDecoder); ok { 352 if runtime.Type2RType(field.Type) == typ { 353 // recursive definition 354 continue 355 } 356 for k, v := range stDec.fieldMap { 357 if tags.ExistsKey(k) { 358 continue 359 } 360 fieldSet := &structFieldSet{ 361 dec: v.dec, 362 offset: field.Offset + v.offset, 363 isTaggedKey: v.isTaggedKey, 364 key: k, 365 keyLen: int64(len(k)), 366 } 367 allFields = append(allFields, fieldSet) 368 } 369 } else if pdec, ok := dec.(*ptrDecoder); ok { 370 contentDec := pdec.contentDecoder() 371 if pdec.typ == typ { 372 // recursive definition 373 continue 374 } 375 var fieldSetErr error 376 if isUnexportedField { 377 fieldSetErr = fmt.Errorf( 378 "json: cannot set embedded pointer to unexported struct: %v", 379 field.Type.Elem(), 380 ) 381 } 382 if dec, ok := contentDec.(*structDecoder); ok { 383 for k, v := range dec.fieldMap { 384 if tags.ExistsKey(k) { 385 continue 386 } 387 fieldSet := &structFieldSet{ 388 dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec), 389 offset: field.Offset, 390 isTaggedKey: v.isTaggedKey, 391 key: k, 392 keyLen: int64(len(k)), 393 err: fieldSetErr, 394 } 395 allFields = append(allFields, fieldSet) 396 } 397 } else { 398 fieldSet := &structFieldSet{ 399 dec: pdec, 400 offset: field.Offset, 401 isTaggedKey: tag.IsTaggedKey, 402 key: field.Name, 403 keyLen: int64(len(field.Name)), 404 } 405 allFields = append(allFields, fieldSet) 406 } 407 } else { 408 fieldSet := &structFieldSet{ 409 dec: dec, 410 offset: field.Offset, 411 isTaggedKey: tag.IsTaggedKey, 412 key: field.Name, 413 keyLen: int64(len(field.Name)), 414 } 415 allFields = append(allFields, fieldSet) 416 } 417 } else { 418 if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) { 419 dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name) 420 } 421 var key string 422 if tag.Key != "" { 423 key = tag.Key 424 } else { 425 key = field.Name 426 } 427 fieldSet := &structFieldSet{ 428 dec: dec, 429 offset: field.Offset, 430 isTaggedKey: tag.IsTaggedKey, 431 key: key, 432 keyLen: int64(len(key)), 433 } 434 allFields = append(allFields, fieldSet) 435 } 436 } 437 for _, set := range filterDuplicatedFields(allFields) { 438 fieldMap[set.key] = set 439 lower := strings.ToLower(set.key) 440 if _, exists := fieldMap[lower]; !exists { 441 // first win 442 fieldMap[lower] = set 443 } 444 } 445 delete(structTypeToDecoder, typeptr) 446 structDec.tryOptimize() 447 return structDec, nil 448 } 449 450 func filterDuplicatedFields(allFields []*structFieldSet) []*structFieldSet { 451 fieldMap := map[string][]*structFieldSet{} 452 for _, field := range allFields { 453 fieldMap[field.key] = append(fieldMap[field.key], field) 454 } 455 duplicatedFieldMap := map[string]struct{}{} 456 for k, sets := range fieldMap { 457 sets = filterFieldSets(sets) 458 if len(sets) != 1 { 459 duplicatedFieldMap[k] = struct{}{} 460 } 461 } 462 463 filtered := make([]*structFieldSet, 0, len(allFields)) 464 for _, field := range allFields { 465 if _, exists := duplicatedFieldMap[field.key]; exists { 466 continue 467 } 468 filtered = append(filtered, field) 469 } 470 return filtered 471 } 472 473 func filterFieldSets(sets []*structFieldSet) []*structFieldSet { 474 if len(sets) == 1 { 475 return sets 476 } 477 filtered := make([]*structFieldSet, 0, len(sets)) 478 for _, set := range sets { 479 if set.isTaggedKey { 480 filtered = append(filtered, set) 481 } 482 } 483 return filtered 484 } 485 486 func implementsUnmarshalJSONType(typ *runtime.Type) bool { 487 return typ.Implements(reflect.ToRT(unmarshalJSONType)) || typ.Implements(reflect.ToRT(unmarshalJSONContextType)) 488 }