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