podman
483 строки · 14.2 Кб
1package jsoniter2
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 {21Type reflect2.Type22Fields []*Binding23}
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 {28for _, binding := range structDescriptor.Fields {29if binding.Field.Name() == fieldName {30return binding31}32}33return nil34}
35
36// Binding describe how should we encode/decode the struct field
37type Binding struct {38levels []int39Field reflect2.StructField40FromNames []string41ToNames []string42Encoder ValEncoder
43Decoder 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 {49UpdateStructDescriptor(structDescriptor *StructDescriptor)50CreateMapKeyDecoder(typ reflect2.Type) ValDecoder51CreateMapKeyEncoder(typ reflect2.Type) ValEncoder52CreateDecoder(typ reflect2.Type) ValDecoder53CreateEncoder(typ reflect2.Type) ValEncoder54DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder55DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder56}
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 {68return nil69}
70
71// CreateMapKeyEncoder No-op
72func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {73return nil74}
75
76// CreateDecoder No-op
77func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {78return nil79}
80
81// CreateEncoder No-op
82func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder {83return nil84}
85
86// DecorateDecoder No-op
87func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {88return decoder89}
90
91// DecorateEncoder No-op
92func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {93return encoder94}
95
96type EncoderExtension map[reflect2.Type]ValEncoder97
98// UpdateStructDescriptor No-op
99func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {100}
101
102// CreateDecoder No-op
103func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {104return nil105}
106
107// CreateEncoder get encoder from map
108func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {109return extension[typ]110}
111
112// CreateMapKeyDecoder No-op
113func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {114return nil115}
116
117// CreateMapKeyEncoder No-op
118func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {119return nil120}
121
122// DecorateDecoder No-op
123func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {124return decoder125}
126
127// DecorateEncoder No-op
128func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {129return encoder130}
131
132type DecoderExtension map[reflect2.Type]ValDecoder133
134// UpdateStructDescriptor No-op
135func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {136}
137
138// CreateMapKeyDecoder No-op
139func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {140return nil141}
142
143// CreateMapKeyEncoder No-op
144func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {145return nil146}
147
148// CreateDecoder get decoder from map
149func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {150return extension[typ]151}
152
153// CreateEncoder No-op
154func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {155return nil156}
157
158// DecorateDecoder No-op
159func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {160return decoder161}
162
163// DecorateEncoder No-op
164func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {165return encoder166}
167
168type funcDecoder struct {169fun DecoderFunc
170}
171
172func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {173decoder.fun(ptr, iter)174}
175
176type funcEncoder struct {177fun EncoderFunc
178isEmptyFunc func(ptr unsafe.Pointer) bool179}
180
181func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {182encoder.fun(ptr, stream)183}
184
185func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {186if encoder.isEmptyFunc == nil {187return false188}189return 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) {200typeDecoders[typ] = &funcDecoder{fun}201}
202
203// RegisterTypeDecoder register TypeDecoder for a typ
204func RegisterTypeDecoder(typ string, decoder ValDecoder) {205typeDecoders[typ] = decoder206}
207
208// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function
209func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {210RegisterFieldDecoder(typ, field, &funcDecoder{fun})211}
212
213// RegisterFieldDecoder register TypeDecoder for a struct field
214func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {215fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder216}
217
218// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function
219func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {220typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc}221}
222
223// RegisterTypeEncoder register TypeEncoder for a type
224func RegisterTypeEncoder(typ string, encoder ValEncoder) {225typeEncoders[typ] = encoder226}
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) {230RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc})231}
232
233// RegisterFieldEncoder register TypeEncoder for a struct field
234func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {235fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder236}
237
238// RegisterExtension register extension
239func RegisterExtension(extension Extension) {240extensions = append(extensions, extension)241}
242
243func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {244decoder := _getTypeDecoderFromExtension(ctx, typ)245if decoder != nil {246for _, extension := range extensions {247decoder = extension.DecorateDecoder(typ, decoder)248}249decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder)250for _, extension := range ctx.extraExtensions {251decoder = extension.DecorateDecoder(typ, decoder)252}253}254return decoder255}
256func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {257for _, extension := range extensions {258decoder := extension.CreateDecoder(typ)259if decoder != nil {260return decoder261}262}263decoder := ctx.decoderExtension.CreateDecoder(typ)264if decoder != nil {265return decoder266}267for _, extension := range ctx.extraExtensions {268decoder := extension.CreateDecoder(typ)269if decoder != nil {270return decoder271}272}273typeName := typ.String()274decoder = typeDecoders[typeName]275if decoder != nil {276return decoder277}278if typ.Kind() == reflect.Ptr {279ptrType := typ.(*reflect2.UnsafePtrType)280decoder := typeDecoders[ptrType.Elem().String()]281if decoder != nil {282return &OptionalDecoder{ptrType.Elem(), decoder}283}284}285return nil286}
287
288func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {289encoder := _getTypeEncoderFromExtension(ctx, typ)290if encoder != nil {291for _, extension := range extensions {292encoder = extension.DecorateEncoder(typ, encoder)293}294encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder)295for _, extension := range ctx.extraExtensions {296encoder = extension.DecorateEncoder(typ, encoder)297}298}299return encoder300}
301
302func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {303for _, extension := range extensions {304encoder := extension.CreateEncoder(typ)305if encoder != nil {306return encoder307}308}309encoder := ctx.encoderExtension.CreateEncoder(typ)310if encoder != nil {311return encoder312}313for _, extension := range ctx.extraExtensions {314encoder := extension.CreateEncoder(typ)315if encoder != nil {316return encoder317}318}319typeName := typ.String()320encoder = typeEncoders[typeName]321if encoder != nil {322return encoder323}324if typ.Kind() == reflect.Ptr {325typePtr := typ.(*reflect2.UnsafePtrType)326encoder := typeEncoders[typePtr.Elem().String()]327if encoder != nil {328return &OptionalEncoder{encoder}329}330}331return nil332}
333
334func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {335structType := typ.(*reflect2.UnsafeStructType)336embeddedBindings := []*Binding{}337bindings := []*Binding{}338for i := 0; i < structType.NumField(); i++ {339field := structType.Field(i)340tag, hastag := field.Tag().Lookup(ctx.getTagKey())341if ctx.onlyTaggedField && !hastag && !field.Anonymous() {342continue343}344if tag == "-" || field.Name() == "_" {345continue346}347tagParts := strings.Split(tag, ",")348if field.Anonymous() && (tag == "" || tagParts[0] == "") {349if field.Type().Kind() == reflect.Struct {350structDescriptor := describeStruct(ctx, field.Type())351for _, binding := range structDescriptor.Fields {352binding.levels = append([]int{i}, binding.levels...)353omitempty := binding.Encoder.(*structFieldEncoder).omitempty354binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}355binding.Decoder = &structFieldDecoder{field, binding.Decoder}356embeddedBindings = append(embeddedBindings, binding)357}358continue359} else if field.Type().Kind() == reflect.Ptr {360ptrType := field.Type().(*reflect2.UnsafePtrType)361if ptrType.Elem().Kind() == reflect.Struct {362structDescriptor := describeStruct(ctx, ptrType.Elem())363for _, binding := range structDescriptor.Fields {364binding.levels = append([]int{i}, binding.levels...)365omitempty := binding.Encoder.(*structFieldEncoder).omitempty366binding.Encoder = &dereferenceEncoder{binding.Encoder}367binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}368binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}369binding.Decoder = &structFieldDecoder{field, binding.Decoder}370embeddedBindings = append(embeddedBindings, binding)371}372continue373}374}375}376fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)377fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())378decoder := fieldDecoders[fieldCacheKey]379if decoder == nil {380decoder = decoderOfType(ctx.append(field.Name()), field.Type())381}382encoder := fieldEncoders[fieldCacheKey]383if encoder == nil {384encoder = encoderOfType(ctx.append(field.Name()), field.Type())385}386binding := &Binding{387Field: field,388FromNames: fieldNames,389ToNames: fieldNames,390Decoder: decoder,391Encoder: encoder,392}393binding.levels = []int{i}394bindings = append(bindings, binding)395}396return createStructDescriptor(ctx, typ, bindings, embeddedBindings)397}
398func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {399structDescriptor := &StructDescriptor{400Type: typ,401Fields: bindings,402}403for _, extension := range extensions {404extension.UpdateStructDescriptor(structDescriptor)405}406ctx.encoderExtension.UpdateStructDescriptor(structDescriptor)407ctx.decoderExtension.UpdateStructDescriptor(structDescriptor)408for _, extension := range ctx.extraExtensions {409extension.UpdateStructDescriptor(structDescriptor)410}411processTags(structDescriptor, ctx.frozenConfig)412// merge normal & embedded bindings & sort with original order413allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))414sort.Sort(allBindings)415structDescriptor.Fields = allBindings416return structDescriptor417}
418
419type sortableBindings []*Binding420
421func (bindings sortableBindings) Len() int {422return len(bindings)423}
424
425func (bindings sortableBindings) Less(i, j int) bool {426left := bindings[i].levels427right := bindings[j].levels428k := 0429for {430if left[k] < right[k] {431return true432} else if left[k] > right[k] {433return false434}435k++436}437}
438
439func (bindings sortableBindings) Swap(i, j int) {440bindings[i], bindings[j] = bindings[j], bindings[i]441}
442
443func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {444for _, binding := range structDescriptor.Fields {445shouldOmitEmpty := false446tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",")447for _, tagPart := range tagParts[1:] {448if tagPart == "omitempty" {449shouldOmitEmpty = true450} else if tagPart == "string" {451if binding.Field.Type().Kind() == reflect.String {452binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}453binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}454} else {455binding.Decoder = &stringModeNumberDecoder{binding.Decoder}456binding.Encoder = &stringModeNumberEncoder{binding.Encoder}457}458}459}460binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}461binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty}462}463}
464
465func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {466// ignore?467if wholeTag == "-" {468return []string{}469}470// rename?471var fieldNames []string472if tagProvidedFieldName == "" {473fieldNames = []string{originalFieldName}474} else {475fieldNames = []string{tagProvidedFieldName}476}477// private?478isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_'479if isNotExported {480fieldNames = []string{}481}482return fieldNames483}
484