feature_reflect_extension.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package jsoniter
  2. import (
  3. "reflect"
  4. "fmt"
  5. "unsafe"
  6. "strings"
  7. "unicode"
  8. )
  9. var typeDecoders = map[string]ValDecoder{}
  10. var fieldDecoders = map[string]ValDecoder{}
  11. var typeEncoders = map[string]ValEncoder{}
  12. var fieldEncoders = map[string]ValEncoder{}
  13. var extensions = []Extension{}
  14. type StructDescriptor struct {
  15. Type reflect.Type
  16. Fields map[string]*Binding
  17. }
  18. type Binding struct {
  19. Field *reflect.StructField
  20. FromNames []string
  21. ToNames []string
  22. ShouldOmitEmpty bool
  23. Encoder ValEncoder
  24. Decoder ValDecoder
  25. }
  26. type Extension interface {
  27. UpdateStructDescriptor(structDescriptor *StructDescriptor)
  28. CreateDecoder(typ reflect.Type) ValDecoder
  29. CreateEncoder(typ reflect.Type) ValEncoder
  30. }
  31. type DummyExtension struct {
  32. }
  33. func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
  34. }
  35. func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder {
  36. return nil
  37. }
  38. func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
  39. return nil
  40. }
  41. type funcDecoder struct {
  42. fun DecoderFunc
  43. }
  44. func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
  45. typeDecoders[typ] = &funcDecoder{fun}
  46. }
  47. func RegisterTypeDecoder(typ string, decoder ValDecoder) {
  48. typeDecoders[typ] = decoder
  49. }
  50. func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {
  51. RegisterFieldDecoder(typ, field, &funcDecoder{fun})
  52. }
  53. func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
  54. fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder
  55. }
  56. func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
  57. typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc}
  58. }
  59. func RegisterTypeEncoder(typ string, encoder ValEncoder) {
  60. typeEncoders[typ] = encoder
  61. }
  62. func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
  63. RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc})
  64. }
  65. func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
  66. fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
  67. }
  68. func RegisterExtension(extension Extension) {
  69. extensions = append(extensions, extension)
  70. }
  71. func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
  72. for _, extension := range extensions {
  73. decoder := extension.CreateDecoder(typ)
  74. if decoder != nil {
  75. return decoder
  76. }
  77. }
  78. typeName := typ.String()
  79. decoder := typeDecoders[typeName]
  80. if decoder != nil {
  81. return decoder
  82. }
  83. if typ.Kind() == reflect.Ptr {
  84. decoder := typeDecoders[typ.Elem().String()]
  85. if decoder != nil {
  86. return &optionalDecoder{typ.Elem(), decoder}
  87. }
  88. }
  89. return nil
  90. }
  91. func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
  92. for _, extension := range extensions {
  93. encoder := extension.CreateEncoder(typ)
  94. if encoder != nil {
  95. return encoder
  96. }
  97. }
  98. typeName := typ.String()
  99. encoder := typeEncoders[typeName]
  100. if encoder != nil {
  101. return encoder
  102. }
  103. if typ.Kind() == reflect.Ptr {
  104. encoder := typeEncoders[typ.Elem().String()]
  105. if encoder != nil {
  106. return &optionalEncoder{encoder}
  107. }
  108. }
  109. return nil
  110. }
  111. func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
  112. bindings := map[string]*Binding{}
  113. for _, field := range listStructFields(typ) {
  114. tagParts := strings.Split(field.Tag.Get("json"), ",")
  115. fieldNames := calcFieldNames(field.Name, tagParts[0])
  116. fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
  117. decoder := fieldDecoders[fieldCacheKey]
  118. if decoder == nil && len(fieldNames) > 0 {
  119. var err error
  120. decoder, err = decoderOfType(cfg, field.Type)
  121. if err != nil {
  122. return nil, err
  123. }
  124. }
  125. encoder := fieldEncoders[fieldCacheKey]
  126. if encoder == nil && len(fieldNames) > 0 {
  127. var err error
  128. encoder, err = encoderOfType(cfg, field.Type)
  129. if err != nil {
  130. return nil, err
  131. }
  132. // map is stored as pointer in the struct
  133. if field.Type.Kind() == reflect.Map {
  134. encoder = &optionalEncoder{encoder}
  135. }
  136. }
  137. binding := &Binding{
  138. Field: field,
  139. FromNames: fieldNames,
  140. ToNames: fieldNames,
  141. Decoder: decoder,
  142. Encoder: encoder,
  143. }
  144. for _, tagPart := range tagParts[1:] {
  145. if tagPart == "omitempty" {
  146. binding.ShouldOmitEmpty = true
  147. } else if tagPart == "string" {
  148. binding.Decoder = &stringModeDecoder{binding.Decoder}
  149. binding.Encoder = &stringModeEncoder{binding.Encoder}
  150. }
  151. }
  152. bindings[field.Name] = binding
  153. }
  154. structDescriptor := &StructDescriptor{
  155. Type: typ,
  156. Fields: bindings,
  157. }
  158. for _, extension := range extensions {
  159. extension.UpdateStructDescriptor(structDescriptor)
  160. }
  161. return structDescriptor, nil
  162. }
  163. func listStructFields(typ reflect.Type) []*reflect.StructField {
  164. fields := []*reflect.StructField{}
  165. for i := 0; i < typ.NumField(); i++ {
  166. field := typ.Field(i)
  167. if field.Anonymous {
  168. fields = append(fields, listStructFields(field.Type)...)
  169. } else {
  170. fields = append(fields, &field)
  171. }
  172. }
  173. return fields
  174. }
  175. func calcFieldNames(originalFieldName string, tagProvidedFieldName string) []string {
  176. // tag => exported? => original
  177. isNotExported := unicode.IsLower(rune(originalFieldName[0]))
  178. var fieldNames []string
  179. /// tagParts[0] always present, even if no tags
  180. switch tagProvidedFieldName {
  181. case "":
  182. if isNotExported {
  183. fieldNames = []string{}
  184. } else {
  185. fieldNames = []string{originalFieldName}
  186. }
  187. case "-":
  188. fieldNames = []string{}
  189. default:
  190. fieldNames = []string{tagProvidedFieldName}
  191. }
  192. return fieldNames
  193. }