errors.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. package decoder
  17. import (
  18. `encoding/json`
  19. `errors`
  20. `fmt`
  21. `reflect`
  22. `strconv`
  23. `strings`
  24. `github.com/bytedance/sonic/internal/native/types`
  25. `github.com/bytedance/sonic/internal/rt`
  26. )
  27. type SyntaxError struct {
  28. Pos int
  29. Src string
  30. Code types.ParsingError
  31. Msg string
  32. }
  33. func (self SyntaxError) Error() string {
  34. return fmt.Sprintf("%q", self.Description())
  35. }
  36. func (self SyntaxError) Description() string {
  37. return "Syntax error " + self.description()
  38. }
  39. func (self SyntaxError) description() string {
  40. /* check for empty source */
  41. if self.Src == "" {
  42. return fmt.Sprintf("no sources available: %#v", self)
  43. }
  44. p, x, q, y := calcBounds(len(self.Src), self.Pos)
  45. /* compose the error description */
  46. return fmt.Sprintf(
  47. "at index %d: %s\n\n\t%s\n\t%s^%s\n",
  48. self.Pos,
  49. self.Message(),
  50. self.Src[p:q],
  51. strings.Repeat(".", x),
  52. strings.Repeat(".", y),
  53. )
  54. }
  55. func calcBounds(size int, pos int) (lbound int, lwidth int, rbound int, rwidth int) {
  56. if pos >= size || pos < 0 {
  57. return 0, 0, size, 0
  58. }
  59. i := 16
  60. lbound = pos - i
  61. rbound = pos + i
  62. /* prevent slicing before the beginning */
  63. if lbound < 0 {
  64. lbound, rbound, i = 0, rbound - lbound, i + lbound
  65. }
  66. /* prevent slicing beyond the end */
  67. if n := size; rbound > n {
  68. n = rbound - n
  69. rbound = size
  70. /* move the left bound if possible */
  71. if lbound > n {
  72. i += n
  73. lbound -= n
  74. }
  75. }
  76. /* left and right length */
  77. lwidth = clamp_zero(i)
  78. rwidth = clamp_zero(rbound - lbound - i - 1)
  79. return
  80. }
  81. func (self SyntaxError) Message() string {
  82. if self.Msg == "" {
  83. return self.Code.Message()
  84. }
  85. return self.Msg
  86. }
  87. func clamp_zero(v int) int {
  88. if v < 0 {
  89. return 0
  90. } else {
  91. return v
  92. }
  93. }
  94. /** JIT Error Helpers **/
  95. var stackOverflow = &json.UnsupportedValueError {
  96. Str : "Value nesting too deep",
  97. Value : reflect.ValueOf("..."),
  98. }
  99. func error_wrap(src string, pos int, code types.ParsingError) error {
  100. return *error_wrap_heap(src, pos, code)
  101. }
  102. //go:noinline
  103. func error_wrap_heap(src string, pos int, code types.ParsingError) *SyntaxError {
  104. return &SyntaxError {
  105. Pos : pos,
  106. Src : src,
  107. Code : code,
  108. }
  109. }
  110. func error_type(vt *rt.GoType) error {
  111. return &json.UnmarshalTypeError{Type: vt.Pack()}
  112. }
  113. type MismatchTypeError struct {
  114. Pos int
  115. Src string
  116. Type reflect.Type
  117. }
  118. func swithchJSONType (src string, pos int) string {
  119. var val string
  120. switch src[pos] {
  121. case 'f': fallthrough
  122. case 't': val = "bool"
  123. case '"': val = "string"
  124. case '{': val = "object"
  125. case '[': val = "array"
  126. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number"
  127. }
  128. return val
  129. }
  130. func (self MismatchTypeError) Error() string {
  131. se := SyntaxError {
  132. Pos : self.Pos,
  133. Src : self.Src,
  134. Code : types.ERR_MISMATCH,
  135. }
  136. return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
  137. }
  138. func (self MismatchTypeError) Description() string {
  139. se := SyntaxError {
  140. Pos : self.Pos,
  141. Src : self.Src,
  142. Code : types.ERR_MISMATCH,
  143. }
  144. return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
  145. }
  146. func error_mismatch(src string, pos int, vt *rt.GoType) error {
  147. return &MismatchTypeError {
  148. Pos : pos,
  149. Src : src,
  150. Type : vt.Pack(),
  151. }
  152. }
  153. func error_field(name string) error {
  154. return errors.New("json: unknown field " + strconv.Quote(name))
  155. }
  156. func error_value(value string, vtype reflect.Type) error {
  157. return &json.UnmarshalTypeError {
  158. Type : vtype,
  159. Value : value,
  160. }
  161. }