Skip to main content

squawk_parser/
lib.rs

1// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/lib.rs
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27use drop_bomb::DropBomb;
28use event::Event;
29use grammar::OPERATOR_FIRST;
30use std::cell::Cell;
31use token_set::TokenSet;
32mod event;
33mod generated;
34mod grammar;
35mod input;
36mod lexed_str;
37mod output;
38mod plpgsql_grammar;
39mod shortcuts;
40mod syntax_kind;
41mod token_set;
42
43pub use crate::{
44    lexed_str::LexedStr,
45    // output::{Output, Step},
46    shortcuts::StrStep,
47    syntax_kind::{
48        SyntaxKind, is_col_name_keyword, is_reserved_keyword, is_type_func_name_keyword,
49    },
50};
51
52use crate::input::Input;
53pub use crate::output::Output;
54
55/// See [`Parser::start`].
56pub(crate) struct Marker {
57    pos: u32,
58    bomb: DropBomb,
59}
60
61impl Marker {
62    fn new(pos: u32) -> Marker {
63        Marker {
64            pos,
65            bomb: DropBomb::new("Marker must be either completed or abandoned"),
66        }
67    }
68
69    /// Finishes the syntax tree node and assigns `kind` to it,
70    /// and mark the create a `CompletedMarker` for possible future
71    /// operation like `.precede()` to deal with `forward_parent`.
72    pub(crate) fn complete(mut self, p: &mut Parser<'_>, kind: SyntaxKind) -> CompletedMarker {
73        self.bomb.defuse();
74        let idx = self.pos as usize;
75        match &mut p.events[idx] {
76            Event::Start { kind: slot, .. } => {
77                *slot = kind;
78            }
79            _ => unreachable!(),
80        }
81        p.push_event(Event::Finish);
82        CompletedMarker::new(self.pos, kind)
83    }
84
85    /// Abandons the syntax tree node. All its children
86    /// are attached to its parent instead.
87    pub(crate) fn abandon(mut self, p: &mut Parser<'_>) {
88        self.bomb.defuse();
89        let idx = self.pos as usize;
90        if idx == p.events.len() - 1 {
91            match p.events.pop() {
92                Some(Event::Start {
93                    kind: SyntaxKind::TOMBSTONE,
94                    forward_parent: None,
95                }) => (),
96                _ => unreachable!(),
97            }
98        }
99    }
100}
101
102pub(crate) struct CompletedMarker {
103    pos: u32,
104    kind: SyntaxKind,
105}
106
107impl CompletedMarker {
108    fn new(pos: u32, kind: SyntaxKind) -> Self {
109        CompletedMarker { pos, kind }
110    }
111
112    /// This method allows to create a new node which starts
113    /// *before* the current one. That is, parser could start
114    /// node `A`, then complete it, and then after parsing the
115    /// whole `A`, decide that it should have started some node
116    /// `B` before starting `A`. `precede` allows to do exactly
117    /// that. See also docs about
118    /// [`Event::Start::forward_parent`](crate::event::Event::Start::forward_parent).
119    ///
120    /// Given completed events `[START, FINISH]` and its corresponding
121    /// `CompletedMarker(pos: 0, _)`.
122    /// Append a new `START` events as `[START, FINISH, NEWSTART]`,
123    /// then mark `NEWSTART` as `START`'s parent with saving its relative
124    /// distance to `NEWSTART` into `forward_parent`(=2 in this case);
125    pub(crate) fn precede(self, p: &mut Parser<'_>) -> Marker {
126        let new_pos = p.start();
127        let idx = self.pos as usize;
128        match &mut p.events[idx] {
129            Event::Start { forward_parent, .. } => {
130                *forward_parent = Some(new_pos.pos - self.pos);
131            }
132            _ => unreachable!(),
133        }
134        new_pos
135    }
136
137    /// Extends this completed marker *to the left* up to `m`.
138    pub(crate) fn extend_to(self, p: &mut Parser<'_>, mut m: Marker) -> CompletedMarker {
139        m.bomb.defuse();
140        let idx = m.pos as usize;
141        match &mut p.events[idx] {
142            Event::Start { forward_parent, .. } => {
143                *forward_parent = Some(self.pos - m.pos);
144            }
145            _ => unreachable!(),
146        }
147        self
148    }
149
150    pub(crate) fn kind(&self) -> SyntaxKind {
151        self.kind
152    }
153}
154
155#[derive(Clone, Copy, Debug)]
156pub enum EntryPoint {
157    SourceFile,
158    Plpgsql,
159}
160
161impl EntryPoint {
162    pub fn parse(&self, input: &Input) -> Output {
163        let mut p = Parser::new(input);
164        // 2. lex tokens to event vec via parser aka actually run the parser code,
165        // it calls the methods on the parser to create a vector of events
166        match self {
167            Self::SourceFile => grammar::entry_point(&mut p),
168            Self::Plpgsql => plpgsql_grammar::plpgsql_entry_point(&mut p),
169        }
170        let events = p.finish();
171        // 3. forward parents
172        event::process(events)
173    }
174}
175
176pub(crate) struct Parser<'t> {
177    inp: &'t Input,
178    pos: usize,
179    limit: usize,
180    events: Vec<Event>,
181    steps: Cell<u32>,
182}
183
184const PARSER_STEP_LIMIT: usize = 15_000_000;
185
186enum TrivaBetween {
187    NotAllowed,
188    Allowed,
189}
190
191const OPERATOR_SIGN: TokenSet = TokenSet::new(&[SyntaxKind::PLUS, SyntaxKind::MINUS]);
192
193/// In order for an operator to end in `+` or `-`, it must contain one of the
194/// following chars:
195///
196/// ```sql
197/// ~ ! @ # % ^ & | ` ?
198/// ```
199///
200/// see: <https://www.postgresql.org/docs/18/sql-createoperator.html>
201const SPECIAL_OP_CHARS: TokenSet = TokenSet::new(&[
202    SyntaxKind::TILDE,
203    SyntaxKind::BANG,
204    SyntaxKind::AT,
205    SyntaxKind::POUND,
206    SyntaxKind::PERCENT,
207    SyntaxKind::CARET,
208    SyntaxKind::AMP,
209    SyntaxKind::PIPE,
210    SyntaxKind::BACKTICK,
211    SyntaxKind::QUESTION,
212]);
213
214impl<'t> Parser<'t> {
215    fn new(inp: &'t Input) -> Parser<'t> {
216        Parser {
217            inp,
218            pos: 0,
219            limit: usize::MAX,
220            events: vec![],
221            steps: Cell::new(0),
222        }
223    }
224
225    // Part of a hack to support pl/pgsql loops where we have to stop at `loop`
226    pub(crate) fn with_limit<T>(&mut self, n: usize, f: impl FnOnce(&mut Parser<'t>) -> T) -> T {
227        let limit = self.limit;
228        self.limit = limit.min(self.pos + n);
229        let res = f(self);
230        self.limit = limit;
231        res
232    }
233
234    fn kind_at(&self, idx: usize) -> SyntaxKind {
235        if idx >= self.limit {
236            return SyntaxKind::EOF;
237        }
238        self.inp.kind(idx)
239    }
240
241    fn contextual_kind_at(&self, idx: usize) -> SyntaxKind {
242        if idx >= self.limit {
243            return SyntaxKind::EOF;
244        }
245        self.inp.contextual_kind(idx)
246    }
247
248    fn is_joint_at(&self, idx: usize) -> bool {
249        idx + 1 < self.limit && self.inp.is_joint(idx)
250    }
251
252    /// Consume the next token if `kind` matches.
253    pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
254        if !self.at(kind) {
255            return false;
256        }
257        let n_raw_tokens = match kind {
258            SyntaxKind::COLON_EQ
259            | SyntaxKind::NEQ
260            | SyntaxKind::NEQB
261            | SyntaxKind::LTEQ
262            | SyntaxKind::FAT_ARROW
263            | SyntaxKind::LESS_LESS
264            | SyntaxKind::GREATER_GREATER
265            | SyntaxKind::GTEQ => 2,
266            SyntaxKind::SIMILAR_TO => {
267                let m = self.start();
268                self.bump(SyntaxKind::SIMILAR_KW);
269                self.bump(SyntaxKind::TO_KW);
270                m.complete(self, SyntaxKind::SIMILAR_TO);
271                return true;
272            }
273            SyntaxKind::AT_TIME_ZONE => {
274                let m = self.start();
275                self.bump(SyntaxKind::AT_KW);
276                self.bump(SyntaxKind::TIME_KW);
277                self.bump(SyntaxKind::ZONE_KW);
278                m.complete(self, SyntaxKind::AT_TIME_ZONE);
279                return true;
280            }
281            SyntaxKind::AT_LOCAL => {
282                let m = self.start();
283                self.bump(SyntaxKind::AT_KW);
284                self.bump(SyntaxKind::LOCAL_KW);
285                m.complete(self, SyntaxKind::AT_LOCAL);
286                return true;
287            }
288            SyntaxKind::IS_NOT_NORMALIZED => {
289                let m = self.start();
290                self.bump(SyntaxKind::IS_KW);
291                self.bump(SyntaxKind::NOT_KW);
292                if matches!(
293                    self.current(),
294                    SyntaxKind::NFC_KW
295                        | SyntaxKind::NFD_KW
296                        | SyntaxKind::NFKC_KW
297                        | SyntaxKind::NFKD_KW
298                ) {
299                    let fm = self.start();
300                    self.bump_any();
301                    fm.complete(self, SyntaxKind::UNICODE_NORMAL_FORM);
302                }
303                self.bump(SyntaxKind::NORMALIZED_KW);
304                m.complete(self, SyntaxKind::IS_NOT_NORMALIZED);
305                return true;
306            }
307            SyntaxKind::IS_NORMALIZED => {
308                let m = self.start();
309                self.bump(SyntaxKind::IS_KW);
310                if matches!(
311                    self.current(),
312                    SyntaxKind::NFC_KW
313                        | SyntaxKind::NFD_KW
314                        | SyntaxKind::NFKC_KW
315                        | SyntaxKind::NFKD_KW
316                ) {
317                    let fm = self.start();
318                    self.bump_any();
319                    fm.complete(self, SyntaxKind::UNICODE_NORMAL_FORM);
320                }
321                self.bump(SyntaxKind::NORMALIZED_KW);
322                m.complete(self, SyntaxKind::IS_NORMALIZED);
323                return true;
324            }
325            SyntaxKind::COLON_COLON => {
326                let m = self.start();
327                self.bump(SyntaxKind::COLON);
328                self.bump(SyntaxKind::COLON);
329                m.complete(self, SyntaxKind::COLON_COLON);
330                return true;
331            }
332            SyntaxKind::IS_JSON => {
333                let m = self.start();
334                self.bump(SyntaxKind::IS_KW);
335                self.bump(SyntaxKind::JSON_KW);
336                grammar::opt_json_keys_unique_clause(self);
337                m.complete(self, SyntaxKind::IS_JSON);
338                return true;
339            }
340            SyntaxKind::IS_NOT_JSON => {
341                let m = self.start();
342                self.bump(SyntaxKind::IS_KW);
343                self.bump(SyntaxKind::NOT_KW);
344                self.bump(SyntaxKind::JSON_KW);
345                grammar::opt_json_keys_unique_clause(self);
346                m.complete(self, SyntaxKind::IS_NOT_JSON);
347                return true;
348            }
349            SyntaxKind::IS_NOT_JSON_OBJECT => {
350                let m = self.start();
351                self.bump(SyntaxKind::IS_KW);
352                self.bump(SyntaxKind::NOT_KW);
353                self.bump(SyntaxKind::JSON_KW);
354                self.bump(SyntaxKind::OBJECT_KW);
355                grammar::opt_json_keys_unique_clause(self);
356                m.complete(self, SyntaxKind::IS_NOT_JSON_OBJECT);
357                return true;
358            }
359            SyntaxKind::IS_NOT_JSON_ARRAY => {
360                let m = self.start();
361                self.bump(SyntaxKind::IS_KW);
362                self.bump(SyntaxKind::NOT_KW);
363                self.bump(SyntaxKind::JSON_KW);
364                self.bump(SyntaxKind::ARRAY_KW);
365                grammar::opt_json_keys_unique_clause(self);
366                m.complete(self, SyntaxKind::IS_NOT_JSON_ARRAY);
367                return true;
368            }
369            SyntaxKind::IS_NOT_JSON_VALUE => {
370                let m = self.start();
371                self.bump(SyntaxKind::IS_KW);
372                self.bump(SyntaxKind::NOT_KW);
373                self.bump(SyntaxKind::JSON_KW);
374                self.bump(SyntaxKind::VALUE_KW);
375                grammar::opt_json_keys_unique_clause(self);
376                m.complete(self, SyntaxKind::IS_NOT_JSON_VALUE);
377                return true;
378            }
379            SyntaxKind::IS_NOT_JSON_SCALAR => {
380                let m = self.start();
381                self.bump(SyntaxKind::IS_KW);
382                self.bump(SyntaxKind::NOT_KW);
383                self.bump(SyntaxKind::JSON_KW);
384                self.bump(SyntaxKind::SCALAR_KW);
385                grammar::opt_json_keys_unique_clause(self);
386                m.complete(self, SyntaxKind::IS_NOT_JSON_SCALAR);
387                return true;
388            }
389            SyntaxKind::IS_JSON_OBJECT => {
390                let m = self.start();
391                self.bump(SyntaxKind::IS_KW);
392                self.bump(SyntaxKind::JSON_KW);
393                self.bump(SyntaxKind::OBJECT_KW);
394                grammar::opt_json_keys_unique_clause(self);
395                m.complete(self, SyntaxKind::IS_JSON_OBJECT);
396                return true;
397            }
398            SyntaxKind::IS_JSON_ARRAY => {
399                let m = self.start();
400                self.bump(SyntaxKind::IS_KW);
401                self.bump(SyntaxKind::JSON_KW);
402                self.bump(SyntaxKind::ARRAY_KW);
403                grammar::opt_json_keys_unique_clause(self);
404                m.complete(self, SyntaxKind::IS_JSON_ARRAY);
405                return true;
406            }
407            SyntaxKind::IS_JSON_VALUE => {
408                let m = self.start();
409                self.bump(SyntaxKind::IS_KW);
410                self.bump(SyntaxKind::JSON_KW);
411                self.bump(SyntaxKind::VALUE_KW);
412                grammar::opt_json_keys_unique_clause(self);
413                m.complete(self, SyntaxKind::IS_JSON_VALUE);
414                return true;
415            }
416            SyntaxKind::IS_JSON_SCALAR => {
417                let m = self.start();
418                self.bump(SyntaxKind::IS_KW);
419                self.bump(SyntaxKind::JSON_KW);
420                self.bump(SyntaxKind::SCALAR_KW);
421                grammar::opt_json_keys_unique_clause(self);
422                m.complete(self, SyntaxKind::IS_JSON_SCALAR);
423                return true;
424            }
425            SyntaxKind::NOT_SIMILAR_TO => {
426                let m = self.start();
427                self.bump(SyntaxKind::NOT_KW);
428                self.bump(SyntaxKind::SIMILAR_KW);
429                self.bump(SyntaxKind::TO_KW);
430                m.complete(self, SyntaxKind::NOT_SIMILAR_TO);
431                return true;
432            }
433            SyntaxKind::IS_NOT_DISTINCT_FROM => {
434                let m = self.start();
435                self.bump(SyntaxKind::IS_KW);
436                self.bump(SyntaxKind::NOT_KW);
437                self.bump(SyntaxKind::DISTINCT_KW);
438                self.bump(SyntaxKind::FROM_KW);
439                m.complete(self, SyntaxKind::IS_NOT_DISTINCT_FROM);
440                return true;
441            }
442            SyntaxKind::OPERATOR_CALL => {
443                let m = self.start();
444                self.bump(SyntaxKind::OPERATOR_KW);
445                self.bump(SyntaxKind::L_PAREN);
446
447                // e.g. `+`, `pg_catalog.+`, `db.pg_catalog.+`
448                grammar::qual_op(self);
449
450                self.expect(SyntaxKind::R_PAREN);
451                m.complete(self, SyntaxKind::OPERATOR_CALL);
452                return true;
453            }
454            SyntaxKind::IS_DISTINCT_FROM => {
455                let m = self.start();
456                self.bump(SyntaxKind::IS_KW);
457                self.bump(SyntaxKind::DISTINCT_KW);
458                self.bump(SyntaxKind::FROM_KW);
459                m.complete(self, SyntaxKind::IS_DISTINCT_FROM);
460                return true;
461            }
462            SyntaxKind::NOT_LIKE => {
463                let m = self.start();
464                self.bump(SyntaxKind::NOT_KW);
465                self.bump(SyntaxKind::LIKE_KW);
466                m.complete(self, SyntaxKind::NOT_LIKE);
467                return true;
468            }
469            SyntaxKind::NOT_ILIKE => {
470                let m = self.start();
471                self.bump(SyntaxKind::NOT_KW);
472                self.bump(SyntaxKind::ILIKE_KW);
473                m.complete(self, SyntaxKind::NOT_ILIKE);
474                return true;
475            }
476            SyntaxKind::NOT_IN => {
477                let m = self.start();
478                self.bump(SyntaxKind::NOT_KW);
479                self.bump(SyntaxKind::IN_KW);
480                m.complete(self, SyntaxKind::NOT_IN);
481                return true;
482            }
483            SyntaxKind::IS_NOT => {
484                let m = self.start();
485                self.bump(SyntaxKind::IS_KW);
486                self.bump(SyntaxKind::NOT_KW);
487                m.complete(self, SyntaxKind::IS_NOT);
488                return true;
489            }
490            SyntaxKind::CUSTOM_OP => {
491                let m = self.start();
492                for _ in 0..self.op_len() {
493                    self.bump_any();
494                }
495                m.complete(self, SyntaxKind::CUSTOM_OP);
496                return true;
497            }
498            _ => 1,
499        };
500        self.do_bump(kind, n_raw_tokens);
501        true
502    }
503
504    fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, triva: TrivaBetween) -> bool {
505        let tokens_match = self.kind_at(self.pos + n) == k1 && self.kind_at(self.pos + n + 1) == k2;
506        // We need to do this so we can say that:
507        // 1 > > 2, is not the same as 1 >> 2
508        match triva {
509            TrivaBetween::Allowed => tokens_match,
510            TrivaBetween::NotAllowed => {
511                return tokens_match
512                    && self.is_joint_at(self.pos + n)
513                    && self.next_not_joined_op_at(n, n + 1);
514            }
515        }
516    }
517
518    fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool {
519        self.kind_at(self.pos + n) == k1
520            && self.kind_at(self.pos + n + 1) == k2
521            && self.kind_at(self.pos + n + 2) == k3
522    }
523
524    fn at_composite4(
525        &self,
526        n: usize,
527        k1: SyntaxKind,
528        k2: SyntaxKind,
529        k3: SyntaxKind,
530        k4: SyntaxKind,
531    ) -> bool {
532        self.kind_at(self.pos + n) == k1
533            && self.kind_at(self.pos + n + 1) == k2
534            && self.kind_at(self.pos + n + 2) == k3
535            && self.kind_at(self.pos + n + 3) == k4
536    }
537
538    fn next_not_joined_op(&self) -> bool {
539        self.next_not_joined_op_at(0, 0)
540    }
541
542    fn next_not_joined_op_at(&self, start: usize, n: usize) -> bool {
543        if !self.nth_at_ts(start, OPERATOR_FIRST) {
544            return true;
545        }
546        // next isn't an operator so we know we're not joined to it
547        if !self.nth_at_ts(n + 1, OPERATOR_FIRST) {
548            return true;
549        }
550        // current kind isn't joined
551        if !self.is_joint_at(self.pos + n) {
552            return true;
553        }
554        self.op_len_at(start) == n + 1 - start
555    }
556
557    fn op_len(&self) -> usize {
558        self.op_len_at(0)
559    }
560
561    fn op_len_at(&self, start: usize) -> usize {
562        if !self.nth_at_ts(start, OPERATOR_FIRST) {
563            return 0;
564        }
565
566        let mut len = 1;
567        let mut has_special = self.nth_at_ts(start, SPECIAL_OP_CHARS);
568        while self.is_joint_at(self.pos + start + len - 1)
569            && self.nth_at_ts(start + len, OPERATOR_FIRST)
570        {
571            has_special |= self.nth_at_ts(start + len, SPECIAL_OP_CHARS);
572            len += 1;
573        }
574
575        // PostgreSQL skips trailing signs from ops if they don't contain a
576        // special char.
577        // This means `2*-3` parses as `2 * -3`.
578        if !has_special {
579            while len > 1 && self.nth_at_ts(start + len - 1, OPERATOR_SIGN) {
580                len -= 1;
581            }
582        }
583
584        len
585    }
586
587    /// Checks if the current token is in `kinds`.
588    pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
589        kinds.contains(self.current())
590    }
591
592    /// Starts a new node in the syntax tree. All nodes and tokens
593    /// consumed between the `start` and the corresponding `Marker::complete`
594    /// belong to the same node.
595    pub(crate) fn start(&mut self) -> Marker {
596        let pos = self.events.len() as u32;
597        self.push_event(Event::tombstone());
598        Marker::new(pos)
599    }
600
601    /// Consume the next token. Panics if the parser isn't currently at `kind`.
602    pub(crate) fn bump(&mut self, kind: SyntaxKind) {
603        assert!(self.eat(kind));
604    }
605
606    /// Advances the parser by one token
607    pub(crate) fn bump_any(&mut self) {
608        let kind = self.nth(0);
609        if kind == SyntaxKind::EOF {
610            return;
611        }
612        self.do_bump(kind, 1);
613    }
614
615    /// Advances the parser by one token, remapping its kind.
616    /// This is useful to create contextual keywords from
617    /// identifiers.
618    pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
619        if self.nth(0) == SyntaxKind::EOF {
620            // FIXME: panic!?
621            return;
622        }
623        self.do_bump(kind, 1);
624    }
625
626    /// Checks if the current token is contextual keyword `kw`.
627    pub(crate) fn at_contextual_kw(&self, kw: SyntaxKind) -> bool {
628        self.contextual_kind_at(self.pos) == kw
629    }
630
631    /// Checks if the nth token is contextual keyword `kw`.
632    pub(crate) fn nth_at_contextual_kw(&self, n: usize, kw: SyntaxKind) -> bool {
633        self.contextual_kind_at(self.pos + n) == kw
634    }
635
636    /// Consume the next token if it is `kind` or emit an error
637    /// otherwise.
638    pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
639        if self.eat(kind) {
640            return true;
641        }
642        self.error(format!("expected {kind:?}"));
643        false
644    }
645
646    /// Create an error node and consume the next token.
647    pub(crate) fn err_and_bump(&mut self, message: &str) {
648        self.err_recover(message, TokenSet::EMPTY);
649    }
650
651    /// Create an error node and consume the next token.
652    pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
653        // TODO: maybe we actually want this?
654        // if matches!(self.current(), SyntaxKind::L_PAREN | SyntaxKind::R_PAREN) {
655        //     self.error(message);
656        //     return;
657        // }
658
659        if self.at_ts(recovery) {
660            self.error(message);
661            return;
662        }
663
664        let m = self.start();
665        self.error(message);
666        self.bump_any();
667        m.complete(self, SyntaxKind::ERROR);
668    }
669
670    fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
671        self.pos += n_raw_tokens as usize;
672        self.steps.set(0);
673        self.push_event(Event::Token { kind, n_raw_tokens });
674    }
675
676    fn push_event(&mut self, event: Event) {
677        self.events.push(event);
678    }
679
680    fn finish(self) -> Vec<Event> {
681        self.events
682    }
683
684    /// Emit error with the `message`
685    /// FIXME: this should be much more fancy and support
686    /// structured errors with spans and notes, like rustc
687    /// does.
688    pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
689        let msg = message.into();
690        self.push_event(Event::Error { msg });
691    }
692
693    /// Checks if the current token is `kind`.
694    #[must_use]
695    pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
696        self.nth_at(0, kind)
697    }
698
699    /// Checks if the nth token is in `kinds`.
700    #[must_use]
701    pub(crate) fn nth_at_ts(&self, n: usize, kinds: TokenSet) -> bool {
702        kinds.contains(self.nth(n))
703    }
704
705    /// Checks if the nth token is a contextual keyword in `kinds`.
706    #[must_use]
707    pub(crate) fn nth_at_contextual_ts(&self, n: usize, kinds: TokenSet) -> bool {
708        kinds.contains(self.nth_contextual_kind(n))
709    }
710
711    /// The contextual keyword kind of the nth token.
712    #[must_use]
713    pub(crate) fn nth_contextual_kind(&self, n: usize) -> SyntaxKind {
714        self.contextual_kind_at(self.pos + n)
715    }
716
717    #[must_use]
718    pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
719        match kind {
720            // =>
721            SyntaxKind::FAT_ARROW => self.at_composite2(
722                n,
723                SyntaxKind::EQ,
724                SyntaxKind::R_ANGLE,
725                TrivaBetween::NotAllowed,
726            ),
727            // :=
728            SyntaxKind::COLON_EQ => self.at_composite2(
729                n,
730                SyntaxKind::COLON,
731                SyntaxKind::EQ,
732                TrivaBetween::NotAllowed,
733            ),
734            // ::
735            SyntaxKind::COLON_COLON => self.at_composite2(
736                n,
737                SyntaxKind::COLON,
738                SyntaxKind::COLON,
739                TrivaBetween::NotAllowed,
740            ),
741            // !=
742            SyntaxKind::NEQ => self.at_composite2(
743                n,
744                SyntaxKind::BANG,
745                SyntaxKind::EQ,
746                TrivaBetween::NotAllowed,
747            ),
748            // <>
749            SyntaxKind::NEQB => self.at_composite2(
750                n,
751                SyntaxKind::L_ANGLE,
752                SyntaxKind::R_ANGLE,
753                TrivaBetween::NotAllowed,
754            ),
755            // is not
756            SyntaxKind::IS_NOT => self.at_composite2(
757                n,
758                SyntaxKind::IS_KW,
759                SyntaxKind::NOT_KW,
760                TrivaBetween::Allowed,
761            ),
762            // not like
763            SyntaxKind::NOT_LIKE => self.at_composite2(
764                n,
765                SyntaxKind::NOT_KW,
766                SyntaxKind::LIKE_KW,
767                TrivaBetween::Allowed,
768            ),
769            // not ilike
770            SyntaxKind::NOT_ILIKE => self.at_composite2(
771                n,
772                SyntaxKind::NOT_KW,
773                SyntaxKind::ILIKE_KW,
774                TrivaBetween::Allowed,
775            ),
776            // not in
777            SyntaxKind::NOT_IN => self.at_composite2(
778                n,
779                SyntaxKind::NOT_KW,
780                SyntaxKind::IN_KW,
781                TrivaBetween::Allowed,
782            ),
783            // at time zone
784            SyntaxKind::AT_TIME_ZONE => self.at_composite3(
785                n,
786                SyntaxKind::AT_KW,
787                SyntaxKind::TIME_KW,
788                SyntaxKind::ZONE_KW,
789            ),
790            // at local
791            SyntaxKind::AT_LOCAL => self.at_composite2(
792                n,
793                SyntaxKind::AT_KW,
794                SyntaxKind::LOCAL_KW,
795                TrivaBetween::Allowed,
796            ),
797            // is distinct from
798            SyntaxKind::IS_DISTINCT_FROM => self.at_composite3(
799                n,
800                SyntaxKind::IS_KW,
801                SyntaxKind::DISTINCT_KW,
802                SyntaxKind::FROM_KW,
803            ),
804            // is not distinct from
805            SyntaxKind::IS_NOT_DISTINCT_FROM => self.at_composite4(
806                n,
807                SyntaxKind::IS_KW,
808                SyntaxKind::NOT_KW,
809                SyntaxKind::DISTINCT_KW,
810                SyntaxKind::FROM_KW,
811            ),
812            // is normalized
813            SyntaxKind::IS_NORMALIZED => {
814                if self.at(SyntaxKind::IS_KW) {
815                    if matches!(
816                        self.nth(1),
817                        SyntaxKind::NFC_KW
818                            | SyntaxKind::NFD_KW
819                            | SyntaxKind::NFKC_KW
820                            | SyntaxKind::NFKD_KW
821                    ) {
822                        if self.nth_at(2, SyntaxKind::NORMALIZED_KW) {
823                            return true;
824                        }
825                    } else {
826                        if self.nth_at(1, SyntaxKind::NORMALIZED_KW) {
827                            return true;
828                        }
829                    }
830                }
831                return false;
832            }
833            // is not normalized
834            SyntaxKind::IS_NOT_NORMALIZED => {
835                if self.at(SyntaxKind::IS_KW) && self.nth_at(1, SyntaxKind::NOT_KW) {
836                    if matches!(
837                        self.nth(2),
838                        SyntaxKind::NFC_KW
839                            | SyntaxKind::NFD_KW
840                            | SyntaxKind::NFKC_KW
841                            | SyntaxKind::NFKD_KW
842                    ) {
843                        if self.nth_at(3, SyntaxKind::NORMALIZED_KW) {
844                            return true;
845                        }
846                    } else if self.nth_at(2, SyntaxKind::NORMALIZED_KW) {
847                        return true;
848                    }
849                }
850                return false;
851            }
852            SyntaxKind::NOT_SIMILAR_TO => self.at_composite3(
853                n,
854                SyntaxKind::NOT_KW,
855                SyntaxKind::SIMILAR_KW,
856                SyntaxKind::TO_KW,
857            ),
858            // similar to
859            SyntaxKind::SIMILAR_TO => self.at_composite2(
860                n,
861                SyntaxKind::SIMILAR_KW,
862                SyntaxKind::TO_KW,
863                TrivaBetween::Allowed,
864            ),
865            // https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS
866            // TODO: is this right?
867            SyntaxKind::OPERATOR_CALL => self.at_composite2(
868                n,
869                SyntaxKind::OPERATOR_KW,
870                SyntaxKind::L_PAREN,
871                TrivaBetween::Allowed,
872            ),
873            // is json
874            SyntaxKind::IS_JSON => self.at_composite2(
875                n,
876                SyntaxKind::IS_KW,
877                SyntaxKind::JSON_KW,
878                TrivaBetween::Allowed,
879            ),
880            // is not json
881            SyntaxKind::IS_NOT_JSON => self.at_composite3(
882                n,
883                SyntaxKind::IS_KW,
884                SyntaxKind::NOT_KW,
885                SyntaxKind::JSON_KW,
886            ),
887            // is not json object
888            SyntaxKind::IS_NOT_JSON_OBJECT => self.at_composite4(
889                n,
890                SyntaxKind::IS_KW,
891                SyntaxKind::NOT_KW,
892                SyntaxKind::JSON_KW,
893                SyntaxKind::OBJECT_KW,
894            ),
895            // is not json array
896            SyntaxKind::IS_NOT_JSON_ARRAY => self.at_composite4(
897                n,
898                SyntaxKind::IS_KW,
899                SyntaxKind::NOT_KW,
900                SyntaxKind::JSON_KW,
901                SyntaxKind::ARRAY_KW,
902            ),
903            // is not json value
904            SyntaxKind::IS_NOT_JSON_VALUE => self.at_composite4(
905                n,
906                SyntaxKind::IS_KW,
907                SyntaxKind::NOT_KW,
908                SyntaxKind::JSON_KW,
909                SyntaxKind::VALUE_KW,
910            ),
911            // is not json scalar
912            SyntaxKind::IS_NOT_JSON_SCALAR => self.at_composite4(
913                n,
914                SyntaxKind::IS_KW,
915                SyntaxKind::NOT_KW,
916                SyntaxKind::JSON_KW,
917                SyntaxKind::SCALAR_KW,
918            ),
919            // is json object
920            SyntaxKind::IS_JSON_OBJECT => self.at_composite3(
921                n,
922                SyntaxKind::IS_KW,
923                SyntaxKind::JSON_KW,
924                SyntaxKind::OBJECT_KW,
925            ),
926            // is json array
927            SyntaxKind::IS_JSON_ARRAY => self.at_composite3(
928                n,
929                SyntaxKind::IS_KW,
930                SyntaxKind::JSON_KW,
931                SyntaxKind::ARRAY_KW,
932            ),
933            // is json value
934            SyntaxKind::IS_JSON_VALUE => self.at_composite3(
935                n,
936                SyntaxKind::IS_KW,
937                SyntaxKind::JSON_KW,
938                SyntaxKind::VALUE_KW,
939            ),
940            // is json scalar
941            SyntaxKind::IS_JSON_SCALAR => self.at_composite3(
942                n,
943                SyntaxKind::IS_KW,
944                SyntaxKind::JSON_KW,
945                SyntaxKind::SCALAR_KW,
946            ),
947            // <=
948            SyntaxKind::LTEQ => self.at_composite2(
949                n,
950                SyntaxKind::L_ANGLE,
951                SyntaxKind::EQ,
952                TrivaBetween::NotAllowed,
953            ),
954            // <=
955            SyntaxKind::GTEQ => self.at_composite2(
956                n,
957                SyntaxKind::R_ANGLE,
958                SyntaxKind::EQ,
959                TrivaBetween::NotAllowed,
960            ),
961            // << used for PL/pgSQL
962            SyntaxKind::LESS_LESS => self.at_composite2(
963                n,
964                SyntaxKind::L_ANGLE,
965                SyntaxKind::L_ANGLE,
966                TrivaBetween::NotAllowed,
967            ),
968            // >>
969            SyntaxKind::GREATER_GREATER => self.at_composite2(
970                n,
971                SyntaxKind::R_ANGLE,
972                SyntaxKind::R_ANGLE,
973                TrivaBetween::NotAllowed,
974            ),
975            SyntaxKind::CUSTOM_OP => {
976                // TODO: is this right?
977                if self.at_ts(OPERATOR_FIRST) {
978                    return true;
979                }
980                return false;
981            }
982            // TODO: we probably shouldn't be using a _ for this but be explicit for each type?
983            _ => self.kind_at(self.pos + n) == kind,
984        }
985    }
986
987    /// Returns the kind of the current token.
988    /// If parser has already reached the end of input,
989    /// the special `EOF` kind is returned.
990    #[must_use]
991    pub(crate) fn current(&self) -> SyntaxKind {
992        self.nth(0)
993    }
994
995    /// Lookahead operation: returns the kind of the next nth
996    /// token.
997    #[must_use]
998    fn nth(&self, n: usize) -> SyntaxKind {
999        let steps = self.steps.get();
1000        assert!(
1001            (steps as usize) < PARSER_STEP_LIMIT,
1002            "the parser seems stuck"
1003        );
1004        self.steps.set(steps + 1);
1005
1006        self.kind_at(self.pos + n)
1007    }
1008}