github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/internal/json/error.go (about) 1 // Copyright 2023 CloudWeGo Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package json 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/cloudwego/dynamicgo/internal/native/types" 22 ) 23 24 type SyntaxError struct { 25 Pos int 26 Src string 27 Code types.ParsingError 28 Msg string 29 } 30 31 func (self SyntaxError) Error() string { 32 return fmt.Sprintf("%q", self.Description()) 33 } 34 35 func (self SyntaxError) Description() string { 36 return "Syntax error " + self.Locate() 37 } 38 39 func (self SyntaxError) Locate() string { 40 i := 16 41 p := self.Pos - i 42 q := self.Pos + i 43 44 /* check for empty source */ 45 if self.Src == "" { 46 return fmt.Sprintf("no sources available: %#v", self) 47 } 48 49 /* prevent slicing before the beginning */ 50 if p < 0 { 51 p, q, i = 0, q-p, i+p 52 } 53 54 /* prevent slicing beyond the end */ 55 if n := len(self.Src); q > n { 56 n = q - n 57 q = len(self.Src) 58 59 /* move the left bound if possible */ 60 if p > n { 61 i += n 62 p -= n 63 } 64 } 65 66 /* left and right length */ 67 x := clamp_zero(i) 68 y := clamp_zero(q - p - i - 1) 69 70 /* compose the error description */ 71 return fmt.Sprintf( 72 "at index %d: %s\n\n\t%s\n\t%s^%s\n", 73 self.Pos, 74 self.Message(), 75 self.Src[p:q], 76 strings.Repeat(".", x), 77 strings.Repeat(".", y), 78 ) 79 } 80 81 func (self SyntaxError) Message() string { 82 if self.Msg == "" { 83 return self.Code.Message() 84 } 85 return self.Msg 86 } 87 88 func clamp_zero(v int) int { 89 if v < 0 { 90 return 0 91 } else { 92 return v 93 } 94 }