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