Scan scans the next token and populates its information into lval. This scan function contains rules for jsonpath.
(lval ScanSymType)
| 18 | // Scan scans the next token and populates its information into lval. |
| 19 | // This scan function contains rules for jsonpath. |
| 20 | func (s *JSONPathScanner) Scan(lval ScanSymType) { |
| 21 | ch, skipWhiteSpace := s.scanSetup(lval, false /* allowComments */) |
| 22 | if skipWhiteSpace { |
| 23 | return |
| 24 | } |
| 25 | |
| 26 | // TODO(normanchenn): We still need to handle $.Xe where X is any digit. |
| 27 | switch ch { |
| 28 | case '$': |
| 29 | // Root path ($) |
| 30 | if s.peek() == '.' || s.peek() == eof || s.peek() == ' ' || s.peek() == '[' || s.peek() == ')' || s.peek() == '?' { |
| 31 | lval.SetID(lexbase.ROOT) |
| 32 | return |
| 33 | } |
| 34 | |
| 35 | // Handle variables like $var, $1a, $"var", etc. |
| 36 | if s.peek() == identQuote { |
| 37 | s.pos++ |
| 38 | if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) { |
| 39 | lval.SetID(lexbase.VARIABLE) |
| 40 | } |
| 41 | return |
| 42 | } |
| 43 | s.pos++ |
| 44 | s.scanIdent(lval) |
| 45 | lval.SetID(lexbase.VARIABLE) |
| 46 | return |
| 47 | case identQuote: |
| 48 | // "[^"]" |
| 49 | // When scanning string literals for like_regex patterns, we need to |
| 50 | // consider how to handle escape characters similarly to Postgres. |
| 51 | // See: https://www.postgresql.org/docs/current/functions-json.html#JSONPATH-REGULAR-EXPRESSIONS, |
| 52 | // "any backslashes you want to use in the regular expression must be doubled". |
| 53 | // |
| 54 | // With allowEscapes == true, |
| 55 | // - String literal input "^\\$" is scanned as "^\\$" (one escaped backslash) |
| 56 | // - This matches the behaviour of Postgres. |
| 57 | // With allowEscapes == false, |
| 58 | // - String literal input "^\\$" is scanned as "^\\\\$" (two escaped backslashes) |
| 59 | if s.scanString(lval, identQuote, true /* allowEscapes */, true /* requireUTF8 */) { |
| 60 | lval.SetID(lexbase.STR) |
| 61 | } |
| 62 | return |
| 63 | case '=': |
| 64 | if s.peek() == '=' { // == |
| 65 | s.pos++ |
| 66 | lval.SetID(lexbase.EQUAL) |
| 67 | return |
| 68 | } |
| 69 | return |
| 70 | case '!': |
| 71 | if s.peek() == '=' { // != |
| 72 | s.pos++ |
| 73 | lval.SetID(lexbase.NOT_EQUAL) |
| 74 | return |
| 75 | } |
| 76 | lval.SetID(lexbase.NOT) |
| 77 | return |
nothing calls this directly
no test coverage detected