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 =
291            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
292
293        if self.peek() == Some(T!['{']) {
294            let selection_set = Some(self.parse_alloc_selection_set());
295            return OperationDefinition {
296                description,
297                operation_type: OperationType::Query,
298                name: None,
299                variable_definitions: ArenaVec::new_in(&self.allocator),
300                directives: ArenaVec::new_in(&self.allocator),
301                selection_set,
302                span: self.span_from(start),
303            };
304        }
305
306        let operation_type = self.parse_operation_type("expected Operation Type");
307
308        let name = if self.peek() == Some(TokenKind::Name) { self.parse_name() } else { None };
309        let variable_definitions = self.parse_variable_definitions_if_present();
310        let directives = self.parse_directives(Constness::NotConst);
311        let selection_set = self.parse_required_selection_set();
312
313        OperationDefinition {
314            description,
315            operation_type,
316            name,
317            variable_definitions,
318            directives,
319            selection_set,
320            span: self.span_from(start),
321        }
322    }
323
324    fn parse_fragment_definition(
325        &mut self,
326        description: Option<ArenaBox<'a, StringValue<'a>>>,
327    ) -> FragmentDefinition<'a> {
328        let start =
329            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
330        self.expect_name_value("fragment");
331        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
332
333        let variable_definitions = if self.experimental_fragment_arguments {
334            self.parse_variable_definitions_if_present()
335        } else {
336            ArenaVec::new_in(&self.allocator)
337        };
338
339        self.expect_name_value("on");
340        let type_condition = self.parse_named_type().unwrap_or_else(|| self.missing_named_type());
341        let directives = self.parse_directives(Constness::NotConst);
342        let selection_set = self.parse_required_selection_set();
343
344        FragmentDefinition {
345            description,
346            name,
347            variable_definitions,
348            type_condition,
349            directives,
350            selection_set,
351            span: self.span_from(start),
352        }
353    }
354
355    fn parse_alloc_selection_set(&mut self) -> ArenaBox<'a, SelectionSet<'a>> {
356        let selection_set = self.parse_selection_set_inner();
357        ArenaBox::new_in(selection_set, &self.allocator)
358    }
359
360    /// Parse a selection set that is required in this position. If the next
361    /// token is not `{`, records an error and returns `None`.
362    fn parse_required_selection_set(&mut self) -> Option<ArenaBox<'a, SelectionSet<'a>>> {
363        if self.peek() == Some(T!['{']) {
364            Some(self.parse_alloc_selection_set())
365        } else {
366            self.err("expected a Selection Set");
367            None
368        }
369    }
370
371    /// Parse an operation type keyword (`query`, `mutation`, or `subscription`),
372    /// consuming it. If none is present, records an error using `missing` and
373    /// falls back to `OperationType::Query`.
374    fn parse_operation_type(&mut self, missing: &str) -> OperationType {
375        match self.peek_data() {
376            Some("query") => {
377                self.bump();
378                OperationType::Query
379            }
380            Some("mutation") => {
381                self.bump();
382                OperationType::Mutation
383            }
384            Some("subscription") => {
385                self.bump();
386                OperationType::Subscription
387            }
388            _ => {
389                self.err(missing);
390                OperationType::Query
391            }
392        }
393    }
394
395    fn parse_selection_set_inner(&mut self) -> SelectionSet<'a> {
396        let start = self.current_start();
397        self.expect(T!['{'], "expected {");
398
399        let mark = self.scratch_mark();
400
401        self.peek_while(|parser, kind| match kind {
402            T!['}'] => {
403                if parser.scratch.len() == mark {
404                    parser.err("expected Selection");
405                }
406                parser.bump();
407                ControlFlow::Break(())
408            }
409            TokenKind::Eof => {
410                parser.err("expected }");
411                ControlFlow::Break(())
412            }
413            _ if parser.recursion_limit.check_and_increment() => {
414                parser.limit_err("parser recursion limit reached");
415                ControlFlow::Break(())
416            }
417            _ => {
418                let selection = parser.parse_selection();
419                parser.scratch.push(ScratchNode::Selection(selection));
420                parser.recursion_limit.decrement();
421                ControlFlow::Continue(())
422            }
423        });
424
425        let selections = self.drain_scratch(mark, |node| match node {
426            ScratchNode::Selection(selection) => selection,
427            _ => unreachable!("scratch stack discipline"),
428        });
429
430        SelectionSet { selections, span: self.span_from(start) }
431    }
432
433    fn parse_selection(&mut self) -> Selection<'a> {
434        if self.peek() == Some(T![...]) {
435            self.parse_fragment_selection()
436        } else {
437            let field = self.parse_field();
438            Selection::Field(ArenaBox::new_in(field, &self.allocator))
439        }
440    }
441
442    fn parse_fragment_selection(&mut self) -> Selection<'a> {
443        let start = self.current_start();
444        self.expect(T![...], "expected ...");
445
446        if self.peek_data() == Some("on") {
447            self.bump();
448            let type_condition = self.parse_named_type();
449            let directives = self.parse_directives(Constness::NotConst);
450            let selection_set = self.parse_required_selection_set();
451            return Selection::InlineFragment(ArenaBox::new_in(
452                InlineFragment {
453                    type_condition,
454                    directives,
455                    selection_set,
456                    span: self.span_from(start),
457                },
458                &self.allocator,
459            ));
460        }
461
462        if matches!(self.peek(), Some(T![@] | T!['{'])) {
463            let directives = self.parse_directives(Constness::NotConst);
464            let selection_set = self.parse_required_selection_set();
465            return Selection::InlineFragment(ArenaBox::new_in(
466                InlineFragment {
467                    type_condition: None,
468                    directives,
469                    selection_set,
470                    span: self.span_from(start),
471                },
472                &self.allocator,
473            ));
474        }
475
476        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
477        let arguments = if self.experimental_fragment_arguments {
478            self.parse_arguments_if_present(Constness::NotConst)
479        } else {
480            ArenaVec::new_in(&self.allocator)
481        };
482        let directives = self.parse_directives(Constness::NotConst);
483        Selection::FragmentSpread(ArenaBox::new_in(
484            FragmentSpread { name, arguments, directives, span: self.span_from(start) },
485            &self.allocator,
486        ))
487    }
488
489    fn parse_field(&mut self) -> Field<'a> {
490        let start = self.current_start();
491        let first_name = self.parse_name().unwrap_or_else(|| self.missing_name());
492        let (alias, name) = if self.peek() == Some(T![:]) {
493            self.bump();
494            let name = self.parse_name().unwrap_or_else(|| self.missing_name());
495            (Some(first_name), name)
496        } else {
497            (None, first_name)
498        };
499
500        let arguments = self.parse_arguments_if_present(Constness::NotConst);
501        let directives = self.parse_directives(Constness::NotConst);
502        let selection_set = if self.peek() == Some(T!['{']) {
503            Some(self.parse_alloc_selection_set())
504        } else {
505            None
506        };
507
508        Field { alias, name, arguments, directives, selection_set, span: self.span_from(start) }
509    }
510
511    fn parse_arguments_if_present(&mut self, constness: Constness) -> ArenaVec<'a, Argument<'a>> {
512        if self.peek() != Some(T!['(']) {
513            return ArenaVec::new_in(&self.allocator);
514        }
515
516        self.bump();
517        let mark = self.scratch_mark();
518        self.peek_while(|parser, kind| match kind {
519            T![')'] => {
520                parser.bump();
521                ControlFlow::Break(())
522            }
523            TokenKind::Name => {
524                let argument = parser.parse_argument(constness);
525                parser.scratch.push(ScratchNode::Argument(argument));
526                ControlFlow::Continue(())
527            }
528            TokenKind::Eof => {
529                parser.err("expected )");
530                ControlFlow::Break(())
531            }
532            _ => {
533                parser.err_and_pop("expected an Argument");
534                ControlFlow::Continue(())
535            }
536        });
537        self.drain_scratch(mark, |node| match node {
538            ScratchNode::Argument(argument) => argument,
539            _ => unreachable!("scratch stack discipline"),
540        })
541    }
542
543    fn parse_argument(&mut self, constness: Constness) -> Argument<'a> {
544        let start = self.current_start();
545        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
546        let value = if self.peek() == Some(T![:]) {
547            self.bump();
548            Some(self.parse_value(constness, false))
549        } else {
550            self.err("expected :");
551            None
552        };
553        Argument { name, value, span: self.span_from(start) }
554    }
555
556    fn parse_variable_definitions_if_present(&mut self) -> ArenaVec<'a, VariableDefinition<'a>> {
557        if self.peek() != Some(T!['(']) {
558            return ArenaVec::new_in(&self.allocator);
559        }
560
561        self.bump();
562        let mark = self.scratch_mark();
563        self.peek_while(|parser, kind| match kind {
564            T![')'] => {
565                if parser.scratch.len() == mark {
566                    parser.err("expected a Variable Definition");
567                }
568                parser.bump();
569                ControlFlow::Break(())
570            }
571            T![$] | TokenKind::StringValue => {
572                let definition = parser.parse_variable_definition();
573                parser.scratch.push(ScratchNode::VariableDefinition(definition));
574                ControlFlow::Continue(())
575            }
576            TokenKind::Eof => {
577                parser.err("expected )");
578                ControlFlow::Break(())
579            }
580            _ => {
581                parser.err_and_pop("expected a Variable Definition");
582                ControlFlow::Continue(())
583            }
584        });
585        self.drain_scratch(mark, |node| match node {
586            ScratchNode::VariableDefinition(definition) => definition,
587            _ => unreachable!("scratch stack discipline"),
588        })
589    }
590
591    fn parse_variable_definition(&mut self) -> VariableDefinition<'a> {
592        let start = self.current_start();
593        let description = self.parse_description_if_present();
594        let variable = self.parse_variable().unwrap_or_else(|| self.missing_variable());
595        let mut ty = None;
596        let mut default_value = None;
597        let mut directives = ArenaVec::new_in(&self.allocator);
598
599        if self.peek() == Some(T![:]) {
600            self.bump();
601            ty = self.parse_type_inner();
602            if self.peek() == Some(T![=]) {
603                self.bump();
604                default_value = Some(self.parse_value(Constness::Const, false));
605            }
606            directives = self.parse_directives(Constness::Const);
607        } else {
608            self.err("expected a Name");
609        }
610
611        VariableDefinition {
612            description,
613            variable,
614            ty,
615            default_value,
616            directives,
617            span: self.span_from(start),
618        }
619    }
620
621    fn parse_variable(&mut self) -> Option<Variable<'a>> {
622        let start = self.current_start();
623        if self.peek() != Some(T![$]) {
624            self.err("expected a Variable");
625            return None;
626        }
627        self.bump();
628        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
629        Some(Variable { name, span: self.span_from(start) })
630    }
631
632    fn parse_directives(&mut self, constness: Constness) -> ArenaVec<'a, Directive<'a>> {
633        if self.peek() != Some(T![@]) {
634            return ArenaVec::new_in(&self.allocator);
635        }
636
637        let mark = self.scratch_mark();
638        while self.peek() == Some(T![@]) {
639            let directive = self.parse_directive(constness);
640            self.scratch.push(ScratchNode::Directive(directive));
641        }
642        self.drain_scratch(mark, |node| match node {
643            ScratchNode::Directive(directive) => directive,
644            _ => unreachable!("scratch stack discipline"),
645        })
646    }
647
648    fn parse_directive(&mut self, constness: Constness) -> Directive<'a> {
649        let start = self.current_start();
650        self.expect(T![@], "expected @ symbol");
651        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
652        let arguments = self.parse_arguments_if_present(constness);
653        Directive { name, arguments, span: self.span_from(start) }
654    }
655
656    fn parse_value(&mut self, constness: Constness, pop_on_error: bool) -> Value<'a> {
657        match self.peek() {
658            Some(T![$]) => {
659                if matches!(constness, Constness::Const) {
660                    self.err("unexpected variable value in a Const context");
661                }
662                match self.parse_variable() {
663                    Some(variable) => Value::Variable(ArenaBox::new_in(variable, &self.allocator)),
664                    None => Value::Missing(self.current_span()),
665                }
666            }
667            Some(TokenKind::Int) => self.parse_int_value(),
668            Some(TokenKind::Float) => self.parse_float_value(),
669            Some(TokenKind::StringValue) => match self.parse_string_value() {
670                Some(value) => Value::String(ArenaBox::new_in(value, &self.allocator)),
671                None => Value::Missing(self.current_span()),
672            },
673            Some(TokenKind::Name) => self.parse_name_value(),
674            Some(T!['[']) => self.parse_list_value(constness),
675            Some(T!['{']) => self.parse_object_value(constness),
676            _ => {
677                let message = "expected a valid Value";
678                if pop_on_error {
679                    self.err_and_pop(message);
680                } else {
681                    self.err(message);
682                }
683                Value::Missing(self.current_span())
684            }
685        }
686    }
687
688    fn parse_int_value(&mut self) -> Value<'a> {
689        let token = self.bump().expect("peeked int token must be available");
690        Value::Int(ArenaBox::new_in(
691            IntValue { raw: token.data(), span: token_span(&token) },
692            &self.allocator,
693        ))
694    }
695
696    fn parse_float_value(&mut self) -> Value<'a> {
697        let token = self.bump().expect("peeked float token must be available");
698        Value::Float(ArenaBox::new_in(
699            FloatValue { raw: token.data(), span: token_span(&token) },
700            &self.allocator,
701        ))
702    }
703
704    fn parse_name_value(&mut self) -> Value<'a> {
705        let Some(name) = self.parse_name() else {
706            return Value::Missing(self.current_span());
707        };
708        match name.value {
709            "true" => Value::Boolean(ArenaBox::new_in(
710                BooleanValue { value: true, span: name.span },
711                &self.allocator,
712            )),
713            "false" => Value::Boolean(ArenaBox::new_in(
714                BooleanValue { value: false, span: name.span },
715                &self.allocator,
716            )),
717            "null" => Value::Null(ArenaBox::new_in(NullValue { span: name.span }, &self.allocator)),
718            _ => Value::Enum(ArenaBox::new_in(EnumValue { name }, &self.allocator)),
719        }
720    }
721
722    fn parse_list_value(&mut self, constness: Constness) -> Value<'a> {
723        let start = self.current_start();
724        self.expect(T!['['], "expected [");
725        let mut values = ArenaVec::new_in(&self.allocator);
726
727        self.peek_while(|parser, kind| match kind {
728            T![']'] => {
729                parser.bump();
730                ControlFlow::Break(())
731            }
732            TokenKind::Eof => {
733                parser.err("expected ]");
734                ControlFlow::Break(())
735            }
736            _ if parser.recursion_limit.check_and_increment() => {
737                parser.limit_err("parser recursion limit reached");
738                ControlFlow::Break(())
739            }
740            _ => {
741                values.push(parser.parse_value(constness, true));
742                parser.recursion_limit.decrement();
743                ControlFlow::Continue(())
744            }
745        });
746
747        Value::List(ArenaBox::new_in(
748            ListValue { values, span: self.span_from(start) },
749            &self.allocator,
750        ))
751    }
752
753    fn parse_object_value(&mut self, constness: Constness) -> Value<'a> {
754        let start = self.current_start();
755        self.expect(T!['{'], "expected {");
756        let mut fields = ArenaVec::new_in(&self.allocator);
757
758        self.peek_while(|parser, kind| match kind {
759            T!['}'] => {
760                parser.bump();
761                ControlFlow::Break(())
762            }
763            TokenKind::Name if parser.recursion_limit.check_and_increment() => {
764                parser.limit_err("parser recursion limit reached");
765                ControlFlow::Break(())
766            }
767            TokenKind::Name => {
768                fields.push(parser.parse_object_field(constness));
769                parser.recursion_limit.decrement();
770                ControlFlow::Continue(())
771            }
772            TokenKind::Eof => {
773                parser.err("expected }");
774                ControlFlow::Break(())
775            }
776            _ => {
777                parser.err_and_pop("expected Object Field");
778                ControlFlow::Continue(())
779            }
780        });
781
782        Value::Object(ArenaBox::new_in(
783            ObjectValue { fields, span: self.span_from(start) },
784            &self.allocator,
785        ))
786    }
787
788    fn parse_object_field(&mut self, constness: Constness) -> ObjectField<'a> {
789        let start = self.current_start();
790        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
791        let value = if self.peek() == Some(T![:]) {
792            self.bump();
793            Some(self.parse_value(constness, true))
794        } else {
795            self.err("expected :");
796            None
797        };
798        ObjectField { name, value, span: self.span_from(start) }
799    }
800
801    fn parse_type_inner(&mut self) -> Option<Type<'a>> {
802        let start = self.current_start();
803        let mut ty = match self.peek() {
804            Some(T!['[']) => {
805                self.bump();
806                if self.recursion_limit.check_and_increment() {
807                    self.limit_err("parser recursion limit reached");
808                    return Some(Type::Missing(self.span_from(start)));
809                }
810                let inner =
811                    self.parse_type_inner().unwrap_or_else(|| Type::Missing(self.current_span()));
812                self.recursion_limit.decrement();
813                self.expect(T![']'], "expected ]");
814                Type::List(ArenaBox::new_in(
815                    ListType { ty: inner, span: self.span_from(start) },
816                    &self.allocator,
817                ))
818            }
819            Some(TokenKind::Name) => {
820                let name = self.parse_name().unwrap_or_else(|| self.missing_name());
821                Type::Named(ArenaBox::new_in(NamedType { name }, &self.allocator))
822            }
823            Some(_) => {
824                self.err("expected a type");
825                return None;
826            }
827            None => return None,
828        };
829
830        if self.peek() == Some(T![!]) {
831            self.bump();
832            ty = Type::NonNull(ArenaBox::new_in(
833                NonNullType { ty, span: self.span_from(start) },
834                &self.allocator,
835            ));
836        }
837
838        Some(ty)
839    }
840
841    fn parse_named_type(&mut self) -> Option<NamedType<'a>> {
842        self.parse_name().map(|name| NamedType { name })
843    }
844
845    fn parse_schema_definition(
846        &mut self,
847        description: Option<ArenaBox<'a, StringValue<'a>>>,
848    ) -> SchemaDefinition<'a> {
849        let start =
850            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
851        self.expect_name_value("schema");
852        let directives = self.parse_directives(Constness::Const);
853        let root_operations = self.parse_root_operation_types_if_present();
854        SchemaDefinition { description, directives, root_operations, span: self.span_from(start) }
855    }
856
857    fn parse_schema_extension_from(&mut self, start: u32) -> SchemaExtension<'a> {
858        self.expect_name_value("schema");
859        let directives = self.parse_directives(Constness::Const);
860        let root_operations = self.parse_root_operation_types_if_present();
861        if directives.is_empty() && root_operations.is_empty() {
862            self.err("expected Directives or Root Operation Types");
863        }
864        SchemaExtension { directives, root_operations, span: self.span_from(start) }
865    }
866
867    fn parse_root_operation_types_if_present(
868        &mut self,
869    ) -> ArenaVec<'a, RootOperationTypeDefinition<'a>> {
870        if self.peek() != Some(T!['{']) {
871            return ArenaVec::new_in(&self.allocator);
872        }
873
874        self.bump();
875        let mut root_operations = ArenaVec::new_in(&self.allocator);
876        self.peek_while(|parser, kind| match kind {
877            T!['}'] => {
878                parser.bump();
879                ControlFlow::Break(())
880            }
881            TokenKind::Name => {
882                root_operations.push(parser.parse_root_operation_type_definition());
883                ControlFlow::Continue(())
884            }
885            TokenKind::Eof => {
886                parser.err("expected }");
887                ControlFlow::Break(())
888            }
889            _ => {
890                parser.err_and_pop("expected Root Operation Type Definition");
891                ControlFlow::Continue(())
892            }
893        });
894        root_operations
895    }
896
897    fn parse_root_operation_type_definition(&mut self) -> RootOperationTypeDefinition<'a> {
898        let start = self.current_start();
899        let operation_type = self.parse_operation_type("expected an Operation Type");
900        self.expect(T![:], "expected :");
901        let named_type = self.parse_named_type().unwrap_or_else(|| self.missing_named_type());
902        RootOperationTypeDefinition { operation_type, named_type, span: self.span_from(start) }
903    }
904
905    fn parse_directive_extension_from(&mut self, start: u32) -> DirectiveExtension<'a> {
906        self.expect_name_value("directive");
907        self.expect(T![@], "expected @ symbol");
908        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
909        let directives = self.parse_directives(Constness::Const);
910        if directives.is_empty() {
911            self.err("expected Directives");
912        }
913        DirectiveExtension { name, directives, span: self.span_from(start) }
914    }
915
916    fn parse_directive_definition(
917        &mut self,
918        description: Option<ArenaBox<'a, StringValue<'a>>>,
919    ) -> DirectiveDefinition<'a> {
920        let start =
921            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
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 =
978            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
979        self.expect_name_value("scalar");
980        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
981        let directives = self.parse_directives(Constness::Const);
982        ScalarTypeDefinition { description, name, directives, span: self.span_from(start) }
983    }
984
985    fn parse_scalar_type_extension_from(&mut self, start: u32) -> ScalarTypeExtension<'a> {
986        self.expect_name_value("scalar");
987        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
988        let directives = self.parse_directives(Constness::Const);
989        if directives.is_empty() {
990            self.err("expected Directives");
991        }
992        ScalarTypeExtension { name, directives, span: self.span_from(start) }
993    }
994
995    fn parse_object_type_definition(
996        &mut self,
997        description: Option<ArenaBox<'a, StringValue<'a>>>,
998    ) -> ObjectTypeDefinition<'a> {
999        let start =
1000            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
1001        self.expect_name_value("type");
1002        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1003        let interfaces = self.parse_implements_interfaces();
1004        let directives = self.parse_directives(Constness::Const);
1005        let fields = self.parse_fields_definition_if_present();
1006        ObjectTypeDefinition {
1007            description,
1008            name,
1009            interfaces,
1010            directives,
1011            fields,
1012            span: self.span_from(start),
1013        }
1014    }
1015
1016    fn parse_object_type_extension_from(&mut self, start: u32) -> ObjectTypeExtension<'a> {
1017        self.expect_name_value("type");
1018        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1019        let interfaces = self.parse_implements_interfaces();
1020        let directives = self.parse_directives(Constness::Const);
1021        let fields = self.parse_fields_definition_if_present();
1022        if interfaces.is_empty() && directives.is_empty() && fields.is_empty() {
1023            self.err("expected Implements Interfaces, Directives, or Fields Definition");
1024        }
1025        ObjectTypeExtension { name, interfaces, directives, fields, span: self.span_from(start) }
1026    }
1027
1028    fn parse_interface_type_definition(
1029        &mut self,
1030        description: Option<ArenaBox<'a, StringValue<'a>>>,
1031    ) -> InterfaceTypeDefinition<'a> {
1032        let start =
1033            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
1034        self.expect_name_value("interface");
1035        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1036        let interfaces = self.parse_implements_interfaces();
1037        let directives = self.parse_directives(Constness::Const);
1038        let fields = self.parse_fields_definition_if_present();
1039        InterfaceTypeDefinition {
1040            description,
1041            name,
1042            interfaces,
1043            directives,
1044            fields,
1045            span: self.span_from(start),
1046        }
1047    }
1048
1049    fn parse_interface_type_extension_from(&mut self, start: u32) -> InterfaceTypeExtension<'a> {
1050        self.expect_name_value("interface");
1051        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1052        let interfaces = self.parse_implements_interfaces();
1053        let directives = self.parse_directives(Constness::Const);
1054        let fields = self.parse_fields_definition_if_present();
1055        if interfaces.is_empty() && directives.is_empty() && fields.is_empty() {
1056            self.err("expected an Implements Interfaces, Directives, or a Fields Definition");
1057        }
1058        InterfaceTypeExtension { name, interfaces, directives, fields, span: self.span_from(start) }
1059    }
1060
1061    fn parse_implements_interfaces(&mut self) -> ArenaVec<'a, NamedType<'a>> {
1062        if self.peek_data() != Some("implements") {
1063            return ArenaVec::new_in(&self.allocator);
1064        }
1065
1066        self.bump();
1067        if self.peek() == Some(T![&]) {
1068            self.bump();
1069        }
1070
1071        let mut interfaces = ArenaVec::new_in(&self.allocator);
1072        loop {
1073            if let Some(named_type) = self.parse_named_type() {
1074                interfaces.push(named_type);
1075            } else {
1076                self.err("expected Implements Interface");
1077                break;
1078            }
1079
1080            if self.peek() == Some(T![&]) {
1081                self.bump();
1082            } else {
1083                break;
1084            }
1085        }
1086        interfaces
1087    }
1088
1089    fn parse_fields_definition_if_present(&mut self) -> ArenaVec<'a, FieldDefinition<'a>> {
1090        if self.peek() != Some(T!['{']) {
1091            return ArenaVec::new_in(&self.allocator);
1092        }
1093
1094        self.bump();
1095        let mark = self.scratch_mark();
1096        self.peek_while(|parser, kind| match kind {
1097            T!['}'] => {
1098                if parser.scratch.len() == mark {
1099                    parser.err("expected Field Definition");
1100                }
1101                parser.bump();
1102                ControlFlow::Break(())
1103            }
1104            TokenKind::Name | TokenKind::StringValue => {
1105                let field = parser.parse_field_definition();
1106                parser.scratch.push(ScratchNode::FieldDefinition(field));
1107                ControlFlow::Continue(())
1108            }
1109            TokenKind::Eof => {
1110                parser.err("expected }");
1111                ControlFlow::Break(())
1112            }
1113            _ => {
1114                parser.err_and_pop("expected a Field Definition");
1115                ControlFlow::Continue(())
1116            }
1117        });
1118        self.drain_scratch(mark, |node| match node {
1119            ScratchNode::FieldDefinition(field) => field,
1120            _ => unreachable!("scratch stack discipline"),
1121        })
1122    }
1123
1124    fn parse_field_definition(&mut self) -> FieldDefinition<'a> {
1125        let start = self.current_start();
1126        let description = self.parse_description_if_present();
1127        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1128        let arguments = self.parse_arguments_definition_if_present();
1129        let ty = if self.peek() == Some(T![:]) {
1130            self.bump();
1131            self.parse_type_inner()
1132        } else {
1133            self.err("expected a Type");
1134            None
1135        };
1136        let directives = self.parse_directives(Constness::Const);
1137        FieldDefinition {
1138            description,
1139            name,
1140            arguments,
1141            ty,
1142            directives,
1143            span: self.span_from(start),
1144        }
1145    }
1146
1147    fn parse_arguments_definition_if_present(&mut self) -> ArenaVec<'a, InputValueDefinition<'a>> {
1148        if self.peek() != Some(T!['(']) {
1149            return ArenaVec::new_in(&self.allocator);
1150        }
1151
1152        self.bump();
1153        let mark = self.scratch_mark();
1154        self.peek_while(|parser, kind| match kind {
1155            T![')'] => {
1156                parser.bump();
1157                ControlFlow::Break(())
1158            }
1159            TokenKind::Name | TokenKind::StringValue => {
1160                let definition = parser.parse_input_value_definition();
1161                parser.scratch.push(ScratchNode::InputValueDefinition(definition));
1162                ControlFlow::Continue(())
1163            }
1164            TokenKind::Eof => {
1165                parser.err("expected )");
1166                ControlFlow::Break(())
1167            }
1168            _ => {
1169                parser.err_and_pop("expected an Argument Definition");
1170                ControlFlow::Continue(())
1171            }
1172        });
1173        self.drain_scratch(mark, |node| match node {
1174            ScratchNode::InputValueDefinition(definition) => definition,
1175            _ => unreachable!("scratch stack discipline"),
1176        })
1177    }
1178
1179    fn parse_input_value_definition(&mut self) -> InputValueDefinition<'a> {
1180        let start = self.current_start();
1181        let description = self.parse_description_if_present();
1182        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1183        let ty = if self.peek() == Some(T![:]) {
1184            self.bump();
1185            self.parse_type_inner()
1186        } else {
1187            self.err("expected a Type");
1188            None
1189        };
1190        let default_value = if self.peek() == Some(T![=]) {
1191            self.bump();
1192            Some(self.parse_value(Constness::Const, false))
1193        } else {
1194            None
1195        };
1196        let directives = self.parse_directives(Constness::Const);
1197        InputValueDefinition {
1198            description,
1199            name,
1200            ty,
1201            default_value,
1202            directives,
1203            span: self.span_from(start),
1204        }
1205    }
1206
1207    fn parse_union_type_definition(
1208        &mut self,
1209        description: Option<ArenaBox<'a, StringValue<'a>>>,
1210    ) -> UnionTypeDefinition<'a> {
1211        let start =
1212            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
1213        self.expect_name_value("union");
1214        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1215        let directives = self.parse_directives(Constness::Const);
1216        let members = self.parse_union_members_if_present();
1217        UnionTypeDefinition { description, name, directives, members, span: self.span_from(start) }
1218    }
1219
1220    fn parse_union_type_extension_from(&mut self, start: u32) -> UnionTypeExtension<'a> {
1221        self.expect_name_value("union");
1222        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1223        let directives = self.parse_directives(Constness::Const);
1224        let members = self.parse_union_members_if_present();
1225        if directives.is_empty() && members.is_empty() {
1226            self.err("expected Directives or Union Member Types");
1227        }
1228        UnionTypeExtension { name, directives, members, span: self.span_from(start) }
1229    }
1230
1231    fn parse_union_members_if_present(&mut self) -> ArenaVec<'a, NamedType<'a>> {
1232        if self.peek() != Some(T![=]) {
1233            return ArenaVec::new_in(&self.allocator);
1234        }
1235
1236        self.bump();
1237        if self.peek() == Some(T![|]) {
1238            self.bump();
1239        }
1240
1241        let mut members = ArenaVec::new_in(&self.allocator);
1242        loop {
1243            if let Some(member) = self.parse_named_type() {
1244                members.push(member);
1245            } else {
1246                self.err("expected Union Member Type");
1247                break;
1248            }
1249
1250            if self.peek() == Some(T![|]) {
1251                self.bump();
1252            } else {
1253                break;
1254            }
1255        }
1256        members
1257    }
1258
1259    fn parse_enum_type_definition(
1260        &mut self,
1261        description: Option<ArenaBox<'a, StringValue<'a>>>,
1262    ) -> EnumTypeDefinition<'a> {
1263        let start =
1264            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
1265        self.expect_name_value("enum");
1266        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1267        let directives = self.parse_directives(Constness::Const);
1268        let values = self.parse_enum_values_definition_if_present();
1269        EnumTypeDefinition { description, name, directives, values, span: self.span_from(start) }
1270    }
1271
1272    fn parse_enum_type_extension_from(&mut self, start: u32) -> EnumTypeExtension<'a> {
1273        self.expect_name_value("enum");
1274        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1275        let directives = self.parse_directives(Constness::Const);
1276        let values = self.parse_enum_values_definition_if_present();
1277        if directives.is_empty() && values.is_empty() {
1278            self.err("expected Directives or Enum Values Definition");
1279        }
1280        EnumTypeExtension { name, directives, values, span: self.span_from(start) }
1281    }
1282
1283    fn parse_enum_values_definition_if_present(&mut self) -> ArenaVec<'a, EnumValueDefinition<'a>> {
1284        if self.peek() != Some(T!['{']) {
1285            return ArenaVec::new_in(&self.allocator);
1286        }
1287
1288        self.bump();
1289        let mut values = ArenaVec::new_in(&self.allocator);
1290        self.peek_while(|parser, kind| match kind {
1291            T!['}'] => {
1292                if values.is_empty() {
1293                    parser.err("expected Enum Value Definition");
1294                }
1295                parser.bump();
1296                ControlFlow::Break(())
1297            }
1298            TokenKind::Name | TokenKind::StringValue => {
1299                values.push(parser.parse_enum_value_definition());
1300                ControlFlow::Continue(())
1301            }
1302            TokenKind::Eof => {
1303                parser.err("expected }");
1304                ControlFlow::Break(())
1305            }
1306            _ => {
1307                parser.err_and_pop("expected an Enum Value Definition");
1308                ControlFlow::Continue(())
1309            }
1310        });
1311        values
1312    }
1313
1314    fn parse_enum_value_definition(&mut self) -> EnumValueDefinition<'a> {
1315        let start = self.current_start();
1316        let description = self.parse_description_if_present();
1317        let value = EnumValue { name: self.parse_name().unwrap_or_else(|| self.missing_name()) };
1318        if matches!(value.name.as_str(), "true" | "false" | "null") {
1319            self.err("invalid Enum Value");
1320        }
1321        let directives = self.parse_directives(Constness::Const);
1322        EnumValueDefinition { description, value, directives, span: self.span_from(start) }
1323    }
1324
1325    fn parse_input_object_type_definition(
1326        &mut self,
1327        description: Option<ArenaBox<'a, StringValue<'a>>>,
1328    ) -> InputObjectTypeDefinition<'a> {
1329        let start =
1330            description.as_ref().map_or_else(|| self.current_start(), |value| value.span.start);
1331        self.expect_name_value("input");
1332        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1333        let directives = self.parse_directives(Constness::Const);
1334        let fields = self.parse_input_fields_definition_if_present();
1335        InputObjectTypeDefinition {
1336            description,
1337            name,
1338            directives,
1339            fields,
1340            span: self.span_from(start),
1341        }
1342    }
1343
1344    fn parse_input_object_type_extension_from(
1345        &mut self,
1346        start: u32,
1347    ) -> InputObjectTypeExtension<'a> {
1348        self.expect_name_value("input");
1349        let name = self.parse_name().unwrap_or_else(|| self.missing_name());
1350        let directives = self.parse_directives(Constness::Const);
1351        let fields = self.parse_input_fields_definition_if_present();
1352        if directives.is_empty() && fields.is_empty() {
1353            self.err("expected Directives or Input Fields Definition");
1354        }
1355        InputObjectTypeExtension { name, directives, fields, span: self.span_from(start) }
1356    }
1357
1358    fn parse_input_fields_definition_if_present(
1359        &mut self,
1360    ) -> ArenaVec<'a, InputValueDefinition<'a>> {
1361        if self.peek() != Some(T!['{']) {
1362            return ArenaVec::new_in(&self.allocator);
1363        }
1364
1365        self.bump();
1366        let mark = self.scratch_mark();
1367        self.peek_while(|parser, kind| match kind {
1368            T!['}'] => {
1369                if parser.scratch.len() == mark {
1370                    parser.err("expected an Input Value Definition");
1371                }
1372                parser.bump();
1373                ControlFlow::Break(())
1374            }
1375            TokenKind::Name | TokenKind::StringValue => {
1376                let field = parser.parse_input_value_definition();
1377                parser.scratch.push(ScratchNode::InputValueDefinition(field));
1378                ControlFlow::Continue(())
1379            }
1380            TokenKind::Eof => {
1381                parser.err("expected }");
1382                ControlFlow::Break(())
1383            }
1384            _ => {
1385                parser.err_and_pop("expected an Input Value Definition");
1386                ControlFlow::Continue(())
1387            }
1388        });
1389        self.drain_scratch(mark, |node| match node {
1390            ScratchNode::InputValueDefinition(field) => field,
1391            _ => unreachable!("scratch stack discipline"),
1392        })
1393    }
1394
1395    fn parse_description_if_present(&mut self) -> Option<ArenaBox<'a, StringValue<'a>>> {
1396        if self.peek() == Some(TokenKind::StringValue) {
1397            let value = self.parse_string_value()?;
1398            Some(ArenaBox::new_in(value, &self.allocator))
1399        } else {
1400            None
1401        }
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            let content = raw.trim_matches('"');
1421            if content.contains('\\') {
1422                self.allocator.alloc_str(&unescape_string(content))
1423            } else {
1424                // No escape sequences: borrow from the source text.
1425                content
1426            }
1427        };
1428        Some(StringValue { raw, value, block, span: token_span(&token) })
1429    }
1430
1431    fn parse_name(&mut self) -> Option<Name<'a>> {
1432        if self.peek()? != TokenKind::Name {
1433            self.err("expected a Name");
1434            return None;
1435        }
1436        let token = self.bump().expect("peeked Name token must be available");
1437        Some(Name { value: token.data(), span: token_span(&token) })
1438    }
1439
1440    fn expect_name_value(&mut self, expected: &str) {
1441        if self.peek_data() == Some(expected) {
1442            self.bump();
1443        } else {
1444            self.err(&format!("expected {expected}"));
1445        }
1446    }
1447
1448    fn expect(&mut self, token: TokenKind, message: &str) {
1449        if self.peek() == Some(token) {
1450            self.bump();
1451        } else {
1452            self.err(message);
1453        }
1454    }
1455
1456    fn missing_name(&self) -> Name<'a> {
1457        Name { value: "", span: Span::new(self.last_end, self.last_end) }
1458    }
1459
1460    fn missing_named_type(&self) -> NamedType<'a> {
1461        NamedType { name: self.missing_name() }
1462    }
1463
1464    fn missing_variable(&self) -> Variable<'a> {
1465        Variable { name: self.missing_name(), span: Span::new(self.last_end, self.last_end) }
1466    }
1467
1468    fn limit_err<S: Into<String>>(&mut self, message: S) {
1469        let index = if let Some(token) = self.peek_token() {
1470            token.index()
1471        } else {
1472            self.last_end as usize
1473        };
1474        self.push_err(Error::limit(message, index));
1475        self.accept_errors = false;
1476    }
1477
1478    fn err(&mut self, message: &str) {
1479        let Some(token) = self.peek_token().copied() else {
1480            return;
1481        };
1482        let err = if token.kind() == TokenKind::Eof {
1483            Error::eof(message, token.index())
1484        } else {
1485            Error::with_loc(message, token.data().to_string(), token.index())
1486        };
1487        self.push_err(err);
1488    }
1489
1490    fn err_and_pop(&mut self, message: &str) {
1491        let Some(token) = self.bump() else {
1492            return;
1493        };
1494        let err = if token.kind() == TokenKind::Eof {
1495            Error::eof(message, token.index())
1496        } else {
1497            Error::with_loc(message, token.data().to_string(), token.index())
1498        };
1499        self.push_err(err);
1500    }
1501
1502    fn push_err(&mut self, err: Error) {
1503        if self.accept_errors {
1504            self.errors.push(err);
1505        }
1506    }
1507
1508    fn peek_while(&mut self, mut run: impl FnMut(&mut Parser<'a>, TokenKind) -> ControlFlow<()>) {
1509        while let Some(kind) = self.peek() {
1510            let before = self.current_token;
1511            match run(self, kind) {
1512                ControlFlow::Break(()) => break,
1513                ControlFlow::Continue(()) => {
1514                    debug_assert!(
1515                        before != self.current_token,
1516                        "peek_while() iteration must advance parsing"
1517                    );
1518                }
1519            }
1520        }
1521    }
1522
1523    fn peek(&mut self) -> Option<TokenKind> {
1524        self.peek_token().map(Token::kind)
1525    }
1526
1527    fn peek_data(&mut self) -> Option<&'a str> {
1528        self.peek_token().map(Token::data)
1529    }
1530
1531    fn peek_token(&mut self) -> Option<&Token<'a>> {
1532        if self.current_token.is_none() {
1533            self.current_token = self.next_significant_token();
1534        }
1535        self.current_token.as_ref()
1536    }
1537
1538    fn bump(&mut self) -> Option<Token<'a>> {
1539        let token = if let Some(token) = self.current_token.take() {
1540            token
1541        } else {
1542            self.next_significant_token()?
1543        };
1544        self.last_end = span_index(token.index() + token.data().len());
1545        Some(token)
1546    }
1547
1548    fn next_significant_token(&mut self) -> Option<Token<'a>> {
1549        // `next_significant` skips whitespace and comma trivia in the cursor;
1550        // comments still surface as tokens so their spans can be recorded.
1551        loop {
1552            match self.lexer.next_significant()? {
1553                Ok(token) => match token.kind() {
1554                    TokenKind::Comment => {
1555                        let span = token_span(&token);
1556                        self.comments.push(span);
1557                    }
1558                    _ => return Some(token),
1559                },
1560                Err(err) => {
1561                    if err.is_limit() {
1562                        self.accept_errors = false;
1563                    }
1564                    self.errors.push(err);
1565                }
1566            }
1567        }
1568    }
1569
1570    fn current_start(&mut self) -> u32 {
1571        if let Some(token) = self.peek_token() { span_index(token.index()) } else { self.last_end }
1572    }
1573
1574    fn current_span(&mut self) -> Span {
1575        self.peek_token().map(token_span).unwrap_or_else(|| Span::new(self.last_end, self.last_end))
1576    }
1577
1578    fn span_from(&self, start: u32) -> Span {
1579        Span::new(start, self.last_end.max(start))
1580    }
1581}
1582
1583/// Converts a byte index to a span offset.
1584///
1585/// `Parser::new` asserts the source text fits in `u32`, so token indexes are
1586/// always in range.
1587#[expect(clippy::cast_possible_truncation)]
1588#[inline]
1589fn span_index(index: usize) -> u32 {
1590    debug_assert!(u32::try_from(index).is_ok());
1591    index as u32
1592}
1593
1594fn token_span(token: &Token<'_>) -> Span {
1595    let start = span_index(token.index());
1596    let end = span_index(token.index() + token.data().len());
1597    Span::new(start, end)
1598}
1599
1600fn unescape_string(input: &str) -> String {
1601    let mut output = String::with_capacity(input.len());
1602    let mut iter = input.chars();
1603    while let Some(c) = iter.next() {
1604        if c != '\\' {
1605            output.push(c);
1606            continue;
1607        }
1608
1609        let Some(c2) = iter.next() else {
1610            output.push(c);
1611            break;
1612        };
1613
1614        match c2 {
1615            '"' | '\\' | '/' => output.push(c2),
1616            'b' => output.push('\u{0008}'),
1617            'f' => output.push('\u{000c}'),
1618            'n' => output.push('\n'),
1619            'r' => output.push('\r'),
1620            't' => output.push('\t'),
1621            'u' => {
1622                let value = iter.by_ref().take(4).fold(0, |acc, c| {
1623                    let digit = c.to_digit(16).unwrap_or(0);
1624                    (acc << 4) + digit
1625                });
1626                if let Some(c) = char::from_u32(value) {
1627                    output.push(c);
1628                }
1629            }
1630            _ => {}
1631        }
1632    }
1633    output
1634}
1635
1636fn normalize_block_string(raw: &str) -> String {
1637    let content =
1638        raw.strip_prefix(r#"""""#).and_then(|value| value.strip_suffix(r#"""""#)).unwrap_or(raw);
1639    let mut output = String::with_capacity(content.len());
1640    let mut chars = content.chars().peekable();
1641    while let Some(ch) = chars.next() {
1642        if ch == '\r' {
1643            if chars.peek() == Some(&'\n') {
1644                chars.next();
1645            }
1646            output.push('\n');
1647        } else {
1648            output.push(ch);
1649        }
1650    }
1651    output
1652}