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