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