Skip to main content

oxc_graphql_parser/
parser_ast.rs

1use crate::ast::*;
2use crate::lexer::Lexer;
3use crate::{Error, LimitTracker, T, Token, TokenKind};
4use oxc_allocator::{Allocator, Box as ArenaBox, Vec as ArenaVec};
5use std::ops::ControlFlow;
6
7pub struct Parser<'a> {
8    allocator: &'a Allocator,
9    input: &'a str,
10    lexer: Lexer<'a>,
11    current_token: Option<Token<'a>>,
12    errors: Vec<Error>,
13    comments: Vec<Span>,
14    recursion_limit: LimitTracker,
15    accept_errors: bool,
16    experimental_fragment_arguments: bool,
17    last_end: u32,
18    /// Reusable scratch stack for building AST lists. List elements are
19    /// collected here and copied into the arena once, at the exact final
20    /// size: growing an arena vec strands every outgrown copy in the arena,
21    /// because parsing the elements allocates in between. Recursive descent
22    /// finishes nested lists in LIFO order, so all list types share this one
23    /// stack: a list records the stack length when it starts and drains
24    /// everything above that mark when it ends.
25    scratch: Vec<ScratchNode<'a>>,
26}
27
28/// An element of [`Parser::scratch`]; one variant per AST list type built
29/// through the scratch stack.
30enum ScratchNode<'a> {
31    Definition(Definition<'a>),
32    Selection(Selection<'a>),
33    Argument(Argument<'a>),
34    VariableDefinition(VariableDefinition<'a>),
35    FieldDefinition(FieldDefinition<'a>),
36    InputValueDefinition(InputValueDefinition<'a>),
37    Directive(Directive<'a>),
38}
39
40#[derive(Clone, Copy)]
41enum Constness {
42    Const,
43    NotConst,
44}
45
46const DEFAULT_RECURSION_LIMIT: usize = 500;
47
48impl<'a> Parser<'a> {
49    /// # Panics
50    ///
51    /// Panics if `input` is larger than 4 GiB: AST spans store `u32` offsets.
52    pub fn new(allocator: &'a Allocator, input: &'a str) -> Self {
53        assert!(
54            u32::try_from(input.len()).is_ok(),
55            "source text is too long for u32 spans (max 4 GiB): {} bytes",
56            input.len()
57        );
58        Self {
59            allocator,
60            input,
61            lexer: Lexer::new(input),
62            current_token: None,
63            errors: Vec::new(),
64            comments: Vec::new(),
65            recursion_limit: LimitTracker::new(DEFAULT_RECURSION_LIMIT),
66            accept_errors: true,
67            experimental_fragment_arguments: false,
68            last_end: 0,
69            scratch: Vec::new(),
70        }
71    }
72
73    pub fn recursion_limit(mut self, recursion_limit: usize) -> Self {
74        self.recursion_limit = LimitTracker::new(recursion_limit);
75        self
76    }
77
78    pub fn token_limit(mut self, token_limit: usize) -> Self {
79        self.lexer = self.lexer.with_limit(token_limit);
80        self
81    }
82
83    pub fn experimental_fragment_arguments(mut self, allow: bool) -> Self {
84        self.experimental_fragment_arguments = allow;
85        self
86    }
87
88    pub fn parse(mut self) -> Ast<'a, Document<'a>> {
89        let document = self.parse_document();
90        self.into_ast(document)
91    }
92
93    pub fn parse_selection_set(mut self) -> Ast<'a, SelectionSet<'a>> {
94        let selection_set = self.parse_selection_set_inner();
95        self.into_ast(selection_set)
96    }
97
98    pub fn parse_type(mut self) -> Ast<'a, Type<'a>> {
99        let ty = self.parse_type_inner().unwrap_or_else(|| {
100            let span = self.current_span();
101            self.err("expected a type");
102            Type::Missing(span)
103        });
104        self.into_ast(ty)
105    }
106
107    fn into_ast<T>(self, root: T) -> Ast<'a, T> {
108        let token_limit = self.lexer.limit_tracker;
109        Ast::new(self.input, root, self.errors, self.comments, self.recursion_limit, token_limit)
110    }
111
112    /// Marks the start of a new scratch-built list, pre-sizing the stack so
113    /// small parses pay for at most one scratch allocation.
114    fn scratch_mark(&mut self) -> usize {
115        if self.scratch.capacity() == 0 {
116            self.scratch.reserve(128);
117        }
118        self.scratch.len()
119    }
120
121    /// Moves the scratch elements above `mark` into an exact-size arena vec.
122    #[inline]
123    fn drain_scratch<T>(
124        &mut self,
125        mark: usize,
126        unwrap: impl FnMut(ScratchNode<'a>) -> T,
127    ) -> ArenaVec<'a, T> {
128        ArenaVec::from_iter_in(self.scratch.drain(mark..).map(unwrap), &self.allocator)
129    }
130
131    fn parse_document(&mut self) -> Document<'a> {
132        let start = self.current_start();
133        let mark = self.scratch_mark();
134
135        if self.peek().is_none_or(|kind| kind == TokenKind::Eof) {
136            self.err("Unexpected <EOF>.");
137        }
138
139        self.peek_while(|parser, kind| {
140            if kind == TokenKind::Eof {
141                return ControlFlow::Break(());
142            }
143
144            let before = parser.current_span();
145            if let Some(definition) = parser.parse_definition() {
146                parser.scratch.push(ScratchNode::Definition(definition));
147            } else {
148                parser.err_and_pop("expected a StringValue, Name or OperationDefinition");
149            }
150
151            if parser.current_span() == before && parser.peek() != Some(TokenKind::Eof) {
152                parser.bump();
153            }
154
155            ControlFlow::Continue(())
156        });
157
158        let definitions = self.drain_scratch(mark, |node| match node {
159            ScratchNode::Definition(definition) => definition,
160            _ => unreachable!("scratch stack discipline"),
161        });
162        Document { definitions, span: self.span_from(start) }
163    }
164
165    fn parse_definition(&mut self) -> Option<Definition<'a>> {
166        let description = self.parse_description_if_present();
167        let selector = self.peek_data()?;
168
169        let definition = match selector {
170            "directive" => {
171                let definition = self.parse_directive_definition(description);
172                Definition::Directive(ArenaBox::new_in(definition, &self.allocator))
173            }
174            "enum" => {
175                let definition = self.parse_enum_type_definition(description);
176                Definition::EnumType(ArenaBox::new_in(definition, &self.allocator))
177            }
178            "extend" => {
179                if description.is_some() {
180                    self.err(
181                        "Unexpected description, only GraphQL definitions support descriptions.",
182                    );
183                }
184                return self.parse_extension();
185            }
186            "fragment" => {
187                let definition = self.parse_fragment_definition(description);
188                Definition::Fragment(ArenaBox::new_in(definition, &self.allocator))
189            }
190            "input" => {
191                let definition = self.parse_input_object_type_definition(description);
192                Definition::InputObjectType(ArenaBox::new_in(definition, &self.allocator))
193            }
194            "interface" => {
195                let definition = self.parse_interface_type_definition(description);
196                Definition::InterfaceType(ArenaBox::new_in(definition, &self.allocator))
197            }
198            "type" => {
199                let definition = self.parse_object_type_definition(description);
200                Definition::ObjectType(ArenaBox::new_in(definition, &self.allocator))
201            }
202            "{" => {
203                if description.is_some() {
204                    self.err(
205                        "Unexpected description, descriptions are not supported on shorthand queries.",
206                    );
207                }
208                let definition = self.parse_operation_definition(description);
209                Definition::Operation(ArenaBox::new_in(definition, &self.allocator))
210            }
211            "query" | "mutation" | "subscription" => {
212                let definition = self.parse_operation_definition(description);
213                Definition::Operation(ArenaBox::new_in(definition, &self.allocator))
214            }
215            "scalar" => {
216                let definition = self.parse_scalar_type_definition(description);
217                Definition::ScalarType(ArenaBox::new_in(definition, &self.allocator))
218            }
219            "schema" => {
220                let definition = self.parse_schema_definition(description);
221                Definition::Schema(ArenaBox::new_in(definition, &self.allocator))
222            }
223            "union" => {
224                let definition = self.parse_union_type_definition(description);
225                Definition::UnionType(ArenaBox::new_in(definition, &self.allocator))
226            }
227            _ => {
228                if description.is_some() {
229                    self.err("expected a definition after this StringValue");
230                } else {
231                    self.err_and_pop("expected definition");
232                }
233                return None;
234            }
235        };
236
237        Some(definition)
238    }
239
240    fn parse_extension(&mut self) -> Option<Definition<'a>> {
241        let start = self.current_start();
242        self.expect_name_value("extend");
243
244        let definition = match self.peek_data() {
245            Some("schema") => {
246                let extension = self.parse_schema_extension_from(start);
247                Definition::SchemaExtension(ArenaBox::new_in(extension, &self.allocator))
248            }
249            Some("scalar") => {
250                let extension = self.parse_scalar_type_extension_from(start);
251                Definition::ScalarTypeExtension(ArenaBox::new_in(extension, &self.allocator))
252            }
253            Some("type") => {
254                let extension = self.parse_object_type_extension_from(start);
255                Definition::ObjectTypeExtension(ArenaBox::new_in(extension, &self.allocator))
256            }
257            Some("interface") => {
258                let extension = self.parse_interface_type_extension_from(start);
259                Definition::InterfaceTypeExtension(ArenaBox::new_in(extension, &self.allocator))
260            }
261            Some("union") => {
262                let extension = self.parse_union_type_extension_from(start);
263                Definition::UnionTypeExtension(ArenaBox::new_in(extension, &self.allocator))
264            }
265            Some("enum") => {
266                let extension = self.parse_enum_type_extension_from(start);
267                Definition::EnumTypeExtension(ArenaBox::new_in(extension, &self.allocator))
268            }
269            Some("input") => {
270                let extension = self.parse_input_object_type_extension_from(start);
271                Definition::InputObjectTypeExtension(ArenaBox::new_in(extension, &self.allocator))
272            }
273            Some("directive") => {
274                let extension = self.parse_directive_extension_from(start);
275                Definition::DirectiveExtension(ArenaBox::new_in(extension, &self.allocator))
276            }
277            _ => {
278                self.err("expected a valid extension");
279                return None;
280            }
281        };
282
283        Some(definition)
284    }
285
286    fn parse_operation_definition(
287        &mut self,
288        description: Option<ArenaBox<'a, StringValue<'a>>>,
289    ) -> OperationDefinition<'a> {
290        let start = self.definition_start(&description);
291
292        if self.peek() == Some(T!['{']) {
293            let selection_set = Some(self.parse_alloc_selection_set());
294            return OperationDefinition {
295                description,
296                operation_type: OperationType::Query,
297                name: None,
298                variable_definitions: ArenaVec::new_in(&self.allocator),
299                directives: ArenaVec::new_in(&self.allocator),
300                selection_set,
301                span: self.span_from(start),
302            };
303        }
304
305        let operation_type = self.parse_operation_type("expected Operation Type");
306
307        let name = if self.peek() == Some(TokenKind::Name) { self.parse_name() } else { None };
308        let variable_definitions = self.parse_variable_definitions_if_present();
309        let directives = self.parse_directives(Constness::NotConst);
310        let selection_set = self.parse_required_selection_set();
311
312        OperationDefinition {
313            description,
314            operation_type,
315            name,
316            variable_definitions,
317            directives,
318            selection_set,
319            span: self.span_from(start),
320        }
321    }
322
323    fn parse_fragment_definition(
324        &mut self,
325        description: Option<ArenaBox<'a, StringValue<'a>>>,
326    ) -> FragmentDefinition<'a> {
327        let start = self.definition_start(&description);
328        self.expect_name_value("fragment");
329        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
330
331        let variable_definitions = if self.experimental_fragment_arguments {
332            self.parse_variable_definitions_if_present()
333        } else {
334            ArenaVec::new_in(&self.allocator)
335        };
336
337        self.expect_name_value("on");
338        let type_condition = self.parse_named_type().unwrap_or_else(|| self.missing_named_type());
339        let directives = self.parse_directives(Constness::NotConst);
340        let selection_set = self.parse_required_selection_set();
341
342        FragmentDefinition {
343            description,
344            name,
345            variable_definitions,
346            type_condition,
347            directives,
348            selection_set,
349            span: self.span_from(start),
350        }
351    }
352
353    fn parse_alloc_selection_set(&mut self) -> ArenaBox<'a, SelectionSet<'a>> {
354        let selection_set = self.parse_selection_set_inner();
355        ArenaBox::new_in(selection_set, &self.allocator)
356    }
357
358    /// Parse a selection set that is required in this position. If the next
359    /// token is not `{`, records an error and returns `None`.
360    fn parse_required_selection_set(&mut self) -> Option<ArenaBox<'a, SelectionSet<'a>>> {
361        if self.peek() == Some(T!['{']) {
362            Some(self.parse_alloc_selection_set())
363        } else {
364            self.err("expected a Selection Set");
365            None
366        }
367    }
368
369    /// Parse an operation type keyword (`query`, `mutation`, or `subscription`),
370    /// consuming it. If none is present, records an error using `missing` and
371    /// falls back to `OperationType::Query`.
372    fn parse_operation_type(&mut self, missing: &str) -> OperationType {
373        match self.peek_data() {
374            Some("query") => {
375                self.bump();
376                OperationType::Query
377            }
378            Some("mutation") => {
379                self.bump();
380                OperationType::Mutation
381            }
382            Some("subscription") => {
383                self.bump();
384                OperationType::Subscription
385            }
386            _ => {
387                self.err(missing);
388                OperationType::Query
389            }
390        }
391    }
392
393    fn parse_selection_set_inner(&mut self) -> SelectionSet<'a> {
394        let start = self.current_start();
395        self.expect(T!['{'], "expected {");
396
397        let mark = self.scratch_mark();
398
399        self.peek_while(|parser, kind| match kind {
400            T!['}'] => {
401                if parser.scratch.len() == mark {
402                    parser.err("expected Selection");
403                }
404                parser.bump();
405                ControlFlow::Break(())
406            }
407            TokenKind::Eof => {
408                parser.err("expected }");
409                ControlFlow::Break(())
410            }
411            TokenKind::Name | T![...] if parser.recursion_limit.check_and_increment() => {
412                parser.limit_err("parser recursion limit reached");
413                ControlFlow::Break(())
414            }
415            TokenKind::Name | T![...] => {
416                let selection = parser.parse_selection();
417                parser.scratch.push(ScratchNode::Selection(selection));
418                parser.recursion_limit.decrement();
419                ControlFlow::Continue(())
420            }
421            _ => {
422                parser.err_and_pop("expected a Selection");
423                ControlFlow::Continue(())
424            }
425        });
426
427        let selections = self.drain_scratch(mark, |node| match node {
428            ScratchNode::Selection(selection) => selection,
429            _ => unreachable!("scratch stack discipline"),
430        });
431
432        SelectionSet { selections, span: self.span_from(start) }
433    }
434
435    fn parse_selection(&mut self) -> Selection<'a> {
436        if self.peek() == Some(T![...]) {
437            self.parse_fragment_selection()
438        } else {
439            let field = self.parse_field();
440            Selection::Field(ArenaBox::new_in(field, &self.allocator))
441        }
442    }
443
444    fn parse_fragment_selection(&mut self) -> Selection<'a> {
445        let start = self.current_start();
446        self.expect(T![...], "expected ...");
447
448        if self.peek_data() == Some("on") {
449            self.bump();
450            let type_condition = self.parse_named_type();
451            let directives = self.parse_directives(Constness::NotConst);
452            let selection_set = self.parse_required_selection_set();
453            return Selection::InlineFragment(ArenaBox::new_in(
454                InlineFragment {
455                    type_condition,
456                    directives,
457                    selection_set,
458                    span: self.span_from(start),
459                },
460                &self.allocator,
461            ));
462        }
463
464        if matches!(self.peek(), Some(T![@] | T!['{'])) {
465            let directives = self.parse_directives(Constness::NotConst);
466            let selection_set = self.parse_required_selection_set();
467            return Selection::InlineFragment(ArenaBox::new_in(
468                InlineFragment {
469                    type_condition: None,
470                    directives,
471                    selection_set,
472                    span: self.span_from(start),
473                },
474                &self.allocator,
475            ));
476        }
477
478        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
479        let arguments = if self.experimental_fragment_arguments {
480            self.parse_arguments_if_present(Constness::NotConst)
481        } else {
482            ArenaVec::new_in(&self.allocator)
483        };
484        let directives = self.parse_directives(Constness::NotConst);
485        Selection::FragmentSpread(ArenaBox::new_in(
486            FragmentSpread { name, arguments, directives, span: self.span_from(start) },
487            &self.allocator,
488        ))
489    }
490
491    fn parse_field(&mut self) -> Field<'a> {
492        let start = self.current_start();
493        let first_name = self.parse_name().unwrap_or_else(|| self.missing_name());
494        let (alias, name) = if self.peek() == Some(T![:]) {
495            self.bump();
496            let name = self.parse_name().unwrap_or_else(|| self.missing_name());
497            (Some(first_name), name)
498        } else {
499            (None, first_name)
500        };
501
502        let arguments = self.parse_arguments_if_present(Constness::NotConst);
503        let directives = self.parse_directives(Constness::NotConst);
504        let selection_set = if self.peek() == Some(T!['{']) {
505            Some(self.parse_alloc_selection_set())
506        } else {
507            None
508        };
509
510        Field { alias, name, arguments, directives, selection_set, span: self.span_from(start) }
511    }
512
513    fn parse_arguments_if_present(&mut self, constness: Constness) -> ArenaVec<'a, Argument<'a>> {
514        if self.peek() != Some(T!['(']) {
515            return ArenaVec::new_in(&self.allocator);
516        }
517
518        self.bump();
519        let mark = self.scratch_mark();
520        self.peek_while(|parser, kind| match kind {
521            T![')'] => {
522                parser.bump();
523                ControlFlow::Break(())
524            }
525            TokenKind::Name => {
526                let argument = parser.parse_argument(constness);
527                parser.scratch.push(ScratchNode::Argument(argument));
528                ControlFlow::Continue(())
529            }
530            TokenKind::Eof => {
531                parser.err("expected )");
532                ControlFlow::Break(())
533            }
534            _ => {
535                parser.err_and_pop("expected an Argument");
536                ControlFlow::Continue(())
537            }
538        });
539        self.drain_scratch(mark, |node| match node {
540            ScratchNode::Argument(argument) => argument,
541            _ => unreachable!("scratch stack discipline"),
542        })
543    }
544
545    fn parse_argument(&mut self, constness: Constness) -> Argument<'a> {
546        let start = self.current_start();
547        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
548        let value = if self.peek() == Some(T![:]) {
549            self.bump();
550            Some(self.parse_value(constness, false))
551        } else {
552            self.err("expected :");
553            None
554        };
555        Argument { name, value, span: self.span_from(start) }
556    }
557
558    fn parse_variable_definitions_if_present(&mut self) -> ArenaVec<'a, VariableDefinition<'a>> {
559        if self.peek() != Some(T!['(']) {
560            return ArenaVec::new_in(&self.allocator);
561        }
562
563        self.bump();
564        let mark = self.scratch_mark();
565        self.peek_while(|parser, kind| match kind {
566            T![')'] => {
567                if parser.scratch.len() == mark {
568                    parser.err("expected a Variable Definition");
569                }
570                parser.bump();
571                ControlFlow::Break(())
572            }
573            T![$] | TokenKind::StringValue => {
574                let definition = parser.parse_variable_definition();
575                parser.scratch.push(ScratchNode::VariableDefinition(definition));
576                ControlFlow::Continue(())
577            }
578            TokenKind::Eof => {
579                parser.err("expected )");
580                ControlFlow::Break(())
581            }
582            _ => {
583                parser.err_and_pop("expected a Variable Definition");
584                ControlFlow::Continue(())
585            }
586        });
587        self.drain_scratch(mark, |node| match node {
588            ScratchNode::VariableDefinition(definition) => definition,
589            _ => unreachable!("scratch stack discipline"),
590        })
591    }
592
593    fn parse_variable_definition(&mut self) -> VariableDefinition<'a> {
594        let start = self.current_start();
595        let description = self.parse_description_if_present();
596        let variable = self.parse_variable().unwrap_or_else(|| self.missing_variable());
597        let mut ty = None;
598        let mut default_value = None;
599        let mut directives = ArenaVec::new_in(&self.allocator);
600
601        if self.peek() == Some(T![:]) {
602            self.bump();
603            ty = self.parse_type_inner();
604            if self.peek() == Some(T![=]) {
605                self.bump();
606                default_value = Some(self.parse_value(Constness::Const, false));
607            }
608            directives = self.parse_directives(Constness::Const);
609        } else {
610            self.err("expected a Name");
611        }
612
613        VariableDefinition {
614            description,
615            variable,
616            ty,
617            default_value,
618            directives,
619            span: self.span_from(start),
620        }
621    }
622
623    fn parse_variable(&mut self) -> Option<Variable<'a>> {
624        let start = self.current_start();
625        if self.peek() != Some(T![$]) {
626            self.err("expected a Variable");
627            return None;
628        }
629        self.bump();
630        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
631        Some(Variable { name, span: self.span_from(start) })
632    }
633
634    fn parse_directives(&mut self, constness: Constness) -> ArenaVec<'a, Directive<'a>> {
635        if self.peek() != Some(T![@]) {
636            return ArenaVec::new_in(&self.allocator);
637        }
638
639        let mark = self.scratch_mark();
640        while self.peek() == Some(T![@]) {
641            let directive = self.parse_directive(constness);
642            self.scratch.push(ScratchNode::Directive(directive));
643        }
644        self.drain_scratch(mark, |node| match node {
645            ScratchNode::Directive(directive) => directive,
646            _ => unreachable!("scratch stack discipline"),
647        })
648    }
649
650    fn parse_directive(&mut self, constness: Constness) -> Directive<'a> {
651        let start = self.current_start();
652        self.expect(T![@], "expected @ symbol");
653        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
654        let arguments = self.parse_arguments_if_present(constness);
655        Directive { name, arguments, span: self.span_from(start) }
656    }
657
658    fn parse_value(&mut self, constness: Constness, pop_on_error: bool) -> Value<'a> {
659        match self.peek() {
660            Some(T![$]) => {
661                if matches!(constness, Constness::Const) {
662                    self.err("unexpected variable value in a Const context");
663                }
664                match self.parse_variable() {
665                    Some(variable) => Value::Variable(ArenaBox::new_in(variable, &self.allocator)),
666                    None => Value::Missing(self.current_span()),
667                }
668            }
669            Some(TokenKind::Int) => self.parse_int_value(),
670            Some(TokenKind::Float) => self.parse_float_value(),
671            Some(TokenKind::StringValue) => match self.parse_string_value() {
672                Some(value) => Value::String(ArenaBox::new_in(value, &self.allocator)),
673                None => Value::Missing(self.current_span()),
674            },
675            Some(TokenKind::Name) => self.parse_name_value(),
676            Some(T!['[']) => self.parse_list_value(constness),
677            Some(T!['{']) => self.parse_object_value(constness),
678            _ => {
679                let message = "expected a valid Value";
680                if pop_on_error {
681                    self.err_and_pop(message);
682                } else {
683                    self.err(message);
684                }
685                Value::Missing(self.current_span())
686            }
687        }
688    }
689
690    fn parse_int_value(&mut self) -> Value<'a> {
691        let token = self.bump().expect("peeked int token must be available");
692        Value::Int(ArenaBox::new_in(
693            IntValue { raw: token.data(), span: token_span(&token) },
694            &self.allocator,
695        ))
696    }
697
698    fn parse_float_value(&mut self) -> Value<'a> {
699        let token = self.bump().expect("peeked float token must be available");
700        Value::Float(ArenaBox::new_in(
701            FloatValue { raw: token.data(), span: token_span(&token) },
702            &self.allocator,
703        ))
704    }
705
706    fn parse_name_value(&mut self) -> Value<'a> {
707        let Some(name) = self.parse_name() else {
708            return Value::Missing(self.current_span());
709        };
710        match name.value {
711            "true" => Value::Boolean(ArenaBox::new_in(
712                BooleanValue { value: true, span: name.span },
713                &self.allocator,
714            )),
715            "false" => Value::Boolean(ArenaBox::new_in(
716                BooleanValue { value: false, span: name.span },
717                &self.allocator,
718            )),
719            "null" => Value::Null(ArenaBox::new_in(NullValue { span: name.span }, &self.allocator)),
720            _ => Value::Enum(ArenaBox::new_in(EnumValue { name }, &self.allocator)),
721        }
722    }
723
724    fn parse_list_value(&mut self, constness: Constness) -> Value<'a> {
725        let start = self.current_start();
726        self.expect(T!['['], "expected [");
727        let mut values = ArenaVec::new_in(&self.allocator);
728
729        self.peek_while(|parser, kind| match kind {
730            T![']'] => {
731                parser.bump();
732                ControlFlow::Break(())
733            }
734            TokenKind::Eof => {
735                parser.err("expected ]");
736                ControlFlow::Break(())
737            }
738            _ if parser.recursion_limit.check_and_increment() => {
739                parser.limit_err("parser recursion limit reached");
740                ControlFlow::Break(())
741            }
742            _ => {
743                values.push(parser.parse_value(constness, true));
744                parser.recursion_limit.decrement();
745                ControlFlow::Continue(())
746            }
747        });
748
749        Value::List(ArenaBox::new_in(
750            ListValue { values, span: self.span_from(start) },
751            &self.allocator,
752        ))
753    }
754
755    fn parse_object_value(&mut self, constness: Constness) -> Value<'a> {
756        let start = self.current_start();
757        self.expect(T!['{'], "expected {");
758        let mut fields = ArenaVec::new_in(&self.allocator);
759
760        self.peek_while(|parser, kind| match kind {
761            T!['}'] => {
762                parser.bump();
763                ControlFlow::Break(())
764            }
765            TokenKind::Name if parser.recursion_limit.check_and_increment() => {
766                parser.limit_err("parser recursion limit reached");
767                ControlFlow::Break(())
768            }
769            TokenKind::Name => {
770                fields.push(parser.parse_object_field(constness));
771                parser.recursion_limit.decrement();
772                ControlFlow::Continue(())
773            }
774            TokenKind::Eof => {
775                parser.err("expected }");
776                ControlFlow::Break(())
777            }
778            _ => {
779                parser.err_and_pop("expected Object Field");
780                ControlFlow::Continue(())
781            }
782        });
783
784        Value::Object(ArenaBox::new_in(
785            ObjectValue { fields, span: self.span_from(start) },
786            &self.allocator,
787        ))
788    }
789
790    fn parse_object_field(&mut self, constness: Constness) -> ObjectField<'a> {
791        let start = self.current_start();
792        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
793        let value = if self.peek() == Some(T![:]) {
794            self.bump();
795            Some(self.parse_value(constness, true))
796        } else {
797            self.err("expected :");
798            None
799        };
800        ObjectField { name, value, span: self.span_from(start) }
801    }
802
803    fn parse_type_inner(&mut self) -> Option<Type<'a>> {
804        let start = self.current_start();
805        let mut ty = match self.peek() {
806            Some(T!['[']) => {
807                self.bump();
808                if self.recursion_limit.check_and_increment() {
809                    self.limit_err("parser recursion limit reached");
810                    return Some(Type::Missing(self.span_from(start)));
811                }
812                let inner =
813                    self.parse_type_inner().unwrap_or_else(|| Type::Missing(self.current_span()));
814                self.recursion_limit.decrement();
815                self.expect(T![']'], "expected ]");
816                Type::List(ArenaBox::new_in(
817                    ListType { ty: inner, span: self.span_from(start) },
818                    &self.allocator,
819                ))
820            }
821            Some(TokenKind::Name) => {
822                let name = self.parse_name().unwrap_or_else(|| self.missing_name());
823                Type::Named(ArenaBox::new_in(NamedType { name }, &self.allocator))
824            }
825            Some(_) => {
826                self.err("expected a type");
827                return None;
828            }
829            None => return None,
830        };
831
832        if self.peek() == Some(T![!]) {
833            self.bump();
834            ty = Type::NonNull(ArenaBox::new_in(
835                NonNullType { ty, span: self.span_from(start) },
836                &self.allocator,
837            ));
838        }
839
840        Some(ty)
841    }
842
843    fn parse_named_type(&mut self) -> Option<NamedType<'a>> {
844        self.parse_name().map(|name| NamedType { name })
845    }
846
847    fn parse_schema_definition(
848        &mut self,
849        description: Option<ArenaBox<'a, StringValue<'a>>>,
850    ) -> SchemaDefinition<'a> {
851        let start = self.definition_start(&description);
852        self.expect_name_value("schema");
853        let directives = self.parse_directives(Constness::Const);
854        let root_operations = self.parse_root_operation_types_if_present();
855        SchemaDefinition { description, directives, root_operations, span: self.span_from(start) }
856    }
857
858    fn parse_schema_extension_from(&mut self, start: u32) -> SchemaExtension<'a> {
859        self.expect_name_value("schema");
860        let directives = self.parse_directives(Constness::Const);
861        let root_operations = self.parse_root_operation_types_if_present();
862        if directives.is_empty() && root_operations.is_empty() {
863            self.err("expected Directives or Root Operation Types");
864        }
865        SchemaExtension { directives, root_operations, span: self.span_from(start) }
866    }
867
868    fn parse_root_operation_types_if_present(
869        &mut self,
870    ) -> ArenaVec<'a, RootOperationTypeDefinition<'a>> {
871        if self.peek() != Some(T!['{']) {
872            return ArenaVec::new_in(&self.allocator);
873        }
874
875        self.bump();
876        let mut root_operations = ArenaVec::new_in(&self.allocator);
877        self.peek_while(|parser, kind| match kind {
878            T!['}'] => {
879                parser.bump();
880                ControlFlow::Break(())
881            }
882            TokenKind::Name => {
883                root_operations.push(parser.parse_root_operation_type_definition());
884                ControlFlow::Continue(())
885            }
886            TokenKind::Eof => {
887                parser.err("expected }");
888                ControlFlow::Break(())
889            }
890            _ => {
891                parser.err_and_pop("expected Root Operation Type Definition");
892                ControlFlow::Continue(())
893            }
894        });
895        root_operations
896    }
897
898    fn parse_root_operation_type_definition(&mut self) -> RootOperationTypeDefinition<'a> {
899        let start = self.current_start();
900        let operation_type = self.parse_operation_type("expected an Operation Type");
901        self.expect(T![:], "expected :");
902        let named_type = self.parse_named_type().unwrap_or_else(|| self.missing_named_type());
903        RootOperationTypeDefinition { operation_type, named_type, span: self.span_from(start) }
904    }
905
906    fn parse_directive_extension_from(&mut self, start: u32) -> DirectiveExtension<'a> {
907        self.expect_name_value("directive");
908        self.expect(T![@], "expected @ symbol");
909        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
910        let directives = self.parse_directives(Constness::Const);
911        if directives.is_empty() {
912            self.err("expected Directives");
913        }
914        DirectiveExtension { name, directives, span: self.span_from(start) }
915    }
916
917    fn parse_directive_definition(
918        &mut self,
919        description: Option<ArenaBox<'a, StringValue<'a>>>,
920    ) -> DirectiveDefinition<'a> {
921        let start = self.definition_start(&description);
922        self.expect_name_value("directive");
923        self.expect(T![@], "expected @ symbol");
924        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
925        let arguments = self.parse_arguments_definition_if_present();
926        let directives = self.parse_directives(Constness::Const);
927        let repeatable = if self.peek_data() == Some("repeatable") {
928            self.bump();
929            true
930        } else {
931            false
932        };
933        self.expect_name_value("on");
934        let locations = self.parse_directive_locations();
935
936        DirectiveDefinition {
937            description,
938            name,
939            arguments,
940            directives,
941            repeatable,
942            locations,
943            span: self.span_from(start),
944        }
945    }
946
947    fn parse_directive_locations(&mut self) -> ArenaVec<'a, DirectiveLocation<'a>> {
948        if self.peek() == Some(T![|]) {
949            self.bump();
950        }
951
952        let mut locations = ArenaVec::new_in(&self.allocator);
953        loop {
954            if let Some(token) = self.peek_token().copied()
955                && token.kind() == TokenKind::Name
956            {
957                self.bump();
958                locations.push(DirectiveLocation { name: token.data(), span: token_span(&token) });
959            } else {
960                self.err("expected valid Directive Location");
961                break;
962            }
963
964            if self.peek() == Some(T![|]) {
965                self.bump();
966            } else {
967                break;
968            }
969        }
970        locations
971    }
972
973    fn parse_scalar_type_definition(
974        &mut self,
975        description: Option<ArenaBox<'a, StringValue<'a>>>,
976    ) -> ScalarTypeDefinition<'a> {
977        let start = self.definition_start(&description);
978        self.expect_name_value("scalar");
979        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
980        let directives = self.parse_directives(Constness::Const);
981        ScalarTypeDefinition { description, name, directives, span: self.span_from(start) }
982    }
983
984    fn parse_scalar_type_extension_from(&mut self, start: u32) -> ScalarTypeExtension<'a> {
985        self.expect_name_value("scalar");
986        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
987        let directives = self.parse_directives(Constness::Const);
988        if directives.is_empty() {
989            self.err("expected Directives");
990        }
991        ScalarTypeExtension { name, directives, span: self.span_from(start) }
992    }
993
994    fn parse_object_type_definition(
995        &mut self,
996        description: Option<ArenaBox<'a, StringValue<'a>>>,
997    ) -> ObjectTypeDefinition<'a> {
998        let start = self.definition_start(&description);
999        self.expect_name_value("type");
1000        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1001        let interfaces = self.parse_implements_interfaces();
1002        let directives = self.parse_directives(Constness::Const);
1003        let fields = self.parse_fields_definition_if_present();
1004        ObjectTypeDefinition {
1005            description,
1006            name,
1007            interfaces,
1008            directives,
1009            fields,
1010            span: self.span_from(start),
1011        }
1012    }
1013
1014    fn parse_object_type_extension_from(&mut self, start: u32) -> ObjectTypeExtension<'a> {
1015        self.expect_name_value("type");
1016        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1017        let interfaces = self.parse_implements_interfaces();
1018        let directives = self.parse_directives(Constness::Const);
1019        let fields = self.parse_fields_definition_if_present();
1020        if interfaces.is_empty() && directives.is_empty() && fields.is_empty() {
1021            self.err("expected Implements Interfaces, Directives, or Fields Definition");
1022        }
1023        ObjectTypeExtension { name, interfaces, directives, fields, span: self.span_from(start) }
1024    }
1025
1026    fn parse_interface_type_definition(
1027        &mut self,
1028        description: Option<ArenaBox<'a, StringValue<'a>>>,
1029    ) -> InterfaceTypeDefinition<'a> {
1030        let start = self.definition_start(&description);
1031        self.expect_name_value("interface");
1032        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1033        let interfaces = self.parse_implements_interfaces();
1034        let directives = self.parse_directives(Constness::Const);
1035        let fields = self.parse_fields_definition_if_present();
1036        InterfaceTypeDefinition {
1037            description,
1038            name,
1039            interfaces,
1040            directives,
1041            fields,
1042            span: self.span_from(start),
1043        }
1044    }
1045
1046    fn parse_interface_type_extension_from(&mut self, start: u32) -> InterfaceTypeExtension<'a> {
1047        self.expect_name_value("interface");
1048        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1049        let interfaces = self.parse_implements_interfaces();
1050        let directives = self.parse_directives(Constness::Const);
1051        let fields = self.parse_fields_definition_if_present();
1052        if interfaces.is_empty() && directives.is_empty() && fields.is_empty() {
1053            self.err("expected an Implements Interfaces, Directives, or a Fields Definition");
1054        }
1055        InterfaceTypeExtension { name, interfaces, directives, fields, span: self.span_from(start) }
1056    }
1057
1058    fn parse_implements_interfaces(&mut self) -> ArenaVec<'a, NamedType<'a>> {
1059        if self.peek_data() != Some("implements") {
1060            return ArenaVec::new_in(&self.allocator);
1061        }
1062
1063        self.bump();
1064        if self.peek() == Some(T![&]) {
1065            self.bump();
1066        }
1067
1068        let mut interfaces = ArenaVec::new_in(&self.allocator);
1069        loop {
1070            if let Some(named_type) = self.parse_named_type() {
1071                interfaces.push(named_type);
1072            } else {
1073                self.err("expected Implements Interface");
1074                break;
1075            }
1076
1077            if self.peek() == Some(T![&]) {
1078                self.bump();
1079            } else {
1080                break;
1081            }
1082        }
1083        interfaces
1084    }
1085
1086    fn parse_fields_definition_if_present(&mut self) -> ArenaVec<'a, FieldDefinition<'a>> {
1087        if self.peek() != Some(T!['{']) {
1088            return ArenaVec::new_in(&self.allocator);
1089        }
1090
1091        self.bump();
1092        let mark = self.scratch_mark();
1093        self.peek_while(|parser, kind| match kind {
1094            T!['}'] => {
1095                if parser.scratch.len() == mark {
1096                    parser.err("expected Field Definition");
1097                }
1098                parser.bump();
1099                ControlFlow::Break(())
1100            }
1101            TokenKind::Name | TokenKind::StringValue => {
1102                let field = parser.parse_field_definition();
1103                parser.scratch.push(ScratchNode::FieldDefinition(field));
1104                ControlFlow::Continue(())
1105            }
1106            TokenKind::Eof => {
1107                parser.err("expected }");
1108                ControlFlow::Break(())
1109            }
1110            _ => {
1111                parser.err_and_pop("expected a Field Definition");
1112                ControlFlow::Continue(())
1113            }
1114        });
1115        self.drain_scratch(mark, |node| match node {
1116            ScratchNode::FieldDefinition(field) => field,
1117            _ => unreachable!("scratch stack discipline"),
1118        })
1119    }
1120
1121    fn parse_field_definition(&mut self) -> FieldDefinition<'a> {
1122        let start = self.current_start();
1123        let description = self.parse_description_if_present();
1124        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1125        let arguments = self.parse_arguments_definition_if_present();
1126        let ty = if self.peek() == Some(T![:]) {
1127            self.bump();
1128            self.parse_type_inner()
1129        } else {
1130            self.err("expected a Type");
1131            None
1132        };
1133        let directives = self.parse_directives(Constness::Const);
1134        FieldDefinition {
1135            description,
1136            name,
1137            arguments,
1138            ty,
1139            directives,
1140            span: self.span_from(start),
1141        }
1142    }
1143
1144    fn parse_arguments_definition_if_present(&mut self) -> ArenaVec<'a, InputValueDefinition<'a>> {
1145        if self.peek() != Some(T!['(']) {
1146            return ArenaVec::new_in(&self.allocator);
1147        }
1148
1149        self.bump();
1150        let mark = self.scratch_mark();
1151        self.peek_while(|parser, kind| match kind {
1152            T![')'] => {
1153                parser.bump();
1154                ControlFlow::Break(())
1155            }
1156            TokenKind::Name | TokenKind::StringValue => {
1157                let definition = parser.parse_input_value_definition();
1158                parser.scratch.push(ScratchNode::InputValueDefinition(definition));
1159                ControlFlow::Continue(())
1160            }
1161            TokenKind::Eof => {
1162                parser.err("expected )");
1163                ControlFlow::Break(())
1164            }
1165            _ => {
1166                parser.err_and_pop("expected an Argument Definition");
1167                ControlFlow::Continue(())
1168            }
1169        });
1170        self.drain_scratch(mark, |node| match node {
1171            ScratchNode::InputValueDefinition(definition) => definition,
1172            _ => unreachable!("scratch stack discipline"),
1173        })
1174    }
1175
1176    fn parse_input_value_definition(&mut self) -> InputValueDefinition<'a> {
1177        let start = self.current_start();
1178        let description = self.parse_description_if_present();
1179        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1180        let ty = if self.peek() == Some(T![:]) {
1181            self.bump();
1182            self.parse_type_inner()
1183        } else {
1184            self.err("expected a Type");
1185            None
1186        };
1187        let default_value = if self.peek() == Some(T![=]) {
1188            self.bump();
1189            Some(self.parse_value(Constness::Const, false))
1190        } else {
1191            None
1192        };
1193        let directives = self.parse_directives(Constness::Const);
1194        InputValueDefinition {
1195            description,
1196            name,
1197            ty,
1198            default_value,
1199            directives,
1200            span: self.span_from(start),
1201        }
1202    }
1203
1204    fn parse_union_type_definition(
1205        &mut self,
1206        description: Option<ArenaBox<'a, StringValue<'a>>>,
1207    ) -> UnionTypeDefinition<'a> {
1208        let start = self.definition_start(&description);
1209        self.expect_name_value("union");
1210        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1211        let directives = self.parse_directives(Constness::Const);
1212        let members = self.parse_union_members_if_present();
1213        UnionTypeDefinition { description, name, directives, members, span: self.span_from(start) }
1214    }
1215
1216    fn parse_union_type_extension_from(&mut self, start: u32) -> UnionTypeExtension<'a> {
1217        self.expect_name_value("union");
1218        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1219        let directives = self.parse_directives(Constness::Const);
1220        let members = self.parse_union_members_if_present();
1221        if directives.is_empty() && members.is_empty() {
1222            self.err("expected Directives or Union Member Types");
1223        }
1224        UnionTypeExtension { name, directives, members, span: self.span_from(start) }
1225    }
1226
1227    fn parse_union_members_if_present(&mut self) -> ArenaVec<'a, NamedType<'a>> {
1228        if self.peek() != Some(T![=]) {
1229            return ArenaVec::new_in(&self.allocator);
1230        }
1231
1232        self.bump();
1233        if self.peek() == Some(T![|]) {
1234            self.bump();
1235        }
1236
1237        let mut members = ArenaVec::new_in(&self.allocator);
1238        loop {
1239            if let Some(member) = self.parse_named_type() {
1240                members.push(member);
1241            } else {
1242                self.err("expected Union Member Type");
1243                break;
1244            }
1245
1246            if self.peek() == Some(T![|]) {
1247                self.bump();
1248            } else {
1249                break;
1250            }
1251        }
1252        members
1253    }
1254
1255    fn parse_enum_type_definition(
1256        &mut self,
1257        description: Option<ArenaBox<'a, StringValue<'a>>>,
1258    ) -> EnumTypeDefinition<'a> {
1259        let start = self.definition_start(&description);
1260        self.expect_name_value("enum");
1261        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1262        let directives = self.parse_directives(Constness::Const);
1263        let values = self.parse_enum_values_definition_if_present();
1264        EnumTypeDefinition { description, name, directives, values, span: self.span_from(start) }
1265    }
1266
1267    fn parse_enum_type_extension_from(&mut self, start: u32) -> EnumTypeExtension<'a> {
1268        self.expect_name_value("enum");
1269        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1270        let directives = self.parse_directives(Constness::Const);
1271        let values = self.parse_enum_values_definition_if_present();
1272        if directives.is_empty() && values.is_empty() {
1273            self.err("expected Directives or Enum Values Definition");
1274        }
1275        EnumTypeExtension { name, directives, values, span: self.span_from(start) }
1276    }
1277
1278    fn parse_enum_values_definition_if_present(&mut self) -> ArenaVec<'a, EnumValueDefinition<'a>> {
1279        if self.peek() != Some(T!['{']) {
1280            return ArenaVec::new_in(&self.allocator);
1281        }
1282
1283        self.bump();
1284        let mut values = ArenaVec::new_in(&self.allocator);
1285        self.peek_while(|parser, kind| match kind {
1286            T!['}'] => {
1287                if values.is_empty() {
1288                    parser.err("expected Enum Value Definition");
1289                }
1290                parser.bump();
1291                ControlFlow::Break(())
1292            }
1293            TokenKind::Name | TokenKind::StringValue => {
1294                values.push(parser.parse_enum_value_definition());
1295                ControlFlow::Continue(())
1296            }
1297            TokenKind::Eof => {
1298                parser.err("expected }");
1299                ControlFlow::Break(())
1300            }
1301            _ => {
1302                parser.err_and_pop("expected an Enum Value Definition");
1303                ControlFlow::Continue(())
1304            }
1305        });
1306        values
1307    }
1308
1309    fn parse_enum_value_definition(&mut self) -> EnumValueDefinition<'a> {
1310        let start = self.current_start();
1311        let description = self.parse_description_if_present();
1312        let value = EnumValue { name: self.parse_name().unwrap_or_else(|| self.missing_name()) };
1313        if matches!(value.name.as_str(), "true" | "false" | "null") {
1314            self.err("invalid Enum Value");
1315        }
1316        let directives = self.parse_directives(Constness::Const);
1317        EnumValueDefinition { description, value, directives, span: self.span_from(start) }
1318    }
1319
1320    fn parse_input_object_type_definition(
1321        &mut self,
1322        description: Option<ArenaBox<'a, StringValue<'a>>>,
1323    ) -> InputObjectTypeDefinition<'a> {
1324        let start = self.definition_start(&description);
1325        self.expect_name_value("input");
1326        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1327        let directives = self.parse_directives(Constness::Const);
1328        let fields = self.parse_input_fields_definition_if_present();
1329        InputObjectTypeDefinition {
1330            description,
1331            name,
1332            directives,
1333            fields,
1334            span: self.span_from(start),
1335        }
1336    }
1337
1338    fn parse_input_object_type_extension_from(
1339        &mut self,
1340        start: u32,
1341    ) -> InputObjectTypeExtension<'a> {
1342        self.expect_name_value("input");
1343        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1344        let directives = self.parse_directives(Constness::Const);
1345        let fields = self.parse_input_fields_definition_if_present();
1346        if directives.is_empty() && fields.is_empty() {
1347            self.err("expected Directives or Input Fields Definition");
1348        }
1349        InputObjectTypeExtension { name, directives, fields, span: self.span_from(start) }
1350    }
1351
1352    fn parse_input_fields_definition_if_present(
1353        &mut self,
1354    ) -> ArenaVec<'a, InputValueDefinition<'a>> {
1355        if self.peek() != Some(T!['{']) {
1356            return ArenaVec::new_in(&self.allocator);
1357        }
1358
1359        self.bump();
1360        let mark = self.scratch_mark();
1361        self.peek_while(|parser, kind| match kind {
1362            T!['}'] => {
1363                if parser.scratch.len() == mark {
1364                    parser.err("expected an Input Value Definition");
1365                }
1366                parser.bump();
1367                ControlFlow::Break(())
1368            }
1369            TokenKind::Name | TokenKind::StringValue => {
1370                let field = parser.parse_input_value_definition();
1371                parser.scratch.push(ScratchNode::InputValueDefinition(field));
1372                ControlFlow::Continue(())
1373            }
1374            TokenKind::Eof => {
1375                parser.err("expected }");
1376                ControlFlow::Break(())
1377            }
1378            _ => {
1379                parser.err_and_pop("expected an Input Value Definition");
1380                ControlFlow::Continue(())
1381            }
1382        });
1383        self.drain_scratch(mark, |node| match node {
1384            ScratchNode::InputValueDefinition(field) => field,
1385            _ => unreachable!("scratch stack discipline"),
1386        })
1387    }
1388
1389    fn parse_description_if_present(&mut self) -> Option<ArenaBox<'a, StringValue<'a>>> {
1390        if self.peek() == Some(TokenKind::StringValue) {
1391            let value = self.parse_string_value()?;
1392            Some(ArenaBox::new_in(value, &self.allocator))
1393        } else {
1394            None
1395        }
1396    }
1397
1398    /// The span start of a definition: the start of its already-parsed
1399    /// description if it has one, otherwise the start of the current token.
1400    fn definition_start(&mut self, description: &Option<ArenaBox<'a, StringValue<'a>>>) -> u32 {
1401        description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start)
1402    }
1403
1404    fn parse_string_value(&mut self) -> Option<StringValue<'a>> {
1405        let token = self.bump()?;
1406        let raw = token.data();
1407        let block = raw.starts_with(r#"""""#);
1408        let value = if block {
1409            let content = raw
1410                .strip_prefix(r#"""""#)
1411                .and_then(|value| value.strip_suffix(r#"""""#))
1412                .unwrap_or(raw);
1413            if content.contains('\r') {
1414                self.allocator.alloc_str(&normalize_block_string(raw))
1415            } else {
1416                // No line endings to normalize: borrow from the source text.
1417                content
1418            }
1419        } else {
1420            // Strip exactly one quote from each end: `trim_matches` would also
1421            // eat a trailing escaped quote (`"abc\""` must keep its `"`).
1422            let content =
1423                raw.strip_prefix('"').and_then(|value| value.strip_suffix('"')).unwrap_or(raw);
1424            if content.contains('\\') {
1425                self.allocator.alloc_str(&unescape_string(content))
1426            } else {
1427                // No escape sequences: borrow from the source text.
1428                content
1429            }
1430        };
1431        Some(StringValue { raw, value, block, span: token_span(&token) })
1432    }
1433
1434    fn parse_name(&mut self) -> Option<Name<'a>> {
1435        if self.peek()? != TokenKind::Name {
1436            self.err("expected a Name");
1437            return None;
1438        }
1439        let token = self.bump().expect("peeked Name token must be available");
1440        Some(Name { value: token.data(), span: token_span(&token) })
1441    }
1442
1443    fn expect_name_value(&mut self, expected: &str) {
1444        if self.peek_data() == Some(expected) {
1445            self.bump();
1446        } else {
1447            self.err(&format!("expected {expected}"));
1448        }
1449    }
1450
1451    fn expect(&mut self, token: TokenKind, message: &str) {
1452        if self.peek() == Some(token) {
1453            self.bump();
1454        } else {
1455            self.err(message);
1456        }
1457    }
1458
1459    fn missing_name(&self) -> Name<'a> {
1460        Name { value: "", span: Span::new(self.last_end, self.last_end) }
1461    }
1462
1463    fn missing_named_type(&self) -> NamedType<'a> {
1464        NamedType { name: self.missing_name() }
1465    }
1466
1467    fn missing_variable(&self) -> Variable<'a> {
1468        Variable { name: self.missing_name(), span: Span::new(self.last_end, self.last_end) }
1469    }
1470
1471    fn limit_err<S: Into<String>>(&mut self, message: S) {
1472        let index = if let Some(token) = self.peek_token() {
1473            token.index()
1474        } else {
1475            self.last_end as usize
1476        };
1477        self.push_err(Error::limit(message, index));
1478        self.accept_errors = false;
1479    }
1480
1481    fn err(&mut self, message: &str) {
1482        let Some(token) = self.peek_token().copied() else {
1483            return;
1484        };
1485        let err = if token.kind() == TokenKind::Eof {
1486            Error::eof(message, token.index())
1487        } else {
1488            Error::with_loc(message, token.data().to_string(), token.index())
1489        };
1490        self.push_err(err);
1491    }
1492
1493    fn err_and_pop(&mut self, message: &str) {
1494        let Some(token) = self.bump() else {
1495            return;
1496        };
1497        let err = if token.kind() == TokenKind::Eof {
1498            Error::eof(message, token.index())
1499        } else {
1500            Error::with_loc(message, token.data().to_string(), token.index())
1501        };
1502        self.push_err(err);
1503    }
1504
1505    fn push_err(&mut self, err: Error) {
1506        if self.accept_errors {
1507            self.errors.push(err);
1508        }
1509    }
1510
1511    fn peek_while(&mut self, mut run: impl FnMut(&mut Parser<'a>, TokenKind) -> ControlFlow<()>) {
1512        while let Some(kind) = self.peek() {
1513            let before = self.current_token;
1514            match run(self, kind) {
1515                ControlFlow::Break(()) => break,
1516                ControlFlow::Continue(()) => {
1517                    debug_assert!(
1518                        before != self.current_token,
1519                        "peek_while() iteration must advance parsing"
1520                    );
1521                }
1522            }
1523        }
1524    }
1525
1526    fn peek(&mut self) -> Option<TokenKind> {
1527        self.peek_token().map(Token::kind)
1528    }
1529
1530    fn peek_data(&mut self) -> Option<&'a str> {
1531        self.peek_token().map(Token::data)
1532    }
1533
1534    fn peek_token(&mut self) -> Option<&Token<'a>> {
1535        if self.current_token.is_none() {
1536            self.current_token = self.next_significant_token();
1537        }
1538        self.current_token.as_ref()
1539    }
1540
1541    fn bump(&mut self) -> Option<Token<'a>> {
1542        let token = if let Some(token) = self.current_token.take() {
1543            token
1544        } else {
1545            self.next_significant_token()?
1546        };
1547        self.last_end = span_index(token.index() + token.data().len());
1548        Some(token)
1549    }
1550
1551    fn next_significant_token(&mut self) -> Option<Token<'a>> {
1552        // `next_significant` skips whitespace and comma trivia in the cursor;
1553        // comments still surface as tokens so their spans can be recorded.
1554        loop {
1555            match self.lexer.next_significant()? {
1556                Ok(token) => match token.kind() {
1557                    TokenKind::Comment => {
1558                        let span = token_span(&token);
1559                        self.comments.push(span);
1560                    }
1561                    _ => return Some(token),
1562                },
1563                Err(err) => {
1564                    if err.is_limit() {
1565                        self.accept_errors = false;
1566                    }
1567                    self.errors.push(err);
1568                }
1569            }
1570        }
1571    }
1572
1573    fn current_start(&mut self) -> u32 {
1574        if let Some(token) = self.peek_token() { span_index(token.index()) } else { self.last_end }
1575    }
1576
1577    fn current_span(&mut self) -> Span {
1578        self.peek_token().map(token_span).unwrap_or_else(|| Span::new(self.last_end, self.last_end))
1579    }
1580
1581    fn span_from(&self, start: u32) -> Span {
1582        Span::new(start, self.last_end.max(start))
1583    }
1584}
1585
1586/// Converts a byte index to a span offset.
1587///
1588/// `Parser::new` asserts the source text fits in `u32`, so token indexes are
1589/// always in range.
1590#[expect(clippy::cast_possible_truncation)]
1591#[inline]
1592fn span_index(index: usize) -> u32 {
1593    debug_assert!(u32::try_from(index).is_ok());
1594    index as u32
1595}
1596
1597fn token_span(token: &Token<'_>) -> Span {
1598    let start = span_index(token.index());
1599    let end = span_index(token.index() + token.data().len());
1600    Span::new(start, end)
1601}
1602
1603fn unescape_string(input: &str) -> String {
1604    let mut output = String::with_capacity(input.len());
1605    let mut iter = input.chars();
1606    while let Some(c) = iter.next() {
1607        if c != '\\' {
1608            output.push(c);
1609            continue;
1610        }
1611
1612        let Some(c2) = iter.next() else {
1613            output.push(c);
1614            break;
1615        };
1616
1617        match c2 {
1618            '"' | '\\' | '/' => output.push(c2),
1619            'b' => output.push('\u{0008}'),
1620            'f' => output.push('\u{000c}'),
1621            'n' => output.push('\n'),
1622            'r' => output.push('\r'),
1623            't' => output.push('\t'),
1624            'u' => {
1625                let value = iter.by_ref().take(4).fold(0, |acc, c| {
1626                    let digit = c.to_digit(16).unwrap_or(0);
1627                    (acc << 4) + digit
1628                });
1629                if let Some(c) = char::from_u32(value) {
1630                    output.push(c);
1631                }
1632            }
1633            _ => {}
1634        }
1635    }
1636    output
1637}
1638
1639fn normalize_block_string(raw: &str) -> String {
1640    let content =
1641        raw.strip_prefix(r#"""""#).and_then(|value| value.strip_suffix(r#"""""#)).unwrap_or(raw);
1642    let mut output = String::with_capacity(content.len());
1643    let mut chars = content.chars().peekable();
1644    while let Some(ch) = chars.next() {
1645        if ch == '\r' {
1646            chars.next_if_eq(&'\n');
1647            output.push('\n');
1648        } else {
1649            output.push(ch);
1650        }
1651    }
1652    output
1653}