diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/decoder/errors.go')
-rw-r--r-- | vendor/github.com/bytedance/sonic/decoder/errors.go | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/decoder/errors.go b/vendor/github.com/bytedance/sonic/decoder/errors.go new file mode 100644 index 000000000..c905fdfb0 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/decoder/errors.go @@ -0,0 +1,181 @@ +/* + * 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 decoder + +import ( + `encoding/json` + `errors` + `fmt` + `reflect` + `strconv` + `strings` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` +) + +type SyntaxError struct { + Pos int + Src string + Code types.ParsingError + Msg string +} + +func (self SyntaxError) Error() string { + return fmt.Sprintf("%q", self.Description()) +} + +func (self SyntaxError) Description() string { + return "Syntax error " + self.description() +} + +func (self SyntaxError) description() string { + i := 16 + p := self.Pos - i + q := self.Pos + i + + /* check for empty source */ + if self.Src == "" { + return fmt.Sprintf("no sources available: %#v", self) + } + + /* prevent slicing before the beginning */ + if p < 0 { + p, q, i = 0, q - p, i + p + } + + /* prevent slicing beyond the end */ + if n := len(self.Src); q > n { + n = q - n + q = len(self.Src) + + /* move the left bound if possible */ + if p > n { + i += n + p -= n + } + } + + /* left and right length */ + x := clamp_zero(i) + y := clamp_zero(q - p - i - 1) + + /* compose the error description */ + return fmt.Sprintf( + "at index %d: %s\n\n\t%s\n\t%s^%s\n", + self.Pos, + self.Message(), + self.Src[p:q], + strings.Repeat(".", x), + strings.Repeat(".", y), + ) +} + +func (self SyntaxError) Message() string { + if self.Msg == "" { + return self.Code.Message() + } + return self.Msg +} + +func clamp_zero(v int) int { + if v < 0 { + return 0 + } else { + return v + } +} + +/** JIT Error Helpers **/ + +var stackOverflow = &json.UnsupportedValueError { + Str : "Value nesting too deep", + Value : reflect.ValueOf("..."), +} + +//go:nosplit +func error_wrap(src string, pos int, code types.ParsingError) error { + return SyntaxError { + Pos : pos, + Src : src, + Code : code, + } +} + +//go:nosplit +func error_type(vt *rt.GoType) error { + return &json.UnmarshalTypeError{Type: vt.Pack()} +} + +type MismatchTypeError struct { + Pos int + Src string + Type reflect.Type +} + +func swithchJSONType (src string, pos int) string { + var val string + switch src[pos] { + case 'f': fallthrough + case 't': val = "bool" + case '"': val = "string" + case '{': val = "object" + case '[': val = "array" + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number" + } + return val +} + +func (self MismatchTypeError) Error() string { + se := SyntaxError { + Pos : self.Pos, + Src : self.Src, + Code : types.ERR_MISMATCH, + } + return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) +} + +func (self MismatchTypeError) Description() string { + se := SyntaxError { + Pos : self.Pos, + Src : self.Src, + Code : types.ERR_MISMATCH, + } + return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) +} + +//go:nosplit +func error_mismatch(src string, pos int, vt *rt.GoType) error { + return &MismatchTypeError { + Pos : pos, + Src : src, + Type : vt.Pack(), + } +} + +//go:nosplit +func error_field(name string) error { + return errors.New("json: unknown field " + strconv.Quote(name)) +} + +//go:nosplit +func error_value(value string, vtype reflect.Type) error { + return &json.UnmarshalTypeError { + Type : vtype, + Value : value, + } +} |