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}