errors.go (4220B)
1 /* 2 * Copyright 2021 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package decoder 18 19 import ( 20 `encoding/json` 21 `errors` 22 `fmt` 23 `reflect` 24 `strconv` 25 `strings` 26 27 `github.com/bytedance/sonic/internal/native/types` 28 `github.com/bytedance/sonic/internal/rt` 29 ) 30 31 type SyntaxError struct { 32 Pos int 33 Src string 34 Code types.ParsingError 35 Msg string 36 } 37 38 func (self SyntaxError) Error() string { 39 return fmt.Sprintf("%q", self.Description()) 40 } 41 42 func (self SyntaxError) Description() string { 43 return "Syntax error " + self.description() 44 } 45 46 func (self SyntaxError) description() string { 47 i := 16 48 p := self.Pos - i 49 q := self.Pos + i 50 51 /* check for empty source */ 52 if self.Src == "" { 53 return fmt.Sprintf("no sources available: %#v", self) 54 } 55 56 /* prevent slicing before the beginning */ 57 if p < 0 { 58 p, q, i = 0, q - p, i + p 59 } 60 61 /* prevent slicing beyond the end */ 62 if n := len(self.Src); q > n { 63 n = q - n 64 q = len(self.Src) 65 66 /* move the left bound if possible */ 67 if p > n { 68 i += n 69 p -= n 70 } 71 } 72 73 /* left and right length */ 74 x := clamp_zero(i) 75 y := clamp_zero(q - p - i - 1) 76 77 /* compose the error description */ 78 return fmt.Sprintf( 79 "at index %d: %s\n\n\t%s\n\t%s^%s\n", 80 self.Pos, 81 self.Message(), 82 self.Src[p:q], 83 strings.Repeat(".", x), 84 strings.Repeat(".", y), 85 ) 86 } 87 88 func (self SyntaxError) Message() string { 89 if self.Msg == "" { 90 return self.Code.Message() 91 } 92 return self.Msg 93 } 94 95 func clamp_zero(v int) int { 96 if v < 0 { 97 return 0 98 } else { 99 return v 100 } 101 } 102 103 /** JIT Error Helpers **/ 104 105 var stackOverflow = &json.UnsupportedValueError { 106 Str : "Value nesting too deep", 107 Value : reflect.ValueOf("..."), 108 } 109 110 //go:nosplit 111 func error_wrap(src string, pos int, code types.ParsingError) error { 112 return SyntaxError { 113 Pos : pos, 114 Src : src, 115 Code : code, 116 } 117 } 118 119 //go:nosplit 120 func error_type(vt *rt.GoType) error { 121 return &json.UnmarshalTypeError{Type: vt.Pack()} 122 } 123 124 type MismatchTypeError struct { 125 Pos int 126 Src string 127 Type reflect.Type 128 } 129 130 func swithchJSONType (src string, pos int) string { 131 var val string 132 switch src[pos] { 133 case 'f': fallthrough 134 case 't': val = "bool" 135 case '"': val = "string" 136 case '{': val = "object" 137 case '[': val = "array" 138 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number" 139 } 140 return val 141 } 142 143 func (self MismatchTypeError) Error() string { 144 se := SyntaxError { 145 Pos : self.Pos, 146 Src : self.Src, 147 Code : types.ERR_MISMATCH, 148 } 149 return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) 150 } 151 152 func (self MismatchTypeError) Description() string { 153 se := SyntaxError { 154 Pos : self.Pos, 155 Src : self.Src, 156 Code : types.ERR_MISMATCH, 157 } 158 return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description()) 159 } 160 161 //go:nosplit 162 func error_mismatch(src string, pos int, vt *rt.GoType) error { 163 return &MismatchTypeError { 164 Pos : pos, 165 Src : src, 166 Type : vt.Pack(), 167 } 168 } 169 170 //go:nosplit 171 func error_field(name string) error { 172 return errors.New("json: unknown field " + strconv.Quote(name)) 173 } 174 175 //go:nosplit 176 func error_value(value string, vtype reflect.Type) error { 177 return &json.UnmarshalTypeError { 178 Type : vtype, 179 Value : value, 180 } 181 }