diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/resolver/resolver.go')
-rw-r--r-- | vendor/github.com/bytedance/sonic/internal/resolver/resolver.go | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/resolver/resolver.go b/vendor/github.com/bytedance/sonic/internal/resolver/resolver.go deleted file mode 100644 index 795434f4e..000000000 --- a/vendor/github.com/bytedance/sonic/internal/resolver/resolver.go +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2021 ByteDance Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package resolver - -import ( - `fmt` - `reflect` - `strings` - `sync` -) - -type FieldOpts int -type OffsetType int - -const ( - F_omitempty FieldOpts = 1 << iota - F_stringize -) - -const ( - F_offset OffsetType = iota - F_deref -) - -type Offset struct { - Size uintptr - Kind OffsetType - Type reflect.Type -} - -type FieldMeta struct { - Name string - Path []Offset - Opts FieldOpts - Type reflect.Type -} - -func (self *FieldMeta) String() string { - var path []string - var opts []string - - /* dump the field path */ - for _, off := range self.Path { - if off.Kind == F_offset { - path = append(path, fmt.Sprintf("%d", off.Size)) - } else { - path = append(path, fmt.Sprintf("%d.(*%s)", off.Size, off.Type)) - } - } - - /* check for "string" */ - if (self.Opts & F_stringize) != 0 { - opts = append(opts, "string") - } - - /* check for "omitempty" */ - if (self.Opts & F_omitempty) != 0 { - opts = append(opts, "omitempty") - } - - /* format the field */ - return fmt.Sprintf( - "{Field \"%s\" @ %s, opts=%s, type=%s}", - self.Name, - strings.Join(path, "."), - strings.Join(opts, ","), - self.Type, - ) -} - -func (self *FieldMeta) optimize() { - var n int - var v uintptr - - /* merge adjacent offsets */ - for _, o := range self.Path { - if v += o.Size; o.Kind == F_deref { - self.Path[n].Size = v - self.Path[n].Type, v = o.Type, 0 - self.Path[n].Kind, n = F_deref, n + 1 - } - } - - /* last offset value */ - if v != 0 { - self.Path[n].Size = v - self.Path[n].Type = nil - self.Path[n].Kind = F_offset - n++ - } - - /* must be at least 1 offset */ - if n != 0 { - self.Path = self.Path[:n] - } else { - self.Path = []Offset{{Kind: F_offset}} - } -} - -func resolveFields(vt reflect.Type) []FieldMeta { - tfv := typeFields(vt) - ret := []FieldMeta(nil) - - /* convert each field */ - for _, fv := range tfv.list { - item := vt - path := []Offset(nil) - opts := FieldOpts(0) - - /* check for "string" */ - if fv.quoted { - opts |= F_stringize - } - - /* check for "omitempty" */ - if fv.omitEmpty { - opts |= F_omitempty - } - - /* dump the field path */ - for _, i := range fv.index { - kind := F_offset - fval := item.Field(i) - item = fval.Type - - /* deref the pointer if needed */ - if item.Kind() == reflect.Ptr { - kind = F_deref - item = item.Elem() - } - - /* add to path */ - path = append(path, Offset { - Kind: kind, - Type: item, - Size: fval.Offset, - }) - } - - /* get the index to the last offset */ - idx := len(path) - 1 - fvt := path[idx].Type - - /* do not dereference into fields */ - if path[idx].Kind == F_deref { - fvt = reflect.PtrTo(fvt) - path[idx].Kind = F_offset - } - - /* add to result */ - ret = append(ret, FieldMeta { - Type: fvt, - Opts: opts, - Path: path, - Name: fv.name, - }) - } - - /* optimize the offsets */ - for i := range ret { - ret[i].optimize() - } - - /* all done */ - return ret -} - -var ( - fieldLock = sync.RWMutex{} - fieldCache = map[reflect.Type][]FieldMeta{} -) - -func ResolveStruct(vt reflect.Type) []FieldMeta { - var ok bool - var fm []FieldMeta - - /* attempt to read from cache */ - fieldLock.RLock() - fm, ok = fieldCache[vt] - fieldLock.RUnlock() - - /* check if it was cached */ - if ok { - return fm - } - - /* otherwise use write-lock */ - fieldLock.Lock() - defer fieldLock.Unlock() - - /* double check */ - if fm, ok = fieldCache[vt]; ok { - return fm - } - - /* resolve the field */ - fm = resolveFields(vt) - fieldCache[vt] = fm - return fm -} |