diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast/parser.go')
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/parser.go | 766 |
1 files changed, 0 insertions, 766 deletions
diff --git a/vendor/github.com/bytedance/sonic/ast/parser.go b/vendor/github.com/bytedance/sonic/ast/parser.go deleted file mode 100644 index 30bd1f451..000000000 --- a/vendor/github.com/bytedance/sonic/ast/parser.go +++ /dev/null @@ -1,766 +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 ast - -import ( - "fmt" - "sync" - "sync/atomic" - - "github.com/bytedance/sonic/internal/native/types" - "github.com/bytedance/sonic/internal/rt" -) - -const ( - _DEFAULT_NODE_CAP int = 16 - _APPEND_GROW_SHIFT = 1 -) - -const ( - _ERR_NOT_FOUND types.ParsingError = 33 - _ERR_UNSUPPORT_TYPE types.ParsingError = 34 -) - -var ( - // ErrNotExist means both key and value doesn't exist - ErrNotExist error = newError(_ERR_NOT_FOUND, "value not exists") - - // ErrUnsupportType means API on the node is unsupported - ErrUnsupportType error = newError(_ERR_UNSUPPORT_TYPE, "unsupported type") -) - -type Parser struct { - p int - s string - noLazy bool - loadOnce bool - skipValue bool - dbuf *byte -} - -/** Parser Private Methods **/ - -func (self *Parser) delim() types.ParsingError { - n := len(self.s) - p := self.lspace(self.p) - - /* check for EOF */ - if p >= n { - return types.ERR_EOF - } - - /* check for the delimtier */ - if self.s[p] != ':' { - return types.ERR_INVALID_CHAR - } - - /* update the read pointer */ - self.p = p + 1 - return 0 -} - -func (self *Parser) object() types.ParsingError { - n := len(self.s) - p := self.lspace(self.p) - - /* check for EOF */ - if p >= n { - return types.ERR_EOF - } - - /* check for the delimtier */ - if self.s[p] != '{' { - return types.ERR_INVALID_CHAR - } - - /* update the read pointer */ - self.p = p + 1 - return 0 -} - -func (self *Parser) array() types.ParsingError { - n := len(self.s) - p := self.lspace(self.p) - - /* check for EOF */ - if p >= n { - return types.ERR_EOF - } - - /* check for the delimtier */ - if self.s[p] != '[' { - return types.ERR_INVALID_CHAR - } - - /* update the read pointer */ - self.p = p + 1 - return 0 -} - -func (self *Parser) lspace(sp int) int { - ns := len(self.s) - for ; sp<ns && isSpace(self.s[sp]); sp+=1 {} - - return sp -} - -func (self *Parser) backward() { - for ; self.p >= 0 && isSpace(self.s[self.p]); self.p-=1 {} -} - -func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) { - sp := self.p - ns := len(self.s) - - /* check for EOF */ - if self.p = self.lspace(sp); self.p >= ns { - return Node{}, types.ERR_EOF - } - - /* check for empty array */ - if self.s[self.p] == ']' { - self.p++ - return Node{t: types.V_ARRAY}, 0 - } - - /* allocate array space and parse every element */ - for { - var val Node - var err types.ParsingError - - if self.skipValue { - /* skip the value */ - var start int - if start, err = self.skipFast(); err != 0 { - return Node{}, err - } - if self.p > ns { - return Node{}, types.ERR_EOF - } - t := switchRawType(self.s[start]) - if t == _V_NONE { - return Node{}, types.ERR_INVALID_CHAR - } - val = newRawNode(self.s[start:self.p], t, false) - }else{ - /* decode the value */ - if val, err = self.Parse(); err != 0 { - return Node{}, err - } - } - - /* add the value to result */ - ret.Push(val) - self.p = self.lspace(self.p) - - /* check for EOF */ - if self.p >= ns { - return Node{}, types.ERR_EOF - } - - /* check for the next character */ - switch self.s[self.p] { - case ',' : self.p++ - case ']' : self.p++; return newArray(ret), 0 - default: - // if val.isLazy() { - // return newLazyArray(self, ret), 0 - // } - return Node{}, types.ERR_INVALID_CHAR - } - } -} - -func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) { - sp := self.p - ns := len(self.s) - - /* check for EOF */ - if self.p = self.lspace(sp); self.p >= ns { - return Node{}, types.ERR_EOF - } - - /* check for empty object */ - if self.s[self.p] == '}' { - self.p++ - return Node{t: types.V_OBJECT}, 0 - } - - /* decode each pair */ - for { - var val Node - var njs types.JsonState - var err types.ParsingError - - /* decode the key */ - if njs = self.decodeValue(); njs.Vt != types.V_STRING { - return Node{}, types.ERR_INVALID_CHAR - } - - /* extract the key */ - idx := self.p - 1 - key := self.s[njs.Iv:idx] - - /* check for escape sequence */ - if njs.Ep != -1 { - if key, err = unquote(key); err != 0 { - return Node{}, err - } - } - - /* expect a ':' delimiter */ - if err = self.delim(); err != 0 { - return Node{}, err - } - - - if self.skipValue { - /* skip the value */ - var start int - if start, err = self.skipFast(); err != 0 { - return Node{}, err - } - if self.p > ns { - return Node{}, types.ERR_EOF - } - t := switchRawType(self.s[start]) - if t == _V_NONE { - return Node{}, types.ERR_INVALID_CHAR - } - val = newRawNode(self.s[start:self.p], t, false) - } else { - /* decode the value */ - if val, err = self.Parse(); err != 0 { - return Node{}, err - } - } - - /* add the value to result */ - // FIXME: ret's address may change here, thus previous referred node in ret may be invalid !! - ret.Push(NewPair(key, val)) - self.p = self.lspace(self.p) - - /* check for EOF */ - if self.p >= ns { - return Node{}, types.ERR_EOF - } - - /* check for the next character */ - switch self.s[self.p] { - case ',' : self.p++ - case '}' : self.p++; return newObject(ret), 0 - default: - // if val.isLazy() { - // return newLazyObject(self, ret), 0 - // } - return Node{}, types.ERR_INVALID_CHAR - } - } -} - -func (self *Parser) decodeString(iv int64, ep int) (Node, types.ParsingError) { - p := self.p - 1 - s := self.s[iv:p] - - /* fast path: no escape sequence */ - if ep == -1 { - return NewString(s), 0 - } - - /* unquote the string */ - out, err := unquote(s) - - /* check for errors */ - if err != 0 { - return Node{}, err - } else { - return newBytes(rt.Str2Mem(out)), 0 - } -} - -/** Parser Interface **/ - -func (self *Parser) Pos() int { - return self.p -} - - -// Parse returns a ast.Node representing the parser's JSON. -// NOTICE: the specific parsing lazy dependens parser's option -// It only parse first layer and first child for Object or Array be default -func (self *Parser) Parse() (Node, types.ParsingError) { - switch val := self.decodeValue(); val.Vt { - case types.V_EOF : return Node{}, types.ERR_EOF - case types.V_NULL : return nullNode, 0 - case types.V_TRUE : return trueNode, 0 - case types.V_FALSE : return falseNode, 0 - case types.V_STRING : return self.decodeString(val.Iv, val.Ep) - case types.V_ARRAY: - s := self.p - 1; - if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == ']' { - self.p = p + 1 - return Node{t: types.V_ARRAY}, 0 - } - if self.noLazy { - if self.loadOnce { - self.noLazy = false - } - return self.decodeArray(new(linkedNodes)) - } - // NOTICE: loadOnce always keep raw json for object or array - if self.loadOnce { - self.p = s - s, e := self.skipFast() - if e != 0 { - return Node{}, e - } - return newRawNode(self.s[s:self.p], types.V_ARRAY, true), 0 - } - return newLazyArray(self), 0 - case types.V_OBJECT: - s := self.p - 1; - if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == '}' { - self.p = p + 1 - return Node{t: types.V_OBJECT}, 0 - } - // NOTICE: loadOnce always keep raw json for object or array - if self.noLazy { - if self.loadOnce { - self.noLazy = false - } - return self.decodeObject(new(linkedPairs)) - } - if self.loadOnce { - self.p = s - s, e := self.skipFast() - if e != 0 { - return Node{}, e - } - return newRawNode(self.s[s:self.p], types.V_OBJECT, true), 0 - } - return newLazyObject(self), 0 - case types.V_DOUBLE : return NewNumber(self.s[val.Ep:self.p]), 0 - case types.V_INTEGER : return NewNumber(self.s[val.Ep:self.p]), 0 - default : return Node{}, types.ParsingError(-val.Vt) - } -} - -func (self *Parser) searchKey(match string) types.ParsingError { - ns := len(self.s) - if err := self.object(); err != 0 { - return err - } - - /* check for EOF */ - if self.p = self.lspace(self.p); self.p >= ns { - return types.ERR_EOF - } - - /* check for empty object */ - if self.s[self.p] == '}' { - self.p++ - return _ERR_NOT_FOUND - } - - var njs types.JsonState - var err types.ParsingError - /* decode each pair */ - for { - - /* decode the key */ - if njs = self.decodeValue(); njs.Vt != types.V_STRING { - return types.ERR_INVALID_CHAR - } - - /* extract the key */ - idx := self.p - 1 - key := self.s[njs.Iv:idx] - - /* check for escape sequence */ - if njs.Ep != -1 { - if key, err = unquote(key); err != 0 { - return err - } - } - - /* expect a ':' delimiter */ - if err = self.delim(); err != 0 { - return err - } - - /* skip value */ - if key != match { - if _, err = self.skipFast(); err != 0 { - return err - } - } else { - return 0 - } - - /* check for EOF */ - self.p = self.lspace(self.p) - if self.p >= ns { - return types.ERR_EOF - } - - /* check for the next character */ - switch self.s[self.p] { - case ',': - self.p++ - case '}': - self.p++ - return _ERR_NOT_FOUND - default: - return types.ERR_INVALID_CHAR - } - } -} - -func (self *Parser) searchIndex(idx int) types.ParsingError { - ns := len(self.s) - if err := self.array(); err != 0 { - return err - } - - /* check for EOF */ - if self.p = self.lspace(self.p); self.p >= ns { - return types.ERR_EOF - } - - /* check for empty array */ - if self.s[self.p] == ']' { - self.p++ - return _ERR_NOT_FOUND - } - - var err types.ParsingError - /* allocate array space and parse every element */ - for i := 0; i < idx; i++ { - - /* decode the value */ - if _, err = self.skipFast(); err != 0 { - return err - } - - /* check for EOF */ - self.p = self.lspace(self.p) - if self.p >= ns { - return types.ERR_EOF - } - - /* check for the next character */ - switch self.s[self.p] { - case ',': - self.p++ - case ']': - self.p++ - return _ERR_NOT_FOUND - default: - return types.ERR_INVALID_CHAR - } - } - - return 0 -} - -func (self *Node) skipNextNode() *Node { - if !self.isLazy() { - return nil - } - - parser, stack := self.getParserAndArrayStack() - ret := &stack.v - sp := parser.p - ns := len(parser.s) - - /* check for EOF */ - if parser.p = parser.lspace(sp); parser.p >= ns { - return newSyntaxError(parser.syntaxError(types.ERR_EOF)) - } - - /* check for empty array */ - if parser.s[parser.p] == ']' { - parser.p++ - self.setArray(ret) - return nil - } - - var val Node - /* skip the value */ - if start, err := parser.skipFast(); err != 0 { - return newSyntaxError(parser.syntaxError(err)) - } else { - t := switchRawType(parser.s[start]) - if t == _V_NONE { - return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) - } - val = newRawNode(parser.s[start:parser.p], t, false) - } - - /* add the value to result */ - ret.Push(val) - self.l++ - parser.p = parser.lspace(parser.p) - - /* check for EOF */ - if parser.p >= ns { - return newSyntaxError(parser.syntaxError(types.ERR_EOF)) - } - - /* check for the next character */ - switch parser.s[parser.p] { - case ',': - parser.p++ - return ret.At(ret.Len()-1) - case ']': - parser.p++ - self.setArray(ret) - return ret.At(ret.Len()-1) - default: - return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) - } -} - -func (self *Node) skipNextPair() (*Pair) { - if !self.isLazy() { - return nil - } - - parser, stack := self.getParserAndObjectStack() - ret := &stack.v - sp := parser.p - ns := len(parser.s) - - /* check for EOF */ - if parser.p = parser.lspace(sp); parser.p >= ns { - return newErrorPair(parser.syntaxError(types.ERR_EOF)) - } - - /* check for empty object */ - if parser.s[parser.p] == '}' { - parser.p++ - self.setObject(ret) - return nil - } - - /* decode one pair */ - var val Node - var njs types.JsonState - var err types.ParsingError - - /* decode the key */ - if njs = parser.decodeValue(); njs.Vt != types.V_STRING { - return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) - } - - /* extract the key */ - idx := parser.p - 1 - key := parser.s[njs.Iv:idx] - - /* check for escape sequence */ - if njs.Ep != -1 { - if key, err = unquote(key); err != 0 { - return newErrorPair(parser.syntaxError(err)) - } - } - - /* expect a ':' delimiter */ - if err = parser.delim(); err != 0 { - return newErrorPair(parser.syntaxError(err)) - } - - /* skip the value */ - if start, err := parser.skipFast(); err != 0 { - return newErrorPair(parser.syntaxError(err)) - } else { - t := switchRawType(parser.s[start]) - if t == _V_NONE { - return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) - } - val = newRawNode(parser.s[start:parser.p], t, false) - } - - /* add the value to result */ - ret.Push(NewPair(key, val)) - self.l++ - parser.p = parser.lspace(parser.p) - - /* check for EOF */ - if parser.p >= ns { - return newErrorPair(parser.syntaxError(types.ERR_EOF)) - } - - /* check for the next character */ - switch parser.s[parser.p] { - case ',': - parser.p++ - return ret.At(ret.Len()-1) - case '}': - parser.p++ - self.setObject(ret) - return ret.At(ret.Len()-1) - default: - return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) - } -} - - -/** Parser Factory **/ - -// Loads parse all json into interface{} -func Loads(src string) (int, interface{}, error) { - ps := &Parser{s: src} - np, err := ps.Parse() - - /* check for errors */ - if err != 0 { - return 0, nil, ps.ExportError(err) - } else { - x, err := np.Interface() - if err != nil { - return 0, nil, err - } - return ps.Pos(), x, nil - } -} - -// LoadsUseNumber parse all json into interface{}, with numeric nodes casted to json.Number -func LoadsUseNumber(src string) (int, interface{}, error) { - ps := &Parser{s: src} - np, err := ps.Parse() - - /* check for errors */ - if err != 0 { - return 0, nil, err - } else { - x, err := np.InterfaceUseNumber() - if err != nil { - return 0, nil, err - } - return ps.Pos(), x, nil - } -} - -// NewParser returns pointer of new allocated parser -func NewParser(src string) *Parser { - return &Parser{s: src} -} - -// NewParser returns new allocated parser -func NewParserObj(src string) Parser { - return Parser{s: src} -} - -// decodeNumber controls if parser decodes the number values instead of skip them -// WARN: once you set decodeNumber(true), please set decodeNumber(false) before you drop the parser -// otherwise the memory CANNOT be reused -func (self *Parser) decodeNumber(decode bool) { - if !decode && self.dbuf != nil { - types.FreeDbuf(self.dbuf) - self.dbuf = nil - return - } - if decode && self.dbuf == nil { - self.dbuf = types.NewDbuf() - } -} - -// ExportError converts types.ParsingError to std Error -func (self *Parser) ExportError(err types.ParsingError) error { - if err == _ERR_NOT_FOUND { - return ErrNotExist - } - return fmt.Errorf("%q", SyntaxError{ - Pos : self.p, - Src : self.s, - Code: err, - }.Description()) -} - -func backward(src string, i int) int { - for ; i>=0 && isSpace(src[i]); i-- {} - return i -} - - -func newRawNode(str string, typ types.ValueType, lock bool) Node { - ret := Node{ - t: typ | _V_RAW, - p: rt.StrPtr(str), - l: uint(len(str)), - } - if lock { - ret.m = new(sync.RWMutex) - } - return ret -} - -var typeJumpTable = [256]types.ValueType{ - '"' : types.V_STRING, - '-' : _V_NUMBER, - '0' : _V_NUMBER, - '1' : _V_NUMBER, - '2' : _V_NUMBER, - '3' : _V_NUMBER, - '4' : _V_NUMBER, - '5' : _V_NUMBER, - '6' : _V_NUMBER, - '7' : _V_NUMBER, - '8' : _V_NUMBER, - '9' : _V_NUMBER, - '[' : types.V_ARRAY, - 'f' : types.V_FALSE, - 'n' : types.V_NULL, - 't' : types.V_TRUE, - '{' : types.V_OBJECT, -} - -func switchRawType(c byte) types.ValueType { - return typeJumpTable[c] -} - -func (self *Node) loadt() types.ValueType { - return (types.ValueType)(atomic.LoadInt64(&self.t)) -} - -func (self *Node) lock() bool { - if m := self.m; m != nil { - m.Lock() - return true - } - return false -} - -func (self *Node) unlock() { - if m := self.m; m != nil { - m.Unlock() - } -} - -func (self *Node) rlock() bool { - if m := self.m; m != nil { - m.RLock() - return true - } - return false -} - -func (self *Node) runlock() { - if m := self.m; m != nil { - m.RUnlock() - } -} |