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