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