1
2
3
4 package jreader
5
6
7
8
9
10
11
12 import (
13 "fmt"
14 "strings"
15
16 "github.com/mailru/easyjson/jlexer"
17 )
18
19 type tokenReader struct {
20
21 pLexer *jlexer.Lexer
22
23
24 inlineLexer jlexer.Lexer
25 posBeforeCallingNull int
26 posAfterCallingNull int
27 posBeforeValue int
28 }
29
30 func newTokenReader(data []byte) tokenReader {
31 return tokenReader{inlineLexer: jlexer.Lexer{Data: data}}
32 }
33
34 func newTokenReaderFromEasyjsonLexer(lexer *jlexer.Lexer) tokenReader {
35 return tokenReader{pLexer: lexer}
36 }
37
38 func (tr *tokenReader) EOF() bool {
39 pLexer := tr.pLexer
40 if pLexer == nil {
41 pLexer = &tr.inlineLexer
42 }
43 if pLexer.Error() != nil {
44 return true
45 }
46 pLexer.Consumed()
47 return pLexer.Error() == nil
48 }
49
50 func (tr *tokenReader) LastPos() int {
51 if tr.pLexer == nil {
52 return tr.inlineLexer.GetPos()
53 }
54 return tr.pLexer.GetPos()
55 }
56
57 func (tr *tokenReader) Null() (bool, error) {
58 pLexer := tr.pLexer
59 if pLexer == nil {
60 pLexer = &tr.inlineLexer
61 }
62
63
64
65 tr.posBeforeCallingNull = pLexer.GetPos()
66 if pLexer.IsNull() {
67
68 if err := pLexer.Error(); err != nil {
69 return false, tr.translateLexerError()
70 }
71 pLexer.Null()
72 return true, nil
73 }
74 tr.posAfterCallingNull = pLexer.GetPos()
75 return false, tr.translateLexerError()
76 }
77
78 func (tr *tokenReader) Bool() (bool, error) {
79 pLexer := tr.pLexer
80 if pLexer == nil {
81 pLexer = &tr.inlineLexer
82 }
83 tr.markPosBeforeValue()
84 val := pLexer.Bool()
85 if pLexer.Error() == nil {
86 return val, nil
87 }
88 return false, tr.translateLexerErrorWithExpectedType(BoolValue)
89 }
90
91 func (tr *tokenReader) Number() (float64, error) {
92 pLexer := tr.pLexer
93 if pLexer == nil {
94 pLexer = &tr.inlineLexer
95 }
96 tr.markPosBeforeValue()
97 val := pLexer.Float64()
98 if pLexer.Error() == nil {
99 return val, nil
100 }
101 return 0, tr.translateLexerErrorWithExpectedType(NumberValue)
102 }
103
104 func (tr *tokenReader) String() (string, error) {
105 pLexer := tr.pLexer
106 if pLexer == nil {
107 pLexer = &tr.inlineLexer
108 }
109 tr.markPosBeforeValue()
110 val := pLexer.String()
111 if pLexer.Error() == nil {
112 return val, nil
113 }
114 return "", tr.translateLexerErrorWithExpectedType(StringValue)
115 }
116
117 func (tr *tokenReader) PropertyName() ([]byte, error) {
118 pLexer := tr.pLexer
119 if pLexer == nil {
120 pLexer = &tr.inlineLexer
121 }
122 val := pLexer.UnsafeBytes()
123 if err := pLexer.Error(); err != nil {
124 return nil, tr.translateLexerError()
125 }
126 pLexer.WantColon()
127 pLexer.FetchToken()
128 return val, tr.translateLexerError()
129 }
130
131 func (tr *tokenReader) Delimiter(delim byte) (bool, error) {
132 pLexer := tr.pLexer
133 if pLexer == nil {
134 pLexer = &tr.inlineLexer
135 }
136 if err := pLexer.Error(); err != nil {
137 return false, tr.translateLexerError()
138 }
139 found := false
140 if pLexer.IsDelim(byte(delim)) {
141 pLexer.Delim(delim)
142 found = true
143 }
144
145 if err := pLexer.Error(); err != nil {
146 return false, tr.translateLexerError()
147 }
148 return found, nil
149 }
150
151 func (tr *tokenReader) EndDelimiterOrComma(delim byte) (bool, error) {
152 pLexer := tr.pLexer
153 if pLexer == nil {
154 pLexer = &tr.inlineLexer
155 }
156 if pLexer.Error() != nil {
157 return false, tr.translateLexerError()
158 }
159 pLexer.WantComma()
160 if pLexer.IsDelim(delim) {
161 pLexer.Delim(delim)
162 return true, nil
163 }
164 return false, tr.translateLexerError()
165 }
166
167 func (tr *tokenReader) Any() (AnyValue, error) {
168 pLexer := tr.pLexer
169 if pLexer == nil {
170 pLexer = &tr.inlineLexer
171 }
172 value, err := readAnyValue(pLexer)
173 if err != nil {
174 return AnyValue{}, tr.translateLexerError()
175 }
176 return value, nil
177 }
178
179 func (tr *tokenReader) lexerError() error {
180 if tr.pLexer == nil {
181 return tr.inlineLexer.Error()
182 }
183 return tr.pLexer.Error()
184 }
185
186 func readAnyValue(lexer *jlexer.Lexer) (AnyValue, error) {
187 if lexer.IsDelim('[') {
188
189 if err := lexer.Error(); err != nil {
190 return AnyValue{}, err
191 }
192 lexer.Delim('[')
193 return AnyValue{Kind: ArrayValue}, nil
194 }
195 if lexer.IsDelim('{') {
196 if err := lexer.Error(); err != nil {
197 return AnyValue{}, err
198 }
199 lexer.Delim('{')
200 return AnyValue{Kind: ObjectValue}, nil
201 }
202 intf := lexer.Interface()
203 if err := lexer.Error(); err != nil {
204 return AnyValue{}, err
205 }
206 if intf == nil {
207 return AnyValue{Kind: NullValue}, nil
208 }
209 switch v := intf.(type) {
210 case bool:
211 return AnyValue{Kind: BoolValue, Bool: v}, nil
212 case int:
213 return AnyValue{Kind: NumberValue, Number: float64(v)}, nil
214 case float64:
215 return AnyValue{Kind: NumberValue, Number: v}, nil
216 case string:
217 return AnyValue{Kind: StringValue, String: v}, nil
218 }
219 return AnyValue{}, fmt.Errorf("Lexer.Interface() returned unrecognized type %T", intf)
220 }
221
222 func (tr *tokenReader) markPosBeforeValue() {
223 pos := tr.LastPos()
224 if pos == tr.posAfterCallingNull {
225 pos = tr.posBeforeCallingNull
226 }
227 }
228
229 func (tr *tokenReader) translateLexerError() error {
230 return tr.translateLexerErrorWithExpectedType(-1)
231 }
232
233 func (tr *tokenReader) translateLexerErrorWithExpectedType(expectedType ValueKind) error {
234 pLexer := tr.pLexer
235 if pLexer == nil {
236 pLexer = &tr.inlineLexer
237 }
238 originalError := pLexer.Error()
239 if originalError == nil {
240 return nil
241 }
242 le, ok := originalError.(*jlexer.LexerError)
243 if !ok {
244 return originalError
245 }
246 if strings.HasPrefix(le.Reason, "expected ") && expectedType >= 0 {
247
248
249
250 tempLexer := jlexer.Lexer{Data: pLexer.Data[tr.posBeforeValue:]}
251 value, err := readAnyValue(&tempLexer)
252 if err != nil {
253 return translateLexerParseError(err)
254 }
255 return TypeError{Expected: expectedType, Actual: value.Kind, Offset: tr.posBeforeValue}
256 }
257 return translateLexerParseError(originalError)
258 }
259
260 func translateLexerParseError(err error) error {
261 if le, ok := err.(*jlexer.LexerError); ok {
262 return SyntaxError{Message: strings.TrimPrefix(le.Reason, "parse error: "), Offset: le.Offset}
263 }
264 return err
265 }
266
View as plain text