error.go raw
1 package ast
2
3 import (
4 `fmt`
5 `strings`
6 `unsafe`
7
8 `github.com/bytedance/sonic/internal/native/types`
9 )
10
11
12 func newError(err types.ParsingError, msg string) *Node {
13 return &Node{
14 t: V_ERROR,
15 l: uint(err),
16 p: unsafe.Pointer(&msg),
17 }
18 }
19
20 func newErrorPair(err SyntaxError) *Pair {
21 return &Pair{0, "", *newSyntaxError(err)}
22 }
23
24 // Error returns error message if the node is invalid
25 func (self Node) Error() string {
26 if self.t != V_ERROR {
27 return ""
28 } else {
29 return *(*string)(self.p)
30 }
31 }
32
33 func newSyntaxError(err SyntaxError) *Node {
34 msg := err.Description()
35 return &Node{
36 t: V_ERROR,
37 l: uint(err.Code),
38 p: unsafe.Pointer(&msg),
39 }
40 }
41
42 func (self *Parser) syntaxError(err types.ParsingError) SyntaxError {
43 return SyntaxError{
44 Pos : self.p,
45 Src : self.s,
46 Code: err,
47 }
48 }
49
50 func unwrapError(err error) *Node {
51 if se, ok := err.(*Node); ok {
52 return se
53 }else if sse, ok := err.(Node); ok {
54 return &sse
55 } else {
56 msg := err.Error()
57 return &Node{
58 t: V_ERROR,
59 p: unsafe.Pointer(&msg),
60 }
61 }
62 }
63
64 type SyntaxError struct {
65 Pos int
66 Src string
67 Code types.ParsingError
68 Msg string
69 }
70
71 func (self SyntaxError) Error() string {
72 return fmt.Sprintf("%q", self.Description())
73 }
74
75 func (self SyntaxError) Description() string {
76 return "Syntax error " + self.description()
77 }
78
79 func (self SyntaxError) description() string {
80 i := 16
81 p := self.Pos - i
82 q := self.Pos + i
83
84 /* check for empty source */
85 if self.Src == "" {
86 return fmt.Sprintf("no sources available, the input json is empty: %#v", self)
87 }
88
89 /* prevent slicing before the beginning */
90 if p < 0 {
91 p, q, i = 0, q - p, i + p
92 }
93
94 /* prevent slicing beyond the end */
95 if n := len(self.Src); q > n {
96 n = q - n
97 q = len(self.Src)
98
99 /* move the left bound if possible */
100 if p > n {
101 i += n
102 p -= n
103 }
104 }
105
106 /* left and right length */
107 x := clamp_zero(i)
108 y := clamp_zero(q - p - i - 1)
109
110 /* compose the error description */
111 return fmt.Sprintf(
112 "at index %d: %s\n\n\t%s\n\t%s^%s\n",
113 self.Pos,
114 self.Message(),
115 self.Src[p:q],
116 strings.Repeat(".", x),
117 strings.Repeat(".", y),
118 )
119 }
120
121 func (self SyntaxError) Message() string {
122 if self.Msg == "" {
123 return self.Code.Message()
124 }
125 return self.Msg
126 }
127
128 func clamp_zero(v int) int {
129 if v < 0 {
130 return 0
131 } else {
132 return v
133 }
134 }
135