error.go 2.6 KB

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