1
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
48 if self.Src == "" {
49 return fmt.Sprintf("no sources available: %#v", self)
50 }
51
52 p, x, q, y := calcBounds(len(self.Src), self.Pos)
53
54
55 return fmt.Sprintf(
56 "at index %d: %s\n\n\t%s\n\t%s^%s\n",
57 self.Pos,
58 self.Message(),
59 self.Src[p:q],
60 strings.Repeat(".", x),
61 strings.Repeat(".", y),
62 )
63 }
64
65 func calcBounds(size int, pos int) (lbound int, lwidth int, rbound int, rwidth int) {
66 if pos >= size || pos < 0 {
67 return 0, 0, size, 0
68 }
69
70 i := 16
71 lbound = pos - i
72 rbound = pos + i
73
74
75 if lbound < 0 {
76 lbound, rbound, i = 0, rbound - lbound, i + lbound
77 }
78
79
80 if n := size; rbound > n {
81 n = rbound - n
82 rbound = size
83
84
85 if lbound > n {
86 i += n
87 lbound -= n
88 }
89 }
90
91
92 lwidth = clamp_zero(i)
93 rwidth = clamp_zero(rbound - lbound - i - 1)
94
95 return
96 }
97
98 func (self SyntaxError) Message() string {
99 if self.Msg == "" {
100 return self.Code.Message()
101 }
102 return self.Msg
103 }
104
105 func clamp_zero(v int) int {
106 if v < 0 {
107 return 0
108 } else {
109 return v
110 }
111 }
112
113
114
115 var stackOverflow = &json.UnsupportedValueError {
116 Str : "Value nesting too deep",
117 Value : reflect.ValueOf("..."),
118 }
119
120 func error_wrap(src string, pos int, code types.ParsingError) error {
121 return *error_wrap_heap(src, pos, code)
122 }
123
124
125 func error_wrap_heap(src string, pos int, code types.ParsingError) *SyntaxError {
126 return &SyntaxError {
127 Pos : pos,
128 Src : src,
129 Code : code,
130 }
131 }
132
133 func error_type(vt *rt.GoType) error {
134 return &json.UnmarshalTypeError{Type: vt.Pack()}
135 }
136
137 type MismatchTypeError struct {
138 Pos int
139 Src string
140 Type reflect.Type
141 }
142
143 func swithchJSONType (src string, pos int) string {
144 var val string
145 switch src[pos] {
146 case 'f': fallthrough
147 case 't': val = "bool"
148 case '"': val = "string"
149 case '{': val = "object"
150 case '[': val = "array"
151 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number"
152 }
153 return val
154 }
155
156 func (self MismatchTypeError) Error() string {
157 se := SyntaxError {
158 Pos : self.Pos,
159 Src : self.Src,
160 Code : types.ERR_MISMATCH,
161 }
162 return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
163 }
164
165 func (self MismatchTypeError) Description() string {
166 se := SyntaxError {
167 Pos : self.Pos,
168 Src : self.Src,
169 Code : types.ERR_MISMATCH,
170 }
171 return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
172 }
173
174 func error_mismatch(src string, pos int, vt *rt.GoType) error {
175 return &MismatchTypeError {
176 Pos : pos,
177 Src : src,
178 Type : vt.Pack(),
179 }
180 }
181
182 func error_field(name string) error {
183 return errors.New("json: unknown field " + strconv.Quote(name))
184 }
185
186 func error_value(value string, vtype reflect.Type) error {
187 return &json.UnmarshalTypeError {
188 Type : vtype,
189 Value : value,
190 }
191 }
192
View as plain text