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