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