1use crate::ByteSpan;
24use crate::ast;
25use crate::GraphQLParseError;
26use crate::GraphQLParseErrorKind;
27use crate::GraphQLParserConfig;
28use crate::GraphQLTokenStream;
29use crate::ParseResult;
30use crate::ReservedNameContext;
31use crate::SourceSpan;
32use crate::ValueParsingError;
33use crate::token::GraphQLToken;
34use crate::token::GraphQLTokenKind;
35use crate::token::GraphQLTokenSource;
36use crate::token::StrGraphQLTokenSource;
37use smallvec::SmallVec;
38use std::borrow::Cow;
39
40#[derive(Debug, Clone, Copy)]
46enum DelimiterContext {
47 SchemaDefinition,
49 ObjectTypeDefinition,
51 InterfaceDefinition,
53 EnumDefinition,
55 InputObjectDefinition,
57 SelectionSet,
59 FieldArguments,
61 DirectiveArguments,
63 VariableDefinitions,
65 ListType,
67 ListValue,
69 ObjectValue,
71 ArgumentDefinitions,
73}
74
75impl DelimiterContext {
76 fn description(&self) -> &'static str {
78 match self {
79 DelimiterContext::SchemaDefinition => "schema definition",
80 DelimiterContext::ObjectTypeDefinition => "object type definition",
81 DelimiterContext::InterfaceDefinition => "interface definition",
82 DelimiterContext::EnumDefinition => "enum definition",
83 DelimiterContext::InputObjectDefinition => "input object definition",
84 DelimiterContext::SelectionSet => "selection set",
85 DelimiterContext::FieldArguments => "field arguments",
86 DelimiterContext::DirectiveArguments => "directive arguments",
87 DelimiterContext::VariableDefinitions => "variable definitions",
88 DelimiterContext::ListType => "list type annotation",
89 DelimiterContext::ListValue => "list value",
90 DelimiterContext::ObjectValue => "object value",
91 DelimiterContext::ArgumentDefinitions => "argument definitions",
92 }
93 }
94}
95
96#[derive(Debug, Clone)]
98struct OpenDelimiter {
99 span: ByteSpan,
101 context: DelimiterContext,
103}
104
105enum RecoveryAction {
107 Stop,
109 Skip,
111 CheckKeyword(String),
113 CheckDescription,
115}
116
117#[derive(Clone, Copy, Debug)]
122enum ConstContext {
123 AllowVariables,
125 VariableDefaultValue,
127 DirectiveArgument,
129 InputDefaultValue,
131}
132
133impl ConstContext {
134 fn description(&self) -> &'static str {
139 match self {
140 ConstContext::AllowVariables => {
141 unreachable!("description() called on AllowVariables")
142 }
143 ConstContext::VariableDefaultValue => "variable default values",
144 ConstContext::DirectiveArgument => "directive arguments",
145 ConstContext::InputDefaultValue => "input field default values",
146 }
147 }
148}
149
150struct ImplementsClause<'src> {
158 ampersands: Vec<GraphQLToken<'src>>,
159 implements_keyword: GraphQLToken<'src>,
160 interfaces: Vec<ast::Name<'src>>,
161 leading_ampersand: Option<GraphQLToken<'src>>,
162}
163
164struct ImplementsClauseTokens<'src> {
168 ampersands: Vec<GraphQLToken<'src>>,
169 implements_keyword: GraphQLToken<'src>,
170 leading_ampersand: Option<GraphQLToken<'src>>,
171}
172
173pub struct GraphQLParser<'src, TTokenSource: GraphQLTokenSource<'src> = StrGraphQLTokenSource<'src>> {
214 config: GraphQLParserConfig,
217
218 token_stream: GraphQLTokenStream<'src, TTokenSource>,
220
221 errors: Vec<GraphQLParseError>,
223
224 delimiter_stack: SmallVec<[OpenDelimiter; 8]>,
229
230 recursion_depth: usize,
239
240 last_end_position: Option<u32>,
244}
245
246impl<'src> GraphQLParser<'src, StrGraphQLTokenSource<'src>> {
247 pub fn new<S: AsRef<str> + ?Sized>(
263 source: &'src S,
264 ) -> Self {
265 let token_source =
266 StrGraphQLTokenSource::new(source.as_ref());
267 Self::from_token_source(token_source)
268 }
269
270 pub fn with_config<S: AsRef<str> + ?Sized>(
286 source: &'src S,
287 config: GraphQLParserConfig,
288 ) -> Self {
289 let token_source =
290 StrGraphQLTokenSource::new(source.as_ref());
291 Self::from_token_source_with_config(token_source, config)
292 }
293}
294
295impl<'src, TTokenSource: GraphQLTokenSource<'src>> GraphQLParser<'src, TTokenSource> {
296 const MAX_RECURSION_DEPTH: usize = 32;
306
307 pub fn from_token_source(
310 token_source: TTokenSource,
311 ) -> Self {
312 Self::from_token_source_with_config(
313 token_source,
314 GraphQLParserConfig::default(),
315 )
316 }
317
318 pub fn from_token_source_with_config(
321 token_source: TTokenSource,
322 config: GraphQLParserConfig,
323 ) -> Self {
324 Self {
325 config,
326 token_stream: GraphQLTokenStream::new(token_source),
327 errors: Vec::new(),
328 delimiter_stack: SmallVec::new(),
329 recursion_depth: 0,
330 last_end_position: None,
331 }
332 }
333
334 fn record_error(&mut self, error: GraphQLParseError) {
340 self.errors.push(error);
341 }
342
343 fn resolve_span(&self, span: ByteSpan) -> SourceSpan {
353 self.token_stream.source_map().resolve_span(span)
354 .unwrap_or_else(SourceSpan::zero)
355 }
356
357 fn push_delimiter(
359 &mut self,
360 span: ByteSpan,
361 context: DelimiterContext,
362 ) {
363 self.delimiter_stack.push(OpenDelimiter { span, context });
364 }
365
366 fn pop_delimiter(&mut self) -> Option<OpenDelimiter> {
368 self.delimiter_stack.pop()
369 }
370
371 fn recover_to_next_definition(&mut self) {
377 loop {
378 let action = match self.token_stream.peek() {
380 None => RecoveryAction::Stop,
381 Some(token) => match &token.kind {
382 GraphQLTokenKind::Eof => RecoveryAction::Stop,
383 GraphQLTokenKind::CurlyBraceOpen => RecoveryAction::Stop,
384 GraphQLTokenKind::Name(name) => {
385 let name_owned = name.to_string();
386 RecoveryAction::CheckKeyword(name_owned)
387 }
388 GraphQLTokenKind::StringValue(_) => {
389 RecoveryAction::CheckDescription
390 }
391 _ => RecoveryAction::Skip,
392 },
393 };
394
395 match action {
396 RecoveryAction::Stop => break,
397 RecoveryAction::Skip => {
398 self.consume_token();
399 }
400 RecoveryAction::CheckKeyword(keyword) => {
401 if self.looks_like_definition_start(&keyword) {
402 break;
403 }
404 self.consume_token();
405 }
406 RecoveryAction::CheckDescription => {
407 let is_description_for_def =
409 if let Some(next) = self.token_stream.peek_nth(1)
410 && let GraphQLTokenKind::Name(name) = &next.kind {
411 matches!(
412 name.as_ref(),
413 "type"
414 | "interface"
415 | "union"
416 | "enum"
417 | "scalar"
418 | "input"
419 | "directive"
420 | "schema"
421 | "extend"
422 )
423 } else {
424 false
425 };
426 if is_description_for_def {
427 break;
428 }
429 self.consume_token();
430 }
431 }
432 }
433 self.delimiter_stack.clear();
435 }
436
437 fn looks_like_definition_start(&mut self, keyword: &str) -> bool {
443 let next = self.token_stream.peek_nth(1);
444
445 match keyword {
446 "type" | "interface" | "union" | "enum" | "scalar" | "input" => {
449 matches!(
450 next.map(|t| &t.kind),
451 Some(
452 GraphQLTokenKind::Name(_)
453 | GraphQLTokenKind::True
454 | GraphQLTokenKind::False
455 | GraphQLTokenKind::Null
456 )
457 )
458 }
459
460 "directive" => {
462 matches!(next.map(|t| &t.kind), Some(GraphQLTokenKind::At))
463 }
464
465 "schema" => {
467 matches!(
468 next.map(|t| &t.kind),
469 Some(GraphQLTokenKind::CurlyBraceOpen | GraphQLTokenKind::At)
470 )
471 }
472
473 "extend" => {
475 if let Some(next_token) = next {
476 if let GraphQLTokenKind::Name(n) = &next_token.kind {
477 matches!(
478 n.as_ref(),
479 "type"
480 | "interface"
481 | "union"
482 | "enum"
483 | "scalar"
484 | "input"
485 | "schema"
486 )
487 } else {
488 false
489 }
490 } else {
491 false
492 }
493 }
494
495 "query" | "mutation" | "subscription" => {
497 matches!(
498 next.map(|t| &t.kind),
499 Some(
500 GraphQLTokenKind::Name(_)
501 | GraphQLTokenKind::True
502 | GraphQLTokenKind::False
503 | GraphQLTokenKind::Null
504 | GraphQLTokenKind::CurlyBraceOpen
505 | GraphQLTokenKind::ParenOpen
506 | GraphQLTokenKind::At
507 )
508 ) || next.is_none() }
510
511 "fragment" => {
513 if let Some(next_token) = next {
514 if let GraphQLTokenKind::Name(n) = &next_token.kind {
515 n.as_ref() != "on"
517 } else {
518 matches!(
519 &next_token.kind,
520 GraphQLTokenKind::True
521 | GraphQLTokenKind::False
522 | GraphQLTokenKind::Null
523 )
524 }
525 } else {
526 false
527 }
528 }
529
530 _ => false,
531 }
532 }
533
534 fn expect(
543 &mut self,
544 expected_kind: &GraphQLTokenKind,
545 ) -> Result<GraphQLToken<'src>, ()> {
546 let mismatch_info = match self.token_stream.peek() {
551 None => {
552 let span = self.eof_span();
553 self.record_error(GraphQLParseError::new(
554 format!(
555 "expected `{}`",
556 Self::token_kind_display(expected_kind),
557 ),
558 GraphQLParseErrorKind::UnexpectedEof {
559 expected: vec![
560 Self::token_kind_display(
561 expected_kind,
562 ),
563 ],
564 },
565 self.resolve_span(span),
566 ));
567 return Err(());
568 },
569 Some(token) => {
570 if Self::token_kinds_match(
571 &token.kind,
572 expected_kind,
573 ) {
574 None
575 } else {
576 Some((
577 token.span,
578 Self::token_kind_display(&token.kind),
579 ))
580 }
581 },
582 };
583 if let Some((span, found)) = mismatch_info {
585 self.record_error(GraphQLParseError::new(
586 format!(
587 "expected `{}`, found `{}`",
588 Self::token_kind_display(expected_kind),
589 found,
590 ),
591 GraphQLParseErrorKind::UnexpectedToken {
592 expected: vec![
593 Self::token_kind_display(expected_kind),
594 ],
595 found,
596 },
597 self.resolve_span(span),
598 ));
599 Err(())
600 } else {
601 Ok(self.consume_token().unwrap())
602 }
603 }
604
605 fn expect_ast_name(&mut self) -> Result<ast::Name<'src>, ()> {
611 let mismatch = match self.token_stream.peek() {
612 None => {
613 let span = self.eof_span();
614 self.record_error(GraphQLParseError::new(
615 "expected name",
616 GraphQLParseErrorKind::UnexpectedEof {
617 expected: vec!["name".to_string()],
618 },
619 self.resolve_span(span),
620 ));
621 return Err(());
622 },
623 Some(token) => match &token.kind {
624 GraphQLTokenKind::Name(_)
625 | GraphQLTokenKind::True
626 | GraphQLTokenKind::False
627 | GraphQLTokenKind::Null => None,
628 _ => Some((token.span, Self::token_kind_display(&token.kind))),
629 },
630 };
631 if let Some((span, found)) = mismatch {
632 self.record_error(GraphQLParseError::new(
633 format!("expected name, found `{found}`"),
634 GraphQLParseErrorKind::UnexpectedToken {
635 expected: vec!["name".to_string()],
636 found,
637 },
638 self.resolve_span(span),
639 ));
640 return Err(());
641 }
642 let token = self.consume_token().unwrap();
643 if self.config.retain_syntax {
644 let value = match &token.kind {
645 GraphQLTokenKind::Name(s) => s.clone(),
646 GraphQLTokenKind::True => Cow::Borrowed("true"),
647 GraphQLTokenKind::False => Cow::Borrowed("false"),
648 GraphQLTokenKind::Null => Cow::Borrowed("null"),
649 _ => unreachable!(),
650 };
651 let span = token.span;
652 Ok(ast::Name {
653 span,
654 syntax: Some(Box::new(ast::NameSyntax { token })),
655 value,
656 })
657 } else {
658 let value = match token.kind {
659 GraphQLTokenKind::Name(s) => s,
660 GraphQLTokenKind::True => Cow::Borrowed("true"),
661 GraphQLTokenKind::False => Cow::Borrowed("false"),
662 GraphQLTokenKind::Null => Cow::Borrowed("null"),
663 _ => unreachable!(),
664 };
665 Ok(ast::Name {
666 span: token.span,
667 syntax: None,
668 value,
669 })
670 }
671 }
672
673 fn expect_keyword(
688 &mut self,
689 keyword: &str,
690 ) -> Result<GraphQLToken<'src>, ()> {
691 let mismatch = match self.token_stream.peek() {
692 None => {
693 let span = self.eof_span();
694 self.record_error(GraphQLParseError::new(
695 format!("expected `{keyword}`"),
696 GraphQLParseErrorKind::UnexpectedEof {
697 expected: vec![keyword.to_string()],
698 },
699 self.resolve_span(span),
700 ));
701 return Err(());
702 },
703 Some(token) => {
704 if let GraphQLTokenKind::Name(name) = &token.kind
705 && name.as_ref() == keyword {
706 None
707 } else {
708 Some((
709 token.span,
710 Self::token_kind_display(
711 &token.kind,
712 ),
713 ))
714 }
715 },
716 };
717 if let Some((span, found)) = mismatch {
718 self.record_error(GraphQLParseError::new(
719 format!(
720 "expected `{keyword}`, found `{found}`"
721 ),
722 GraphQLParseErrorKind::UnexpectedToken {
723 expected: vec![keyword.to_string()],
724 found,
725 },
726 self.resolve_span(span),
727 ));
728 return Err(());
729 }
730 Ok(self.consume_token().unwrap())
731 }
732
733 fn peek_is_keyword(&mut self, keyword: &str) -> bool {
748 match self.token_stream.peek() {
749 Some(token) => {
750 if let GraphQLTokenKind::Name(name) = &token.kind {
751 name.as_ref() == keyword
752 } else {
753 false
754 }
755 }
756 None => false,
757 }
758 }
759
760 fn peek_is(&mut self, kind: &GraphQLTokenKind) -> bool {
762 match self.token_stream.peek() {
763 Some(token) => Self::token_kinds_match(&token.kind, kind),
764 None => false,
765 }
766 }
767
768 fn consume_token(
775 &mut self,
776 ) -> Option<GraphQLToken<'src>> {
777 let token = self.token_stream.consume();
778 if let Some(ref t) = token {
779 self.last_end_position = Some(t.span.end);
780 }
781 token
782 }
783
784 fn eof_span(&self) -> ByteSpan {
787 if let Some(pos) = self.last_end_position {
788 ByteSpan::new(pos, pos)
789 } else {
790 ByteSpan::new(0, 0)
791 }
792 }
793
794 fn make_span(&self, start: ByteSpan) -> ByteSpan {
797 let end = self.last_end_position.unwrap_or(start.start);
798 ByteSpan::new(start.start, end)
799 }
800
801 fn make_span_ref(&self, start: &ByteSpan) -> ByteSpan {
808 let end = self.last_end_position.unwrap_or(start.start);
809 ByteSpan::new(start.start, end)
810 }
811
812 fn token_kind_display(kind: &GraphQLTokenKind) -> String {
814 match kind {
815 GraphQLTokenKind::Ampersand => "&".to_string(),
816 GraphQLTokenKind::At => "@".to_string(),
817 GraphQLTokenKind::Bang => "!".to_string(),
818 GraphQLTokenKind::Colon => ":".to_string(),
819 GraphQLTokenKind::CurlyBraceClose => "}".to_string(),
820 GraphQLTokenKind::CurlyBraceOpen => "{".to_string(),
821 GraphQLTokenKind::Dollar => "$".to_string(),
822 GraphQLTokenKind::Ellipsis => "...".to_string(),
823 GraphQLTokenKind::Equals => "=".to_string(),
824 GraphQLTokenKind::ParenClose => ")".to_string(),
825 GraphQLTokenKind::ParenOpen => "(".to_string(),
826 GraphQLTokenKind::Pipe => "|".to_string(),
827 GraphQLTokenKind::SquareBracketClose => "]".to_string(),
828 GraphQLTokenKind::SquareBracketOpen => "[".to_string(),
829 GraphQLTokenKind::Name(s) => s.to_string(),
830 GraphQLTokenKind::IntValue(s) => s.to_string(),
831 GraphQLTokenKind::FloatValue(s) => s.to_string(),
832 GraphQLTokenKind::StringValue(_) => "string".to_string(),
833 GraphQLTokenKind::True => "true".to_string(),
834 GraphQLTokenKind::False => "false".to_string(),
835 GraphQLTokenKind::Null => "null".to_string(),
836 GraphQLTokenKind::Eof => "end of input".to_string(),
837 GraphQLTokenKind::Error(err) => {
838 format!("tokenization error: {}", err.message)
839 }
840 }
841 }
842
843 fn token_kinds_match(
854 actual: &GraphQLTokenKind,
855 expected: &GraphQLTokenKind,
856 ) -> bool {
857 match actual {
858 GraphQLTokenKind::Name(_) => matches!(expected, GraphQLTokenKind::Name(_)),
862 GraphQLTokenKind::IntValue(_) => {
863 matches!(expected, GraphQLTokenKind::IntValue(_))
864 }
865 GraphQLTokenKind::FloatValue(_) => {
866 matches!(expected, GraphQLTokenKind::FloatValue(_))
867 }
868 GraphQLTokenKind::StringValue(_) => {
869 matches!(expected, GraphQLTokenKind::StringValue(_))
870 }
871 GraphQLTokenKind::Error(_) => {
872 matches!(expected, GraphQLTokenKind::Error(_))
873 }
874 GraphQLTokenKind::Ampersand => actual == expected,
876 GraphQLTokenKind::At => actual == expected,
877 GraphQLTokenKind::Bang => actual == expected,
878 GraphQLTokenKind::Colon => actual == expected,
879 GraphQLTokenKind::CurlyBraceClose => actual == expected,
880 GraphQLTokenKind::CurlyBraceOpen => actual == expected,
881 GraphQLTokenKind::Dollar => actual == expected,
882 GraphQLTokenKind::Ellipsis => actual == expected,
883 GraphQLTokenKind::Equals => actual == expected,
884 GraphQLTokenKind::ParenClose => actual == expected,
885 GraphQLTokenKind::ParenOpen => actual == expected,
886 GraphQLTokenKind::Pipe => actual == expected,
887 GraphQLTokenKind::SquareBracketClose => actual == expected,
888 GraphQLTokenKind::SquareBracketOpen => actual == expected,
889 GraphQLTokenKind::True => actual == expected,
890 GraphQLTokenKind::False => actual == expected,
891 GraphQLTokenKind::Null => actual == expected,
892 GraphQLTokenKind::Eof => actual == expected,
893 }
894 }
895
896 fn handle_lexer_error(&mut self, token: &GraphQLToken<'src>) {
898 if let GraphQLTokenKind::Error(err) = &token.kind {
899 self.record_error(GraphQLParseError::from_lexer_error(
900 err.message.clone(),
901 err.error_notes.clone(),
902 self.resolve_span(token.span),
903 ));
904 }
905 }
906
907 fn enter_recursion(&mut self) -> Result<(), ()> {
916 self.recursion_depth += 1;
917 if self.recursion_depth > Self::MAX_RECURSION_DEPTH {
918 let span = self
919 .token_stream.peek()
920 .map(|t| t.span)
921 .unwrap_or_else(|| self.eof_span());
922 self.consume_token();
923 self.record_error(GraphQLParseError::new(
924 "maximum nesting depth exceeded",
925 GraphQLParseErrorKind::InvalidSyntax,
926 self.resolve_span(span),
927 ));
928 self.recursion_depth -= 1;
929 return Err(());
930 }
931 Ok(())
932 }
933
934 fn exit_recursion(&mut self) {
936 self.recursion_depth -= 1;
937 }
938
939 fn parse_value(
944 &mut self,
945 context: ConstContext,
946 ) -> Result<ast::Value<'src>, ()> {
947 self.enter_recursion()?;
948 let result = self.parse_value_impl(context);
949 self.exit_recursion();
950 result
951 }
952
953 fn parse_value_impl(
955 &mut self, context: ConstContext,
956 ) -> Result<ast::Value<'src>, ()> {
957 match self.token_stream.peek() {
958 None => {
959 let span = self.eof_span();
960 self.record_error(GraphQLParseError::new(
961 "expected value",
962 GraphQLParseErrorKind::UnexpectedEof {
963 expected: vec![
964 "value".to_string(),
965 ],
966 },
967 self.resolve_span(span),
968 ));
969 Err(())
970 },
971 Some(token) => {
972 let span = token.span;
973 match &token.kind {
974 GraphQLTokenKind::Dollar => {
976 if !matches!(context, ConstContext::AllowVariables) {
977 self.consume_token();
978 self.record_error(GraphQLParseError::new(
979 format!("variables are not allowed in {}", context.description()),
980 GraphQLParseErrorKind::InvalidSyntax,
981 self.resolve_span(span),
982 ));
983 return Err(());
984 }
985 let dollar = self.consume_token().unwrap();
986 let name = self.expect_ast_name()?;
987 if self.config.retain_syntax {
988 let var_span = self.make_span_ref(&dollar.span);
989 Ok(ast::Value::Variable(ast::VariableReference {
990 name, span: var_span,
991 syntax: Some(Box::new(ast::VariableReferenceSyntax { dollar })),
992 }))
993 } else {
994 let var_span = self.make_span(dollar.span);
995 Ok(ast::Value::Variable(ast::VariableReference {
996 name, span: var_span, syntax: None,
997 }))
998 }
999 },
1000
1001 GraphQLTokenKind::IntValue(raw) => {
1003 let parse_result =
1004 token.kind.parse_int_value();
1005 match parse_result {
1006 Some(Ok(val)) => {
1007 if val > i32::MAX as i64
1008 || val
1009 < i32::MIN
1010 as i64
1011 {
1012 let raw_str = raw
1013 .clone()
1014 .into_owned();
1015 self.consume_token();
1016 self.record_error(
1017 GraphQLParseError::new(
1018 format!(
1019 "integer \
1020 `{raw_str}` \
1021 overflows \
1022 32-bit \
1023 integer",
1024 ),
1025 GraphQLParseErrorKind::InvalidValue(
1026 ValueParsingError::Int(
1027 raw_str,
1028 ),
1029 ),
1030 self.resolve_span(span),
1031 ),
1032 );
1033 Err(())
1034 } else {
1035 let token = self.consume_token().unwrap();
1036 if self.config.retain_syntax {
1037 let span = token.span;
1038 Ok(ast::Value::Int(ast::IntValue {
1039 span,
1040 syntax: Some(Box::new(ast::IntValueSyntax { token })),
1041 value: val as i32,
1042 }))
1043 } else {
1044 Ok(ast::Value::Int(ast::IntValue {
1045 span: token.span,
1046 syntax: None,
1047 value: val as i32,
1048 }))
1049 }
1050 }
1051 },
1052 Some(Err(_)) => {
1053 let raw_str = raw
1054 .clone()
1055 .into_owned();
1056 self.consume_token();
1057 self.record_error(
1058 GraphQLParseError::new(
1059 format!(
1060 "invalid \
1061 integer \
1062 `{raw_str}`",
1063 ),
1064 GraphQLParseErrorKind::InvalidValue(
1065 ValueParsingError::Int(
1066 raw_str,
1067 ),
1068 ),
1069 self.resolve_span(span),
1070 ),
1071 );
1072 Err(())
1073 },
1074 None => unreachable!(
1075 "parse_int_value on \
1076 IntValue token",
1077 ),
1078 }
1079 },
1080
1081 GraphQLTokenKind::FloatValue(
1083 raw,
1084 ) => {
1085 let parse_result =
1086 token.kind
1087 .parse_float_value();
1088 match parse_result {
1089 Some(Ok(val)) => {
1090 if val.is_infinite()
1091 || val.is_nan()
1092 {
1093 let raw_str = raw
1094 .clone()
1095 .into_owned();
1096 self.consume_token();
1097 self.record_error(
1098 GraphQLParseError::new(
1099 format!(
1100 "float \
1101 `{raw_str}` \
1102 is not a \
1103 finite \
1104 number",
1105 ),
1106 GraphQLParseErrorKind::InvalidValue(
1107 ValueParsingError::Float(
1108 raw_str,
1109 ),
1110 ),
1111 self.resolve_span(span),
1112 ),
1113 );
1114 Err(())
1115 } else {
1116 let token = self.consume_token().unwrap();
1117 if self.config.retain_syntax {
1118 let span = token.span;
1119 Ok(ast::Value::Float(ast::FloatValue {
1120 span,
1121 syntax: Some(Box::new(
1122 ast::FloatValueSyntax { token },
1123 )),
1124 value: val,
1125 }))
1126 } else {
1127 Ok(ast::Value::Float(ast::FloatValue {
1128 span: token.span,
1129 syntax: None,
1130 value: val,
1131 }))
1132 }
1133 }
1134 },
1135 Some(Err(_)) => {
1136 let raw_str = raw
1137 .clone()
1138 .into_owned();
1139 self.consume_token();
1140 self.record_error(
1141 GraphQLParseError::new(
1142 format!(
1143 "invalid \
1144 float \
1145 `{raw_str}`",
1146 ),
1147 GraphQLParseErrorKind::InvalidValue(
1148 ValueParsingError::Float(
1149 raw_str,
1150 ),
1151 ),
1152 self.resolve_span(span),
1153 ),
1154 );
1155 Err(())
1156 },
1157 None => unreachable!(
1158 "parse_float_value \
1159 on FloatValue token",
1160 ),
1161 }
1162 },
1163
1164 GraphQLTokenKind::StringValue(raw) => {
1166 let is_block = raw.starts_with("\"\"\"");
1167 let parse_result = token.kind.parse_string_value();
1168 let consumed = self.consume_token().unwrap();
1169 match parse_result {
1170 Some(Ok(parsed)) => {
1171 if self.config.retain_syntax {
1172 let s = consumed.span;
1173 Ok(ast::Value::String(ast::StringValue {
1174 is_block, span: s,
1175 syntax: Some(Box::new(
1176 ast::StringValueSyntax { token: consumed },
1177 )),
1178 value: Cow::Owned(parsed),
1179 }))
1180 } else {
1181 Ok(ast::Value::String(ast::StringValue {
1182 is_block, span: consumed.span,
1183 syntax: None, value: Cow::Owned(parsed),
1184 }))
1185 }
1186 },
1187 Some(Err(e)) => {
1188 self.record_error(GraphQLParseError::new(
1189 format!("invalid string: {e}"),
1190 GraphQLParseErrorKind::InvalidValue(
1191 ValueParsingError::String(e),
1192 ),
1193 self.resolve_span(span),
1194 ));
1195 Err(())
1196 },
1197 None => {
1198 self.record_error(GraphQLParseError::new(
1199 "invalid string", GraphQLParseErrorKind::InvalidSyntax,
1200 self.resolve_span(span),
1201 ));
1202 Err(())
1203 },
1204 }
1205 },
1206
1207 GraphQLTokenKind::True => {
1209 let token = self.consume_token().unwrap();
1210 if self.config.retain_syntax {
1211 let span = token.span;
1212 Ok(ast::Value::Boolean(ast::BooleanValue {
1213 span,
1214 syntax: Some(Box::new(
1215 ast::BooleanValueSyntax { token },
1216 )),
1217 value: true,
1218 }))
1219 } else {
1220 Ok(ast::Value::Boolean(ast::BooleanValue {
1221 span: token.span, syntax: None, value: true,
1222 }))
1223 }
1224 },
1225 GraphQLTokenKind::False => {
1226 let token = self.consume_token().unwrap();
1227 if self.config.retain_syntax {
1228 let span = token.span;
1229 Ok(ast::Value::Boolean(ast::BooleanValue {
1230 span,
1231 syntax: Some(Box::new(
1232 ast::BooleanValueSyntax { token },
1233 )),
1234 value: false,
1235 }))
1236 } else {
1237 Ok(ast::Value::Boolean(ast::BooleanValue {
1238 span: token.span, syntax: None, value: false,
1239 }))
1240 }
1241 },
1242
1243 GraphQLTokenKind::Null => {
1245 let token = self.consume_token().unwrap();
1246 if self.config.retain_syntax {
1247 let span = token.span;
1248 Ok(ast::Value::Null(ast::NullValue {
1249 span,
1250 syntax: Some(Box::new(ast::NullValueSyntax { token })),
1251 }))
1252 } else {
1253 Ok(ast::Value::Null(ast::NullValue {
1254 span: token.span, syntax: None,
1255 }))
1256 }
1257 },
1258
1259 GraphQLTokenKind::SquareBracketOpen => {
1261 self.parse_list_value(context)
1262 },
1263
1264 GraphQLTokenKind::CurlyBraceOpen => {
1266 self.parse_object_value(context)
1267 },
1268
1269 GraphQLTokenKind::Name(_) => {
1271 let token = self.consume_token().unwrap();
1272 if self.config.retain_syntax {
1273 let value = match &token.kind {
1274 GraphQLTokenKind::Name(s) => s.clone(),
1275 _ => unreachable!(),
1276 };
1277 let span = token.span;
1278 Ok(ast::Value::Enum(ast::EnumValue {
1279 span,
1280 syntax: Some(Box::new(ast::EnumValueSyntax { token })),
1281 value,
1282 }))
1283 } else {
1284 let value = match token.kind {
1285 GraphQLTokenKind::Name(s) => s,
1286 _ => unreachable!(),
1287 };
1288 Ok(ast::Value::Enum(ast::EnumValue {
1289 span: token.span, syntax: None, value,
1290 }))
1291 }
1292 },
1293
1294 GraphQLTokenKind::Error(_) => {
1296 let token = token.clone();
1297 self.handle_lexer_error(
1298 &token,
1299 );
1300 self.consume_token();
1301 Err(())
1302 },
1303
1304 _ => {
1306 let found =
1307 Self::token_kind_display(
1308 &token.kind,
1309 );
1310 self.record_error(
1311 GraphQLParseError::new(
1312 format!(
1313 "expected value, \
1314 found `{found}`",
1315 ),
1316 GraphQLParseErrorKind::UnexpectedToken {
1317 expected: vec![
1318 "value"
1319 .to_string(),
1320 ],
1321 found,
1322 },
1323 self.resolve_span(span),
1324 ),
1325 );
1326 Err(())
1327 },
1328 }
1329 },
1330 }
1331 }
1332
1333 fn parse_list_value(
1335 &mut self, context: ConstContext,
1336 ) -> Result<ast::Value<'src>, ()> {
1337 let open_token = self.expect(&GraphQLTokenKind::SquareBracketOpen)?;
1338 self.push_delimiter(open_token.span, DelimiterContext::ListValue);
1339 let mut values = Vec::new();
1340 loop {
1341 if self.peek_is(&GraphQLTokenKind::SquareBracketClose) {
1342 break;
1343 }
1344 if self.token_stream.is_at_end() {
1345 let span = self.eof_span();
1346 let open_delim = self.pop_delimiter();
1347 let mut error = GraphQLParseError::new(
1348 "unclosed `[`",
1349 GraphQLParseErrorKind::UnclosedDelimiter {
1350 delimiter: "[".to_string(),
1351 },
1352 self.resolve_span(span),
1353 );
1354 if let Some(delim) = open_delim {
1355 error.add_note_with_span("opening `[` here", self.resolve_span(delim.span));
1356 }
1357 self.record_error(error);
1358 return Err(());
1359 }
1360 match self.parse_value(context) {
1361 Ok(value) => values.push(value),
1362 Err(()) => {
1363 self.skip_to_list_recovery_point();
1364 if self.peek_is(&GraphQLTokenKind::SquareBracketClose) {
1365 break;
1366 }
1367 },
1368 }
1369 }
1370 let close_token = self.expect(&GraphQLTokenKind::SquareBracketClose)?;
1371 self.pop_delimiter();
1372 if self.config.retain_syntax {
1373 let span = self.make_span_ref(&open_token.span);
1374 Ok(ast::Value::List(ast::ListValue {
1375 span,
1376 syntax: Some(Box::new(ast::ListValueSyntax {
1377 brackets: ast::DelimiterPair { close: close_token, open: open_token },
1378 })),
1379 values,
1380 }))
1381 } else {
1382 let span = self.make_span(open_token.span);
1383 Ok(ast::Value::List(ast::ListValue { span, syntax: None, values }))
1384 }
1385 }
1386
1387 fn parse_object_value(
1389 &mut self, context: ConstContext,
1390 ) -> Result<ast::Value<'src>, ()> {
1391 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
1392 self.push_delimiter(open_token.span, DelimiterContext::ObjectValue);
1393 let mut fields = Vec::new();
1394 loop {
1395 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
1396 break;
1397 }
1398 if self.token_stream.is_at_end() {
1399 let span = self.eof_span();
1400 let open_delim = self.pop_delimiter();
1401 let mut error = GraphQLParseError::new(
1402 "unclosed `{`",
1403 GraphQLParseErrorKind::UnclosedDelimiter {
1404 delimiter: "{".to_string(),
1405 },
1406 self.resolve_span(span),
1407 );
1408 if let Some(delim) = open_delim {
1409 error.add_note_with_span(
1410 format!("opening `{{` in {} here", delim.context.description()),
1411 self.resolve_span(delim.span),
1412 );
1413 }
1414 self.record_error(error);
1415 return Err(());
1416 }
1417 let field_name = self.expect_ast_name()?;
1418 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
1419 let value = self.parse_value(context)?;
1420 let field_span = ByteSpan::new(
1421 field_name.span.start,
1422 self.last_end_position
1423 .unwrap_or(field_name.span.end),
1424 );
1425 let field_syntax = if self.config.retain_syntax {
1426 Some(Box::new(ast::ObjectFieldSyntax { colon: colon_token }))
1427 } else {
1428 None
1429 };
1430 fields.push(ast::ObjectField {
1431 name: field_name, span: field_span, syntax: field_syntax, value,
1432 });
1433 }
1434 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
1435 self.pop_delimiter();
1436 if self.config.retain_syntax {
1437 let span = self.make_span_ref(&open_token.span);
1438 Ok(ast::Value::Object(ast::ObjectValue {
1439 fields, span,
1440 syntax: Some(Box::new(ast::ObjectValueSyntax {
1441 braces: ast::DelimiterPair { close: close_token, open: open_token },
1442 })),
1443 }))
1444 } else {
1445 let span = self.make_span(open_token.span);
1446 Ok(ast::Value::Object(ast::ObjectValue { fields, span, syntax: None }))
1447 }
1448 }
1449
1450 fn skip_to_list_recovery_point(&mut self) {
1460 loop {
1461 match self.token_stream.peek() {
1462 None => break,
1463 Some(token) => match &token.kind {
1464 GraphQLTokenKind::SquareBracketClose | GraphQLTokenKind::Eof => break,
1466 GraphQLTokenKind::Dollar
1468 | GraphQLTokenKind::IntValue(_)
1469 | GraphQLTokenKind::FloatValue(_)
1470 | GraphQLTokenKind::StringValue(_)
1471 | GraphQLTokenKind::True
1472 | GraphQLTokenKind::False
1473 | GraphQLTokenKind::Null
1474 | GraphQLTokenKind::SquareBracketOpen
1475 | GraphQLTokenKind::CurlyBraceOpen
1476 | GraphQLTokenKind::Name(_) => break,
1477 GraphQLTokenKind::Ampersand
1479 | GraphQLTokenKind::At
1480 | GraphQLTokenKind::Bang
1481 | GraphQLTokenKind::Colon
1482 | GraphQLTokenKind::CurlyBraceClose
1483 | GraphQLTokenKind::Ellipsis
1484 | GraphQLTokenKind::Equals
1485 | GraphQLTokenKind::ParenClose
1486 | GraphQLTokenKind::ParenOpen
1487 | GraphQLTokenKind::Pipe
1488 | GraphQLTokenKind::Error(_) => {
1489 self.consume_token();
1490 }
1491 },
1492 }
1493 }
1494 }
1495
1496 fn parse_type_annotation(&mut self) -> Result<ast::TypeAnnotation<'src>, ()> {
1502 self.enter_recursion()?;
1503 let result = self.parse_type_annotation_impl();
1504 self.exit_recursion();
1505 result
1506 }
1507
1508 fn parse_type_annotation_impl(&mut self) -> Result<ast::TypeAnnotation<'src>, ()> {
1510 if self.peek_is(&GraphQLTokenKind::SquareBracketOpen) {
1511 self.parse_list_type_annotation()
1512 } else {
1513 self.parse_named_type_annotation()
1514 }
1515 }
1516
1517 fn parse_named_type_annotation(&mut self) -> Result<ast::TypeAnnotation<'src>, ()> {
1519 let name = self.expect_ast_name()?;
1520 let (nullability, span_end) = if self.peek_is(&GraphQLTokenKind::Bang) {
1521 let bang = self.consume_token().unwrap();
1522 let end = bang.span.end;
1523 let syntax = if self.config.retain_syntax { Some(bang) } else { None };
1524 (ast::Nullability::NonNull { syntax }, end)
1525 } else {
1526 (ast::Nullability::Nullable, name.span.end)
1527 };
1528 let span = ByteSpan::new(name.span.start, span_end);
1529 Ok(ast::TypeAnnotation::Named(
1530 ast::NamedTypeAnnotation { name, nullability, span },
1531 ))
1532 }
1533
1534 fn parse_list_type_annotation(&mut self) -> Result<ast::TypeAnnotation<'src>, ()> {
1536 let open_token = self.expect(&GraphQLTokenKind::SquareBracketOpen)?;
1537 self.push_delimiter(open_token.span, DelimiterContext::ListType);
1538 let element_type = Box::new(self.parse_type_annotation()?);
1539 let close_token = self.expect(&GraphQLTokenKind::SquareBracketClose)?;
1540 self.pop_delimiter();
1541 let (nullability, span_end) = if self.peek_is(&GraphQLTokenKind::Bang) {
1542 let bang = self.consume_token().unwrap();
1543 let end = bang.span.end;
1544 let syntax = if self.config.retain_syntax { Some(bang) } else { None };
1545 (ast::Nullability::NonNull { syntax }, end)
1546 } else {
1547 let end = self.last_end_position
1548 .unwrap_or(open_token.span.start);
1549 (ast::Nullability::Nullable, end)
1550 };
1551 if self.config.retain_syntax {
1552 let span = ByteSpan::new(
1553 open_token.span.start, span_end,
1554 );
1555 Ok(ast::TypeAnnotation::List(ast::ListTypeAnnotation {
1556 element_type, nullability, span,
1557 syntax: Some(Box::new(ast::ListTypeAnnotationSyntax {
1558 brackets: ast::DelimiterPair { close: close_token, open: open_token },
1559 })),
1560 }))
1561 } else {
1562 let span = ByteSpan::new(open_token.span.start, span_end);
1563 Ok(ast::TypeAnnotation::List(
1564 ast::ListTypeAnnotation { element_type, nullability, span, syntax: None },
1565 ))
1566 }
1567 }
1568
1569 fn parse_directive_annotations(
1575 &mut self,
1576 ) -> Result<Vec<ast::DirectiveAnnotation<'src>>, ()> {
1577 let mut directives = Vec::new();
1578 while self.peek_is(&GraphQLTokenKind::At) {
1579 directives.push(self.parse_directive_annotation()?);
1580 }
1581 Ok(directives)
1582 }
1583
1584 fn parse_directive_annotation(&mut self) -> Result<ast::DirectiveAnnotation<'src>, ()> {
1586 let at_token = self.expect(&GraphQLTokenKind::At)?;
1587 let name = self.expect_ast_name()?;
1588 let (arguments, argument_delimiters) = if self.peek_is(&GraphQLTokenKind::ParenOpen) {
1589 self.parse_ast_arguments(
1590 DelimiterContext::DirectiveArguments,
1591 ConstContext::AllowVariables,
1592 )?
1593 } else {
1594 (Vec::new(), None)
1595 };
1596 if self.config.retain_syntax {
1597 let span = self.make_span_ref(&at_token.span);
1598 Ok(ast::DirectiveAnnotation {
1599 arguments, name, span,
1600 syntax: Some(Box::new(ast::DirectiveAnnotationSyntax {
1601 argument_parens: argument_delimiters, at_sign: at_token,
1602 })),
1603 })
1604 } else {
1605 let span = self.make_span(at_token.span);
1606 Ok(ast::DirectiveAnnotation { arguments, name, span, syntax: None })
1607 }
1608 }
1609
1610 fn parse_const_directive_annotations(
1612 &mut self,
1613 ) -> Result<Vec<ast::DirectiveAnnotation<'src>>, ()> {
1614 let mut directives = Vec::new();
1615 while self.peek_is(&GraphQLTokenKind::At) {
1616 directives.push(self.parse_const_directive_annotation()?);
1617 }
1618 Ok(directives)
1619 }
1620
1621 fn parse_const_directive_annotation(&mut self) -> Result<ast::DirectiveAnnotation<'src>, ()> {
1623 let at_token = self.expect(&GraphQLTokenKind::At)?;
1624 let name = self.expect_ast_name()?;
1625 let (arguments, argument_delimiters) = if self.peek_is(&GraphQLTokenKind::ParenOpen) {
1626 self.parse_ast_arguments(
1627 DelimiterContext::DirectiveArguments,
1628 ConstContext::DirectiveArgument,
1629 )?
1630 } else {
1631 (Vec::new(), None)
1632 };
1633 if self.config.retain_syntax {
1634 let span = self.make_span_ref(&at_token.span);
1635 Ok(ast::DirectiveAnnotation {
1636 arguments, name, span,
1637 syntax: Some(Box::new(ast::DirectiveAnnotationSyntax {
1638 argument_parens: argument_delimiters, at_sign: at_token,
1639 })),
1640 })
1641 } else {
1642 let span = self.make_span(at_token.span);
1643 Ok(ast::DirectiveAnnotation { arguments, name, span, syntax: None })
1644 }
1645 }
1646
1647 fn parse_ast_arguments(
1653 &mut self, delim_context: DelimiterContext, const_context: ConstContext,
1654 ) -> Result<(Vec<ast::Argument<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
1655 let open_token = self.expect(&GraphQLTokenKind::ParenOpen)?;
1656 self.push_delimiter(open_token.span, delim_context);
1657 let mut arguments = Vec::new();
1658 if self.peek_is(&GraphQLTokenKind::ParenClose) {
1659 let span = open_token.span;
1660 self.record_error(GraphQLParseError::new(
1661 "argument list cannot be empty; omit the parentheses instead",
1662 GraphQLParseErrorKind::InvalidEmptyConstruct {
1663 construct: "argument list".to_string(),
1664 },
1665 self.resolve_span(span),
1666 ));
1667 }
1668 loop {
1669 if self.peek_is(&GraphQLTokenKind::ParenClose) {
1670 break;
1671 }
1672 if self.token_stream.is_at_end() {
1673 self.handle_unclosed_paren();
1674 return Err(());
1675 }
1676 let arg_name = self.expect_ast_name()?;
1677 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
1678 let value = self.parse_value(const_context)?;
1679 let span = ByteSpan::new(
1680 arg_name.span.start,
1681 self.last_end_position
1682 .unwrap_or(arg_name.span.end),
1683 );
1684 let syntax = if self.config.retain_syntax {
1685 Some(Box::new(ast::ArgumentSyntax { colon: colon_token }))
1686 } else {
1687 None
1688 };
1689 arguments.push(ast::Argument {
1690 name: arg_name, span, syntax, value,
1691 });
1692 }
1693 let close_token = self.expect(&GraphQLTokenKind::ParenClose)?;
1694 self.pop_delimiter();
1695 let delimiters = if self.config.retain_syntax {
1696 Some(ast::DelimiterPair { close: close_token, open: open_token })
1697 } else {
1698 None
1699 };
1700 Ok((arguments, delimiters))
1701 }
1702
1703 fn handle_unclosed_paren(&mut self) {
1705 let span = self.eof_span();
1706 let open_delim = self.pop_delimiter();
1707 let mut error = GraphQLParseError::new(
1708 "unclosed `(`",
1709 GraphQLParseErrorKind::UnclosedDelimiter {
1710 delimiter: "(".to_string(),
1711 },
1712 self.resolve_span(span),
1713 );
1714 if let Some(delim) = open_delim {
1715 error.add_note_with_span(
1716 format!("opening `(` in {} here", delim.context.description()),
1717 self.resolve_span(delim.span),
1718 );
1719 }
1720 self.record_error(error);
1721 }
1722
1723 fn parse_selection_set(&mut self) -> Result<ast::SelectionSet<'src>, ()> {
1729 self.enter_recursion()?;
1730 let result = self.parse_selection_set_impl();
1731 self.exit_recursion();
1732 result
1733 }
1734
1735 fn parse_selection_set_impl(&mut self) -> Result<ast::SelectionSet<'src>, ()> {
1737 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
1738 self.push_delimiter(open_token.span, DelimiterContext::SelectionSet);
1739 let mut selections = Vec::new();
1740 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
1741 let span = open_token.span;
1742 self.record_error(GraphQLParseError::new(
1743 "selection set cannot be empty",
1744 GraphQLParseErrorKind::InvalidEmptyConstruct {
1745 construct: "selection set".to_string(),
1746 },
1747 self.resolve_span(span),
1748 ));
1749 }
1750 loop {
1751 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
1752 break;
1753 }
1754 if self.token_stream.is_at_end() {
1755 self.handle_unclosed_brace();
1756 return Err(());
1757 }
1758 match self.parse_selection() {
1759 Ok(sel) => selections.push(sel),
1760 Err(()) => {
1761 self.skip_to_selection_recovery_point();
1762 },
1763 }
1764 }
1765 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
1766 self.pop_delimiter();
1767 if self.config.retain_syntax {
1768 let span = self.make_span_ref(&open_token.span);
1769 Ok(ast::SelectionSet {
1770 selections, span,
1771 syntax: Some(Box::new(ast::SelectionSetSyntax {
1772 braces: ast::DelimiterPair { close: close_token, open: open_token },
1773 })),
1774 })
1775 } else {
1776 let span = self.make_span(open_token.span);
1777 Ok(ast::SelectionSet { selections, span, syntax: None })
1778 }
1779 }
1780
1781 fn parse_selection(&mut self) -> Result<ast::Selection<'src>, ()> {
1783 if self.peek_is(&GraphQLTokenKind::Ellipsis) {
1784 let ellipsis_token = self.expect(&GraphQLTokenKind::Ellipsis)?;
1785 if self.peek_is_keyword("on")
1786 || self.peek_is(&GraphQLTokenKind::At)
1787 || self.peek_is(&GraphQLTokenKind::CurlyBraceOpen)
1788 {
1789 self.parse_inline_fragment(ellipsis_token)
1790 } else {
1791 self.parse_fragment_spread(ellipsis_token)
1792 }
1793 } else {
1794 self.parse_field().map(ast::Selection::Field)
1795 }
1796 }
1797
1798 fn parse_field(&mut self) -> Result<ast::FieldSelection<'src>, ()> {
1800 let first_name = self.expect_ast_name()?;
1801 let (alias, alias_colon, name) = if self.peek_is(&GraphQLTokenKind::Colon) {
1802 let colon_token = self.consume_token().unwrap();
1803 let field_name = self.expect_ast_name()?;
1804 (Some(first_name), Some(colon_token), field_name)
1805 } else {
1806 (None, None, first_name)
1807 };
1808 let (arguments, argument_delimiters) = if self.peek_is(&GraphQLTokenKind::ParenOpen) {
1809 self.parse_ast_arguments(
1810 DelimiterContext::FieldArguments,
1811 ConstContext::AllowVariables,
1812 )?
1813 } else {
1814 (Vec::new(), None)
1815 };
1816 let directives = self.parse_directive_annotations()?;
1817 let selection_set = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
1818 Some(self.parse_selection_set()?)
1819 } else {
1820 None
1821 };
1822 let start = match &alias {
1823 Some(a) => a.span.start,
1824 None => name.span.start,
1825 };
1826 let end = self.last_end_position
1827 .unwrap_or(name.span.end);
1828 let span = ByteSpan::new(start, end);
1829 let syntax = if self.config.retain_syntax {
1830 Some(Box::new(ast::FieldSelectionSyntax {
1831 alias_colon,
1832 argument_parens: argument_delimiters,
1833 }))
1834 } else {
1835 None
1836 };
1837 Ok(ast::FieldSelection { alias, arguments, directives, name, selection_set, span, syntax })
1838 }
1839
1840 fn parse_fragment_spread(
1842 &mut self, ellipsis_token: GraphQLToken<'src>,
1843 ) -> Result<ast::Selection<'src>, ()> {
1844 let name = self.expect_ast_name()?;
1845 let directives = self.parse_directive_annotations()?;
1846 if self.config.retain_syntax {
1847 let span = self.make_span_ref(&ellipsis_token.span);
1848 Ok(ast::Selection::FragmentSpread(ast::FragmentSpread {
1849 directives, name, span,
1850 syntax: Some(Box::new(ast::FragmentSpreadSyntax {
1851 ellipsis: ellipsis_token,
1852 })),
1853 }))
1854 } else {
1855 let span = self.make_span(ellipsis_token.span);
1856 Ok(ast::Selection::FragmentSpread(
1857 ast::FragmentSpread { directives, name, span, syntax: None },
1858 ))
1859 }
1860 }
1861
1862 fn parse_inline_fragment(
1865 &mut self, ellipsis_token: GraphQLToken<'src>,
1866 ) -> Result<ast::Selection<'src>, ()> {
1867 let type_condition = if self.peek_is_keyword("on") {
1868 Some(self.parse_type_condition()?)
1869 } else {
1870 None
1871 };
1872 let directives = self.parse_directive_annotations()?;
1873 let selection_set = self.parse_selection_set()?;
1874 if self.config.retain_syntax {
1875 let span = self.make_span_ref(&ellipsis_token.span);
1876 Ok(ast::Selection::InlineFragment(ast::InlineFragment {
1877 directives, selection_set, span,
1878 syntax: Some(Box::new(ast::InlineFragmentSyntax {
1879 ellipsis: ellipsis_token,
1880 })),
1881 type_condition,
1882 }))
1883 } else {
1884 let span = self.make_span(ellipsis_token.span);
1885 Ok(ast::Selection::InlineFragment(ast::InlineFragment {
1886 directives, selection_set, span, syntax: None, type_condition,
1887 }))
1888 }
1889 }
1890
1891 fn skip_to_selection_recovery_point(&mut self) {
1893 loop {
1894 match self.token_stream.peek() {
1895 None => break,
1896 Some(token) => match &token.kind {
1897 GraphQLTokenKind::CurlyBraceClose | GraphQLTokenKind::Eof => break,
1898 GraphQLTokenKind::Ellipsis | GraphQLTokenKind::Name(_) => break,
1900 GraphQLTokenKind::True
1902 | GraphQLTokenKind::False
1903 | GraphQLTokenKind::Null => break,
1904 _ => {
1905 self.consume_token();
1906 }
1907 },
1908 }
1909 }
1910 }
1911
1912 fn handle_unclosed_brace(&mut self) {
1914 let span = self.eof_span();
1915 let open_delim = self.pop_delimiter();
1916 let mut error = GraphQLParseError::new(
1917 "unclosed `{`",
1918 GraphQLParseErrorKind::UnclosedDelimiter {
1919 delimiter: "{".to_string(),
1920 },
1921 self.resolve_span(span),
1922 );
1923 if let Some(delim) = open_delim {
1924 error.add_note_with_span(
1925 format!(
1926 "opening `{{` in {} here",
1927 delim.context.description()
1928 ),
1929 self.resolve_span(delim.span),
1930 );
1931 }
1932 self.record_error(error);
1933 }
1934
1935 fn parse_operation_definition(&mut self) -> Result<ast::OperationDefinition<'src>, ()> {
1941 if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
1943 let selection_set = self.parse_selection_set()?;
1944 let span = selection_set.span;
1945 return Ok(ast::OperationDefinition {
1946 description: None, directives: Vec::new(), name: None,
1947 operation_kind: ast::OperationKind::Query, selection_set,
1948 shorthand: true, span, syntax: None,
1949 variable_definitions: Vec::new(),
1950 });
1951 }
1952
1953 let (op_kind, keyword_token) = if self.peek_is_keyword("query") {
1955 (ast::OperationKind::Query, self.expect_keyword("query")?)
1956 } else if self.peek_is_keyword("mutation") {
1957 (ast::OperationKind::Mutation, self.expect_keyword("mutation")?)
1958 } else if self.peek_is_keyword("subscription") {
1959 (ast::OperationKind::Subscription, self.expect_keyword("subscription")?)
1960 } else {
1961 let span = self
1962 .token_stream.peek()
1963 .map(|t| t.span)
1964 .unwrap_or_else(|| self.eof_span());
1965 let found = self
1966 .token_stream.peek()
1967 .map(|t| Self::token_kind_display(&t.kind))
1968 .unwrap_or_else(|| "end of input".to_string());
1969 self.record_error(GraphQLParseError::new(
1970 format!(
1971 "expected operation type (`query`, `mutation`, or \
1972 `subscription`), found `{found}`"
1973 ),
1974 GraphQLParseErrorKind::UnexpectedToken {
1975 expected: vec![
1976 "query".to_string(),
1977 "mutation".to_string(),
1978 "subscription".to_string(),
1979 ],
1980 found,
1981 },
1982 self.resolve_span(span),
1983 ));
1984 return Err(());
1985 };
1986
1987 let name = if !self.peek_is(&GraphQLTokenKind::ParenOpen)
1989 && !self.peek_is(&GraphQLTokenKind::At)
1990 && !self.peek_is(&GraphQLTokenKind::CurlyBraceOpen)
1991 {
1992 if let Some(token) = self.token_stream.peek() {
1993 match &token.kind {
1994 GraphQLTokenKind::Name(_) | GraphQLTokenKind::True
1995 | GraphQLTokenKind::False | GraphQLTokenKind::Null => {
1996 Some(self.expect_ast_name()?)
1997 },
1998 _ => None,
1999 }
2000 } else {
2001 None
2002 }
2003 } else {
2004 None
2005 };
2006
2007 let (variable_definitions, variable_definition_delimiters) =
2009 if self.peek_is(&GraphQLTokenKind::ParenOpen) {
2010 self.parse_variable_definitions()?
2011 } else {
2012 (Vec::new(), None)
2013 };
2014
2015 let directives = self.parse_directive_annotations()?;
2017 let selection_set = self.parse_selection_set()?;
2018 if self.config.retain_syntax {
2019 let span = self.make_span_ref(&keyword_token.span);
2020 Ok(ast::OperationDefinition {
2021 description: None, directives, name, operation_kind: op_kind,
2022 selection_set, shorthand: false, span,
2023 syntax: Some(Box::new(ast::OperationDefinitionSyntax {
2024 operation_keyword: Some(keyword_token),
2025 variable_definition_parens: variable_definition_delimiters,
2026 })),
2027 variable_definitions,
2028 })
2029 } else {
2030 let span = self.make_span(keyword_token.span);
2031 Ok(ast::OperationDefinition {
2032 description: None, directives, name, operation_kind: op_kind,
2033 selection_set, shorthand: false, span, syntax: None,
2034 variable_definitions,
2035 })
2036 }
2037 }
2038
2039 fn parse_variable_definitions(
2041 &mut self,
2042 ) -> Result<(Vec<ast::VariableDefinition<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
2043 let open_token = self.expect(&GraphQLTokenKind::ParenOpen)?;
2044 self.push_delimiter(
2045 open_token.span,
2046 DelimiterContext::VariableDefinitions,
2047 );
2048
2049 let mut definitions = Vec::new();
2050
2051 if self.peek_is(&GraphQLTokenKind::ParenClose) {
2052 let span = open_token.span;
2053 self.record_error(GraphQLParseError::new(
2054 "variable definitions cannot be empty; omit the parentheses \
2055 instead",
2056 GraphQLParseErrorKind::InvalidEmptyConstruct {
2057 construct: "variable definitions".to_string(),
2058 },
2059 self.resolve_span(span),
2060 ));
2061 }
2062
2063 loop {
2064 if self.peek_is(&GraphQLTokenKind::ParenClose) {
2065 break;
2066 }
2067 if self.token_stream.is_at_end() {
2068 self.handle_unclosed_paren();
2069 return Err(());
2070 }
2071
2072 definitions.push(self.parse_variable_definition()?);
2073 }
2074
2075 let close_token = self.expect(&GraphQLTokenKind::ParenClose)?;
2076 self.pop_delimiter();
2077 let delimiters = if self.config.retain_syntax {
2078 Some(ast::DelimiterPair { close: close_token, open: open_token })
2079 } else {
2080 None
2081 };
2082 Ok((definitions, delimiters))
2083 }
2084
2085 fn parse_variable_definition(&mut self) -> Result<ast::VariableDefinition<'src>, ()> {
2087 let dollar_token = self.expect(&GraphQLTokenKind::Dollar)?;
2088 let variable = self.expect_ast_name()?;
2089 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
2090 let var_type = self.parse_type_annotation()?;
2091 let (default_value, equals_token) = if self.peek_is(&GraphQLTokenKind::Equals) {
2092 let eq = self.consume_token().unwrap();
2093 (Some(self.parse_value(ConstContext::VariableDefaultValue)?), Some(eq))
2094 } else {
2095 (None, None)
2096 };
2097 let directives = self.parse_const_directive_annotations()?;
2098 if self.config.retain_syntax {
2099 let span = self.make_span_ref(&dollar_token.span);
2100 Ok(ast::VariableDefinition {
2101 default_value, description: None, directives, span,
2102 syntax: Some(Box::new(ast::VariableDefinitionSyntax {
2103 colon: colon_token, dollar: dollar_token, equals: equals_token,
2104 })),
2105 var_type, variable,
2106 })
2107 } else {
2108 let span = self.make_span(dollar_token.span);
2109 Ok(ast::VariableDefinition {
2110 default_value, description: None, directives, span,
2111 syntax: None, var_type, variable,
2112 })
2113 }
2114 }
2115
2116 fn parse_fragment_definition(&mut self) -> Result<ast::FragmentDefinition<'src>, ()> {
2122 let keyword_token = self.expect_keyword("fragment")?;
2123 let name = self.expect_ast_name()?;
2124 if name.value == "on" {
2125 let mut error = GraphQLParseError::new(
2126 "fragment name cannot be `on`",
2127 GraphQLParseErrorKind::ReservedName {
2128 name: "on".to_string(), context: ReservedNameContext::FragmentName,
2129 },
2130 self.resolve_span(name.span),
2131 );
2132 error.add_spec(
2133 "https://spec.graphql.org/October2021/#sec-Fragment-Name-Uniqueness",
2134 );
2135 self.record_error(error);
2136 }
2137 let type_condition = self.parse_type_condition()?;
2138 let directives = self.parse_directive_annotations()?;
2139 let selection_set = self.parse_selection_set()?;
2140 if self.config.retain_syntax {
2141 let span = self.make_span_ref(&keyword_token.span);
2142 Ok(ast::FragmentDefinition {
2143 description: None, directives, name, selection_set, span,
2144 syntax: Some(Box::new(ast::FragmentDefinitionSyntax {
2145 fragment_keyword: keyword_token,
2146 })),
2147 type_condition,
2148 })
2149 } else {
2150 let span = self.make_span(keyword_token.span);
2151 Ok(ast::FragmentDefinition {
2152 description: None, directives, name, selection_set, span,
2153 syntax: None, type_condition,
2154 })
2155 }
2156 }
2157
2158 fn parse_type_condition(&mut self) -> Result<ast::TypeCondition<'src>, ()> {
2160 let on_token = self.expect_keyword("on")?;
2161 let named_type = self.expect_ast_name()?;
2162 if self.config.retain_syntax {
2163 let span = ByteSpan::new(
2164 on_token.span.start,
2165 named_type.span.end,
2166 );
2167 Ok(ast::TypeCondition {
2168 named_type, span,
2169 syntax: Some(Box::new(ast::TypeConditionSyntax {
2170 on_keyword: on_token,
2171 })),
2172 })
2173 } else {
2174 let span = ByteSpan::new(
2175 on_token.span.start, named_type.span.end,
2176 );
2177 Ok(ast::TypeCondition { named_type, span, syntax: None })
2178 }
2179 }
2180
2181 fn parse_ast_description(&mut self) -> Option<ast::StringValue<'src>> {
2189 if let Some(token) = self.token_stream.peek()
2190 && matches!(&token.kind, GraphQLTokenKind::StringValue(_)) {
2191 let is_block = match &token.kind {
2192 GraphQLTokenKind::StringValue(raw) => {
2193 raw.starts_with("\"\"\"")
2194 },
2195 _ => false,
2196 };
2197 let token = self.consume_token().unwrap();
2198 match token.kind.parse_string_value() {
2199 Some(Ok(parsed)) => {
2200 if self.config.retain_syntax {
2201 let span = token.span;
2202 return Some(ast::StringValue {
2203 is_block,
2204 span,
2205 syntax: Some(Box::new(
2206 ast::StringValueSyntax { token },
2207 )),
2208 value: Cow::Owned(parsed),
2209 });
2210 } else {
2211 return Some(ast::StringValue {
2212 is_block,
2213 span: token.span,
2214 syntax: None,
2215 value: Cow::Owned(parsed),
2216 });
2217 }
2218 },
2219 Some(Err(err)) => {
2220 self.record_error(GraphQLParseError::new(
2221 format!("invalid string in description: {err}"),
2222 GraphQLParseErrorKind::InvalidSyntax,
2223 self.resolve_span(token.span),
2224 ));
2225 },
2226 None => unreachable!(),
2227 }
2228 }
2229 None
2230 }
2231
2232 fn parse_schema_definition(
2234 &mut self,
2235 description: Option<ast::StringValue<'src>>,
2236 ) -> Result<ast::SchemaDefinition<'src>, ()> {
2237 let keyword_token = self.expect_keyword("schema")?;
2238 let directives = self.parse_const_directive_annotations()?;
2239 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
2240 self.push_delimiter(open_token.span, DelimiterContext::SchemaDefinition);
2241 let mut root_operations = Vec::new();
2242 loop {
2243 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
2244 break;
2245 }
2246 if self.token_stream.is_at_end() {
2247 self.handle_unclosed_brace();
2248 return Err(());
2249 }
2250 let op_name = self.expect_ast_name()?;
2251 let op_kind = match &*op_name.value {
2252 "query" => ast::OperationKind::Query,
2253 "mutation" => ast::OperationKind::Mutation,
2254 "subscription" => ast::OperationKind::Subscription,
2255 _ => {
2256 self.record_error(GraphQLParseError::new(
2257 format!(
2258 "unknown operation type `{}`; expected `query`, `mutation`, \
2259 or `subscription`",
2260 op_name.value,
2261 ),
2262 GraphQLParseErrorKind::InvalidSyntax,
2263 self.resolve_span(op_name.span),
2264 ));
2265 continue;
2266 },
2267 };
2268 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
2269 let named_type = self.expect_ast_name()?;
2270 let root_span = ByteSpan::new(
2271 op_name.span.start,
2272 named_type.span.end,
2273 );
2274 let root_syntax = if self.config.retain_syntax {
2275 Some(Box::new(ast::RootOperationTypeDefinitionSyntax {
2276 colon: colon_token,
2277 }))
2278 } else {
2279 None
2280 };
2281 root_operations.push(ast::RootOperationTypeDefinition {
2282 named_type, operation_kind: op_kind, span: root_span, syntax: root_syntax,
2283 });
2284 }
2285 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
2286 self.pop_delimiter();
2287 if self.config.retain_syntax {
2288 let span = self.make_span_ref(&keyword_token.span);
2289 Ok(ast::SchemaDefinition {
2290 description, directives, root_operations, span,
2291 syntax: Some(Box::new(ast::SchemaDefinitionSyntax {
2292 braces: ast::DelimiterPair { close: close_token, open: open_token },
2293 schema_keyword: keyword_token,
2294 })),
2295 })
2296 } else {
2297 let span = self.make_span(keyword_token.span);
2298 Ok(ast::SchemaDefinition {
2299 description, directives, root_operations, span, syntax: None,
2300 })
2301 }
2302 }
2303
2304 fn parse_scalar_type_definition(
2306 &mut self,
2307 description: Option<ast::StringValue<'src>>,
2308 ) -> Result<ast::TypeDefinition<'src>, ()> {
2309 let keyword_token = self.expect_keyword("scalar")?;
2310 let name = self.expect_ast_name()?;
2311 let directives = self.parse_const_directive_annotations()?;
2312 if self.config.retain_syntax {
2313 let span = self.make_span_ref(&keyword_token.span);
2314 Ok(ast::TypeDefinition::Scalar(ast::ScalarTypeDefinition {
2315 description, directives, name, span,
2316 syntax: Some(Box::new(ast::ScalarTypeDefinitionSyntax {
2317 scalar_keyword: keyword_token,
2318 })),
2319 }))
2320 } else {
2321 let span = self.make_span(keyword_token.span);
2322 Ok(ast::TypeDefinition::Scalar(ast::ScalarTypeDefinition {
2323 description, directives, name, span, syntax: None,
2324 }))
2325 }
2326 }
2327
2328 fn parse_object_type_definition(
2331 &mut self,
2332 description: Option<ast::StringValue<'src>>,
2333 ) -> Result<ast::TypeDefinition<'src>, ()> {
2334 let keyword_token = self.expect_keyword("type")?;
2335 let name = self.expect_ast_name()?;
2336 let (implements_tokens, implements) = if self.peek_is_keyword("implements") {
2337 let clause = self.parse_ast_implements_interfaces()?;
2338 (Some(ImplementsClauseTokens {
2339 ampersands: clause.ampersands,
2340 implements_keyword: clause.implements_keyword,
2341 leading_ampersand: clause.leading_ampersand,
2342 }), clause.interfaces)
2343 } else {
2344 (None, Vec::new())
2345 };
2346 let directives = self.parse_const_directive_annotations()?;
2347 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
2348 self.parse_ast_fields_definition(DelimiterContext::ObjectTypeDefinition)?
2349 } else {
2350 (Vec::new(), None)
2351 };
2352 if self.config.retain_syntax {
2353 let span = self.make_span_ref(&keyword_token.span);
2354 let (impl_kw, leading_amp, amps) = match implements_tokens {
2355 Some(c) => (Some(c.implements_keyword), c.leading_ampersand, c.ampersands),
2356 None => (None, None, Vec::new()),
2357 };
2358 Ok(ast::TypeDefinition::Object(ast::ObjectTypeDefinition {
2359 description, directives, fields, implements, name, span,
2360 syntax: Some(Box::new(ast::ObjectTypeDefinitionSyntax {
2361 ampersands: amps, braces: field_delimiters,
2362 implements_keyword: impl_kw, leading_ampersand: leading_amp,
2363 type_keyword: keyword_token,
2364 })),
2365 }))
2366 } else {
2367 let span = self.make_span(keyword_token.span);
2368 Ok(ast::TypeDefinition::Object(ast::ObjectTypeDefinition {
2369 description, directives, fields, implements, name, span, syntax: None,
2370 }))
2371 }
2372 }
2373
2374 fn parse_interface_type_definition(
2376 &mut self,
2377 description: Option<ast::StringValue<'src>>,
2378 ) -> Result<ast::TypeDefinition<'src>, ()> {
2379 let keyword_token = self.expect_keyword("interface")?;
2380 let name = self.expect_ast_name()?;
2381 let (implements_tokens, implements) = if self.peek_is_keyword("implements") {
2382 let clause = self.parse_ast_implements_interfaces()?;
2383 (Some(ImplementsClauseTokens {
2384 ampersands: clause.ampersands,
2385 implements_keyword: clause.implements_keyword,
2386 leading_ampersand: clause.leading_ampersand,
2387 }), clause.interfaces)
2388 } else {
2389 (None, Vec::new())
2390 };
2391 let directives = self.parse_const_directive_annotations()?;
2392 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
2393 self.parse_ast_fields_definition(DelimiterContext::InterfaceDefinition)?
2394 } else {
2395 (Vec::new(), None)
2396 };
2397 if self.config.retain_syntax {
2398 let span = self.make_span_ref(&keyword_token.span);
2399 let (impl_kw, leading_amp, amps) = match implements_tokens {
2400 Some(c) => (Some(c.implements_keyword), c.leading_ampersand, c.ampersands),
2401 None => (None, None, Vec::new()),
2402 };
2403 Ok(ast::TypeDefinition::Interface(ast::InterfaceTypeDefinition {
2404 description, directives, fields, implements, name, span,
2405 syntax: Some(Box::new(ast::InterfaceTypeDefinitionSyntax {
2406 ampersands: amps, braces: field_delimiters,
2407 implements_keyword: impl_kw, interface_keyword: keyword_token,
2408 leading_ampersand: leading_amp,
2409 })),
2410 }))
2411 } else {
2412 let span = self.make_span(keyword_token.span);
2413 Ok(ast::TypeDefinition::Interface(ast::InterfaceTypeDefinition {
2414 description, directives, fields, implements, name, span, syntax: None,
2415 }))
2416 }
2417 }
2418
2419 fn parse_union_type_definition(
2421 &mut self,
2422 description: Option<ast::StringValue<'src>>,
2423 ) -> Result<ast::TypeDefinition<'src>, ()> {
2424 let keyword_token = self.expect_keyword("union")?;
2425 let name = self.expect_ast_name()?;
2426 let directives = self.parse_const_directive_annotations()?;
2427 let mut members = Vec::new();
2428 let mut equals_token = None;
2429 let mut leading_pipe = None;
2430 let mut pipes = Vec::new();
2431 if self.peek_is(&GraphQLTokenKind::Equals) {
2432 equals_token = Some(self.consume_token().unwrap());
2433 if self.peek_is(&GraphQLTokenKind::Pipe) {
2435 leading_pipe = Some(self.consume_token().unwrap());
2436 }
2437 members.push(self.expect_ast_name()?);
2438 while self.peek_is(&GraphQLTokenKind::Pipe) {
2439 pipes.push(self.consume_token().unwrap());
2440 members.push(self.expect_ast_name()?);
2441 }
2442 }
2443 if self.config.retain_syntax {
2444 let span = self.make_span_ref(&keyword_token.span);
2445 Ok(ast::TypeDefinition::Union(ast::UnionTypeDefinition {
2446 description, directives, members, name, span,
2447 syntax: Some(Box::new(ast::UnionTypeDefinitionSyntax {
2448 equals: equals_token, leading_pipe, pipes,
2449 union_keyword: keyword_token,
2450 })),
2451 }))
2452 } else {
2453 let span = self.make_span(keyword_token.span);
2454 Ok(ast::TypeDefinition::Union(ast::UnionTypeDefinition {
2455 description, directives, members, name, span, syntax: None,
2456 }))
2457 }
2458 }
2459
2460 fn parse_enum_type_definition(
2462 &mut self,
2463 description: Option<ast::StringValue<'src>>,
2464 ) -> Result<ast::TypeDefinition<'src>, ()> {
2465 let keyword_token = self.expect_keyword("enum")?;
2466 let name = self.expect_ast_name()?;
2467 let directives = self.parse_const_directive_annotations()?;
2468 let (values, value_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
2469 self.parse_enum_values_definition()?
2470 } else {
2471 (Vec::new(), None)
2472 };
2473 if self.config.retain_syntax {
2474 let span = self.make_span_ref(&keyword_token.span);
2475 Ok(ast::TypeDefinition::Enum(ast::EnumTypeDefinition {
2476 description, directives, name, span,
2477 syntax: Some(Box::new(ast::EnumTypeDefinitionSyntax {
2478 braces: value_delimiters, enum_keyword: keyword_token,
2479 })),
2480 values,
2481 }))
2482 } else {
2483 let span = self.make_span(keyword_token.span);
2484 Ok(ast::TypeDefinition::Enum(ast::EnumTypeDefinition {
2485 description, directives, name, span, syntax: None, values,
2486 }))
2487 }
2488 }
2489
2490 fn parse_input_object_type_definition(
2492 &mut self,
2493 description: Option<ast::StringValue<'src>>,
2494 ) -> Result<ast::TypeDefinition<'src>, ()> {
2495 let keyword_token = self.expect_keyword("input")?;
2496 let name = self.expect_ast_name()?;
2497 let directives = self.parse_const_directive_annotations()?;
2498 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
2499 self.parse_input_fields_definition()?
2500 } else {
2501 (Vec::new(), None)
2502 };
2503 if self.config.retain_syntax {
2504 let span = self.make_span_ref(&keyword_token.span);
2505 Ok(ast::TypeDefinition::InputObject(ast::InputObjectTypeDefinition {
2506 description, directives, fields, name, span,
2507 syntax: Some(Box::new(ast::InputObjectTypeDefinitionSyntax {
2508 braces: field_delimiters, input_keyword: keyword_token,
2509 })),
2510 }))
2511 } else {
2512 let span = self.make_span(keyword_token.span);
2513 Ok(ast::TypeDefinition::InputObject(ast::InputObjectTypeDefinition {
2514 description, directives, fields, name, span, syntax: None,
2515 }))
2516 }
2517 }
2518
2519 fn parse_directive_definition(
2521 &mut self,
2522 description: Option<ast::StringValue<'src>>,
2523 ) -> Result<ast::DirectiveDefinition<'src>, ()> {
2524 let keyword_token = self.expect_keyword("directive")?;
2525 let at_token = self.expect(&GraphQLTokenKind::At)?;
2526 let name = self.expect_ast_name()?;
2527 let (arguments, argument_delimiters) =
2528 if self.peek_is(&GraphQLTokenKind::ParenOpen) {
2529 self.parse_arguments_definition()?
2530 } else {
2531 (Vec::new(), None)
2532 };
2533 let repeatable_token = if self.peek_is_keyword("repeatable") {
2534 Some(self.consume_token().unwrap())
2535 } else {
2536 None
2537 };
2538 let repeatable = repeatable_token.is_some();
2539 let on_token = self.expect_keyword("on")?;
2540 let locations = self.parse_directive_locations()?;
2541 if self.config.retain_syntax {
2542 let span = self.make_span_ref(&keyword_token.span);
2543 Ok(ast::DirectiveDefinition {
2544 arguments, description, locations, name, repeatable, span,
2545 syntax: Some(Box::new(ast::DirectiveDefinitionSyntax {
2546 argument_parens: argument_delimiters, at_sign: at_token,
2547 directive_keyword: keyword_token, on_keyword: on_token,
2548 repeatable_keyword: repeatable_token,
2549 })),
2550 })
2551 } else {
2552 let span = self.make_span(keyword_token.span);
2553 Ok(ast::DirectiveDefinition {
2554 arguments, description, locations, name, repeatable, span, syntax: None,
2555 })
2556 }
2557 }
2558
2559 fn parse_ast_implements_interfaces(&mut self) -> Result<ImplementsClause<'src>, ()> {
2561 let implements_keyword = self.expect_keyword("implements")?;
2562 let leading_ampersand = if self.peek_is(&GraphQLTokenKind::Ampersand) {
2564 Some(self.consume_token().unwrap())
2565 } else {
2566 None
2567 };
2568 let mut interfaces = Vec::new();
2569 let mut ampersands = Vec::new();
2570 interfaces.push(self.expect_ast_name()?);
2571 while self.peek_is(&GraphQLTokenKind::Ampersand) {
2572 ampersands.push(self.consume_token().unwrap());
2573 interfaces.push(self.expect_ast_name()?);
2574 }
2575 Ok(ImplementsClause {
2576 ampersands, implements_keyword, interfaces, leading_ampersand,
2577 })
2578 }
2579
2580 fn parse_ast_fields_definition(
2582 &mut self,
2583 context: DelimiterContext,
2584 ) -> Result<(Vec<ast::FieldDefinition<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
2585 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
2586 self.push_delimiter(open_token.span, context);
2587 let mut fields = Vec::new();
2588 loop {
2589 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
2590 break;
2591 }
2592 if self.token_stream.is_at_end() {
2593 self.handle_unclosed_brace();
2594 return Err(());
2595 }
2596 fields.push(self.parse_field_definition()?);
2597 }
2598 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
2599 self.pop_delimiter();
2600 let delimiters = if self.config.retain_syntax {
2601 Some(ast::DelimiterPair { close: close_token, open: open_token })
2602 } else {
2603 None
2604 };
2605 Ok((fields, delimiters))
2606 }
2607
2608 fn parse_field_definition(&mut self) -> Result<ast::FieldDefinition<'src>, ()> {
2610 let description = self.parse_ast_description();
2611 let name = self.expect_ast_name()?;
2612 let (arguments, argument_delimiters) =
2613 if self.peek_is(&GraphQLTokenKind::ParenOpen) {
2614 self.parse_arguments_definition()?
2615 } else {
2616 (Vec::new(), None)
2617 };
2618 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
2619 let field_type = self.parse_type_annotation()?;
2620 let directives = self.parse_const_directive_annotations()?;
2621 let span = ByteSpan::new(
2622 name.span.start,
2623 self.last_end_position.unwrap_or(name.span.end),
2624 );
2625 let syntax = if self.config.retain_syntax {
2626 Some(Box::new(ast::FieldDefinitionSyntax {
2627 argument_parens: argument_delimiters, colon: colon_token,
2628 }))
2629 } else {
2630 None
2631 };
2632 Ok(ast::FieldDefinition {
2633 parameters: arguments, description, directives, field_type, name, span, syntax,
2634 })
2635 }
2636
2637 fn parse_arguments_definition(
2639 &mut self,
2640 ) -> Result<(Vec<ast::InputValueDefinition<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
2641 let open_token = self.expect(&GraphQLTokenKind::ParenOpen)?;
2642 self.push_delimiter(open_token.span, DelimiterContext::ArgumentDefinitions);
2643 let mut arguments = Vec::new();
2644 loop {
2645 if self.peek_is(&GraphQLTokenKind::ParenClose) {
2646 break;
2647 }
2648 if self.token_stream.is_at_end() {
2649 self.handle_unclosed_paren();
2650 return Err(());
2651 }
2652 arguments.push(self.parse_input_value_definition()?);
2653 }
2654 let close_token = self.expect(&GraphQLTokenKind::ParenClose)?;
2655 self.pop_delimiter();
2656 let delimiters = if self.config.retain_syntax {
2657 Some(ast::DelimiterPair { close: close_token, open: open_token })
2658 } else {
2659 None
2660 };
2661 Ok((arguments, delimiters))
2662 }
2663
2664 fn parse_input_fields_definition(
2666 &mut self,
2667 ) -> Result<(Vec<ast::InputValueDefinition<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
2668 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
2669 self.push_delimiter(open_token.span, DelimiterContext::InputObjectDefinition);
2670 let mut fields = Vec::new();
2671 loop {
2672 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
2673 break;
2674 }
2675 if self.token_stream.is_at_end() {
2676 self.handle_unclosed_brace();
2677 return Err(());
2678 }
2679 fields.push(self.parse_input_value_definition()?);
2680 }
2681 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
2682 self.pop_delimiter();
2683 let delimiters = if self.config.retain_syntax {
2684 Some(ast::DelimiterPair { close: close_token, open: open_token })
2685 } else {
2686 None
2687 };
2688 Ok((fields, delimiters))
2689 }
2690
2691 fn parse_input_value_definition(&mut self) -> Result<ast::InputValueDefinition<'src>, ()> {
2693 let description = self.parse_ast_description();
2694 let name = self.expect_ast_name()?;
2695 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
2696 let value_type = self.parse_type_annotation()?;
2697 let (default_value, equals_token) = if self.peek_is(&GraphQLTokenKind::Equals) {
2698 let eq = self.consume_token().unwrap();
2699 (Some(self.parse_value(ConstContext::InputDefaultValue)?), Some(eq))
2700 } else {
2701 (None, None)
2702 };
2703 let directives = self.parse_const_directive_annotations()?;
2704 let span = ByteSpan::new(
2705 name.span.start,
2706 self.last_end_position.unwrap_or(name.span.end),
2707 );
2708 let syntax = if self.config.retain_syntax {
2709 Some(Box::new(ast::InputValueDefinitionSyntax {
2710 colon: colon_token, equals: equals_token,
2711 }))
2712 } else {
2713 None
2714 };
2715 Ok(ast::InputValueDefinition {
2716 default_value, description, directives, name, span, syntax, value_type,
2717 })
2718 }
2719
2720 fn parse_enum_values_definition(
2722 &mut self,
2723 ) -> Result<(Vec<ast::EnumValueDefinition<'src>>, Option<ast::DelimiterPair<'src>>), ()> {
2724 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
2725 self.push_delimiter(open_token.span, DelimiterContext::EnumDefinition);
2726 let mut values = Vec::new();
2727 loop {
2728 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
2729 break;
2730 }
2731 if self.token_stream.is_at_end() {
2732 self.handle_unclosed_brace();
2733 return Err(());
2734 }
2735 values.push(self.parse_enum_value_definition()?);
2736 }
2737 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
2738 self.pop_delimiter();
2739 let delimiters = if self.config.retain_syntax {
2740 Some(ast::DelimiterPair { close: close_token, open: open_token })
2741 } else {
2742 None
2743 };
2744 Ok((values, delimiters))
2745 }
2746
2747 fn parse_enum_value_definition(&mut self) -> Result<ast::EnumValueDefinition<'src>, ()> {
2749 let description = self.parse_ast_description();
2750 let name = self.expect_ast_name()?;
2751 if matches!(&*name.value, "true" | "false" | "null") {
2752 let mut error = GraphQLParseError::new(
2753 format!("enum value cannot be `{}`", name.value),
2754 GraphQLParseErrorKind::ReservedName {
2755 name: name.value.clone().into_owned(),
2756 context: ReservedNameContext::EnumValue,
2757 },
2758 self.resolve_span(name.span),
2759 );
2760 error.add_spec(
2761 "https://spec.graphql.org/October2021/#sec-Enum-Value-Uniqueness",
2762 );
2763 self.record_error(error);
2764 }
2765 let directives = self.parse_const_directive_annotations()?;
2766 let span = ByteSpan::new(
2767 name.span.start,
2768 self.last_end_position.unwrap_or(name.span.end),
2769 );
2770 Ok(ast::EnumValueDefinition { description, directives, name, span })
2771 }
2772
2773 fn parse_directive_locations(&mut self) -> Result<Vec<ast::DirectiveLocation<'src>>, ()> {
2775 let leading_pipe = if self.peek_is(&GraphQLTokenKind::Pipe) {
2777 Some(self.consume_token().unwrap())
2778 } else {
2779 None
2780 };
2781
2782 let mut locations = Vec::new();
2783 locations.push(self.parse_directive_location(leading_pipe)?);
2784
2785 while self.peek_is(&GraphQLTokenKind::Pipe) {
2786 let pipe = self.consume_token().unwrap();
2787 locations.push(self.parse_directive_location(Some(pipe))?);
2788 }
2789
2790 Ok(locations)
2791 }
2792
2793 fn parse_directive_location(
2795 &mut self, pipe: Option<GraphQLToken<'src>>,
2796 ) -> Result<ast::DirectiveLocation<'src>, ()> {
2797 let name = self.expect_ast_name()?;
2798 let kind = match &*name.value {
2799 "QUERY" => ast::DirectiveLocationKind::Query,
2801 "MUTATION" => ast::DirectiveLocationKind::Mutation,
2802 "SUBSCRIPTION" => ast::DirectiveLocationKind::Subscription,
2803 "FIELD" => ast::DirectiveLocationKind::Field,
2804 "FRAGMENT_DEFINITION" => ast::DirectiveLocationKind::FragmentDefinition,
2805 "FRAGMENT_SPREAD" => ast::DirectiveLocationKind::FragmentSpread,
2806 "INLINE_FRAGMENT" => ast::DirectiveLocationKind::InlineFragment,
2807 "VARIABLE_DEFINITION" => ast::DirectiveLocationKind::VariableDefinition,
2808 "SCHEMA" => ast::DirectiveLocationKind::Schema,
2810 "SCALAR" => ast::DirectiveLocationKind::Scalar,
2811 "OBJECT" => ast::DirectiveLocationKind::Object,
2812 "FIELD_DEFINITION" => ast::DirectiveLocationKind::FieldDefinition,
2813 "ARGUMENT_DEFINITION" => ast::DirectiveLocationKind::ArgumentDefinition,
2814 "INTERFACE" => ast::DirectiveLocationKind::Interface,
2815 "UNION" => ast::DirectiveLocationKind::Union,
2816 "ENUM" => ast::DirectiveLocationKind::Enum,
2817 "ENUM_VALUE" => ast::DirectiveLocationKind::EnumValue,
2818 "INPUT_OBJECT" => ast::DirectiveLocationKind::InputObject,
2819 "INPUT_FIELD_DEFINITION" => ast::DirectiveLocationKind::InputFieldDefinition,
2820 _ => {
2821 let mut error = GraphQLParseError::new(
2822 format!("unknown directive location `{}`", name.value),
2823 GraphQLParseErrorKind::InvalidSyntax,
2824 self.resolve_span(name.span),
2825 );
2826 if let Some(suggestion) = Self::suggest_directive_location(&name.value) {
2827 error.add_help(format!("did you mean `{suggestion}`?"));
2828 }
2829 self.record_error(error);
2830 return Err(());
2831 },
2832 };
2833 let syntax = if self.config.retain_syntax {
2834 Some(Box::new(ast::DirectiveLocationSyntax {
2835 pipe,
2836 token: name.syntax.unwrap().token,
2837 }))
2838 } else {
2839 None
2840 };
2841 Ok(ast::DirectiveLocation { kind, span: name.span, syntax })
2842 }
2843
2844 fn suggest_directive_location(input: &str) -> Option<&'static str> {
2846 const LOCATIONS: &[&str] = &[
2847 "QUERY",
2848 "MUTATION",
2849 "SUBSCRIPTION",
2850 "FIELD",
2851 "FRAGMENT_DEFINITION",
2852 "FRAGMENT_SPREAD",
2853 "INLINE_FRAGMENT",
2854 "VARIABLE_DEFINITION",
2855 "SCHEMA",
2856 "SCALAR",
2857 "OBJECT",
2858 "FIELD_DEFINITION",
2859 "ARGUMENT_DEFINITION",
2860 "INTERFACE",
2861 "UNION",
2862 "ENUM",
2863 "ENUM_VALUE",
2864 "INPUT_OBJECT",
2865 "INPUT_FIELD_DEFINITION",
2866 ];
2867
2868 let input_upper = input.to_uppercase();
2870 let mut best_match: Option<&'static str> = None;
2871 let mut best_distance = usize::MAX;
2872
2873 for &location in LOCATIONS {
2874 let distance = Self::edit_distance(&input_upper, location);
2875 if distance < best_distance && distance <= 3 {
2876 best_distance = distance;
2877 best_match = Some(location);
2878 }
2879 }
2880
2881 best_match
2882 }
2883
2884 fn edit_distance(a: &str, b: &str) -> usize {
2886 let a_chars: Vec<char> = a.chars().collect();
2887 let b_chars: Vec<char> = b.chars().collect();
2888 let m = a_chars.len();
2889 let n = b_chars.len();
2890
2891 if m == 0 {
2892 return n;
2893 }
2894 if n == 0 {
2895 return m;
2896 }
2897
2898 let mut prev: Vec<usize> = (0..=n).collect();
2899 let mut curr = vec![0; n + 1];
2900
2901 for i in 1..=m {
2902 curr[0] = i;
2903 for j in 1..=n {
2904 let cost = if a_chars[i - 1] == b_chars[j - 1] {
2905 0
2906 } else {
2907 1
2908 };
2909 curr[j] = (prev[j] + 1)
2910 .min(curr[j - 1] + 1)
2911 .min(prev[j - 1] + cost);
2912 }
2913 std::mem::swap(&mut prev, &mut curr);
2914 }
2915
2916 prev[n]
2917 }
2918
2919 fn parse_type_extension(&mut self) -> Result<ast::Definition<'src>, ()> {
2927 let extend_token = self.expect_keyword("extend")?;
2928 if self.peek_is_keyword("schema") {
2929 self.parse_schema_extension(extend_token)
2930 } else if self.peek_is_keyword("scalar") {
2931 self.parse_scalar_type_extension(extend_token)
2932 } else if self.peek_is_keyword("type") {
2933 self.parse_object_type_extension(extend_token)
2934 } else if self.peek_is_keyword("interface") {
2935 self.parse_interface_type_extension(extend_token)
2936 } else if self.peek_is_keyword("union") {
2937 self.parse_union_type_extension(extend_token)
2938 } else if self.peek_is_keyword("enum") {
2939 self.parse_enum_type_extension(extend_token)
2940 } else if self.peek_is_keyword("input") {
2941 self.parse_input_object_type_extension(extend_token)
2942 } else {
2943 let span = self.token_stream.peek()
2944 .map(|t| t.span)
2945 .unwrap_or_else(|| self.eof_span());
2946 let found = self.token_stream.peek()
2947 .map(|t| Self::token_kind_display(&t.kind))
2948 .unwrap_or_else(|| "end of input".to_string());
2949 self.record_error(GraphQLParseError::new(
2950 format!(
2951 "expected type extension keyword (`schema`, `scalar`, `type`, \
2952 `interface`, `union`, `enum`, `input`), found `{found}`"
2953 ),
2954 GraphQLParseErrorKind::UnexpectedToken {
2955 expected: vec![
2956 "schema".to_string(),
2957 "scalar".to_string(),
2958 "type".to_string(),
2959 "interface".to_string(),
2960 "union".to_string(),
2961 "enum".to_string(),
2962 "input".to_string(),
2963 ],
2964 found,
2965 },
2966 self.resolve_span(span),
2967 ));
2968 Err(())
2969 }
2970 }
2971
2972 fn parse_schema_extension(
2974 &mut self,
2975 extend_token: GraphQLToken<'src>,
2976 ) -> Result<ast::Definition<'src>, ()> {
2977 let schema_token = self.expect_keyword("schema")?;
2978 let directives = self.parse_const_directive_annotations()?;
2979 let mut root_operations = Vec::new();
2980 let mut braces = None;
2981 if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
2982 let open_token = self.expect(&GraphQLTokenKind::CurlyBraceOpen)?;
2983 self.push_delimiter(open_token.span, DelimiterContext::SchemaDefinition);
2984 loop {
2985 if self.peek_is(&GraphQLTokenKind::CurlyBraceClose) {
2986 break;
2987 }
2988 if self.token_stream.is_at_end() {
2989 self.handle_unclosed_brace();
2990 return Err(());
2991 }
2992 let op_name = self.expect_ast_name()?;
2993 let op_kind = match &*op_name.value {
2994 "query" => ast::OperationKind::Query,
2995 "mutation" => ast::OperationKind::Mutation,
2996 "subscription" => ast::OperationKind::Subscription,
2997 _ => {
2998 self.record_error(GraphQLParseError::new(
2999 format!(
3000 "unknown operation type `{}`; expected `query`, `mutation`, \
3001 or `subscription`",
3002 op_name.value,
3003 ),
3004 GraphQLParseErrorKind::InvalidSyntax,
3005 self.resolve_span(op_name.span),
3006 ));
3007 continue;
3008 },
3009 };
3010 let colon_token = self.expect(&GraphQLTokenKind::Colon)?;
3011 let named_type = self.expect_ast_name()?;
3012 let root_span = ByteSpan::new(
3013 op_name.span.start,
3014 named_type.span.end,
3015 );
3016 let root_syntax = if self.config.retain_syntax {
3017 Some(Box::new(ast::RootOperationTypeDefinitionSyntax {
3018 colon: colon_token,
3019 }))
3020 } else {
3021 None
3022 };
3023 root_operations.push(ast::RootOperationTypeDefinition {
3024 named_type, operation_kind: op_kind, span: root_span, syntax: root_syntax,
3025 });
3026 }
3027 let close_token = self.expect(&GraphQLTokenKind::CurlyBraceClose)?;
3028 self.pop_delimiter();
3029 if self.config.retain_syntax {
3030 braces = Some(ast::DelimiterPair { close: close_token, open: open_token });
3031 }
3032 }
3033 if self.config.retain_syntax {
3034 let span = self.make_span_ref(&extend_token.span);
3035 Ok(ast::Definition::SchemaExtension(ast::SchemaExtension {
3036 directives, root_operations, span,
3037 syntax: Some(Box::new(ast::SchemaExtensionSyntax {
3038 braces, extend_keyword: extend_token, schema_keyword: schema_token,
3039 })),
3040 }))
3041 } else {
3042 let span = self.make_span(extend_token.span);
3043 Ok(ast::Definition::SchemaExtension(ast::SchemaExtension {
3044 directives, root_operations, span, syntax: None,
3045 }))
3046 }
3047 }
3048
3049 fn parse_scalar_type_extension(
3051 &mut self,
3052 extend_token: GraphQLToken<'src>,
3053 ) -> Result<ast::Definition<'src>, ()> {
3054 let scalar_token = self.expect_keyword("scalar")?;
3055 let name = self.expect_ast_name()?;
3056 let directives = self.parse_const_directive_annotations()?;
3057 if self.config.retain_syntax {
3058 let span = self.make_span_ref(&extend_token.span);
3059 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Scalar(
3060 ast::ScalarTypeExtension {
3061 directives, name, span,
3062 syntax: Some(Box::new(ast::ScalarTypeExtensionSyntax {
3063 extend_keyword: extend_token, scalar_keyword: scalar_token,
3064 })),
3065 },
3066 )))
3067 } else {
3068 let span = self.make_span(extend_token.span);
3069 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Scalar(
3070 ast::ScalarTypeExtension { directives, name, span, syntax: None },
3071 )))
3072 }
3073 }
3074
3075 fn parse_object_type_extension(
3078 &mut self,
3079 extend_token: GraphQLToken<'src>,
3080 ) -> Result<ast::Definition<'src>, ()> {
3081 let type_token = self.expect_keyword("type")?;
3082 let name = self.expect_ast_name()?;
3083 let (implements_tokens, implements) = if self.peek_is_keyword("implements") {
3084 let clause = self.parse_ast_implements_interfaces()?;
3085 (Some(ImplementsClauseTokens {
3086 ampersands: clause.ampersands,
3087 implements_keyword: clause.implements_keyword,
3088 leading_ampersand: clause.leading_ampersand,
3089 }), clause.interfaces)
3090 } else {
3091 (None, Vec::new())
3092 };
3093 let directives = self.parse_const_directive_annotations()?;
3094 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3095 self.parse_ast_fields_definition(DelimiterContext::ObjectTypeDefinition)?
3096 } else {
3097 (Vec::new(), None)
3098 };
3099 if self.config.retain_syntax {
3100 let span = self.make_span_ref(&extend_token.span);
3101 let (impl_kw, leading_amp, amps) = match implements_tokens {
3102 Some(c) => (Some(c.implements_keyword), c.leading_ampersand, c.ampersands),
3103 None => (None, None, Vec::new()),
3104 };
3105 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Object(
3106 ast::ObjectTypeExtension {
3107 directives, fields, implements, name, span,
3108 syntax: Some(Box::new(ast::ObjectTypeExtensionSyntax {
3109 ampersands: amps, braces: field_delimiters,
3110 extend_keyword: extend_token, implements_keyword: impl_kw,
3111 leading_ampersand: leading_amp, type_keyword: type_token,
3112 })),
3113 },
3114 )))
3115 } else {
3116 let span = self.make_span(extend_token.span);
3117 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Object(
3118 ast::ObjectTypeExtension {
3119 directives, fields, implements, name, span, syntax: None,
3120 },
3121 )))
3122 }
3123 }
3124
3125 fn parse_interface_type_extension(
3127 &mut self,
3128 extend_token: GraphQLToken<'src>,
3129 ) -> Result<ast::Definition<'src>, ()> {
3130 let interface_token = self.expect_keyword("interface")?;
3131 let name = self.expect_ast_name()?;
3132 let (implements_tokens, implements) = if self.peek_is_keyword("implements") {
3133 let clause = self.parse_ast_implements_interfaces()?;
3134 (Some(ImplementsClauseTokens {
3135 ampersands: clause.ampersands,
3136 implements_keyword: clause.implements_keyword,
3137 leading_ampersand: clause.leading_ampersand,
3138 }), clause.interfaces)
3139 } else {
3140 (None, Vec::new())
3141 };
3142 let directives = self.parse_const_directive_annotations()?;
3143 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3144 self.parse_ast_fields_definition(DelimiterContext::InterfaceDefinition)?
3145 } else {
3146 (Vec::new(), None)
3147 };
3148 if self.config.retain_syntax {
3149 let span = self.make_span_ref(&extend_token.span);
3150 let (impl_kw, leading_amp, amps) = match implements_tokens {
3151 Some(c) => (Some(c.implements_keyword), c.leading_ampersand, c.ampersands),
3152 None => (None, None, Vec::new()),
3153 };
3154 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Interface(
3155 ast::InterfaceTypeExtension {
3156 directives, fields, implements, name, span,
3157 syntax: Some(Box::new(ast::InterfaceTypeExtensionSyntax {
3158 ampersands: amps, braces: field_delimiters,
3159 extend_keyword: extend_token, implements_keyword: impl_kw,
3160 interface_keyword: interface_token, leading_ampersand: leading_amp,
3161 })),
3162 },
3163 )))
3164 } else {
3165 let span = self.make_span(extend_token.span);
3166 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Interface(
3167 ast::InterfaceTypeExtension {
3168 directives, fields, implements, name, span, syntax: None,
3169 },
3170 )))
3171 }
3172 }
3173
3174 fn parse_union_type_extension(
3176 &mut self,
3177 extend_token: GraphQLToken<'src>,
3178 ) -> Result<ast::Definition<'src>, ()> {
3179 let union_token = self.expect_keyword("union")?;
3180 let name = self.expect_ast_name()?;
3181 let directives = self.parse_const_directive_annotations()?;
3182 let mut members = Vec::new();
3183 let mut equals_token = None;
3184 let mut leading_pipe = None;
3185 let mut pipes = Vec::new();
3186 if self.peek_is(&GraphQLTokenKind::Equals) {
3187 equals_token = Some(self.consume_token().unwrap());
3188 if self.peek_is(&GraphQLTokenKind::Pipe) {
3189 leading_pipe = Some(self.consume_token().unwrap());
3190 }
3191 members.push(self.expect_ast_name()?);
3192 while self.peek_is(&GraphQLTokenKind::Pipe) {
3193 pipes.push(self.consume_token().unwrap());
3194 members.push(self.expect_ast_name()?);
3195 }
3196 }
3197 if self.config.retain_syntax {
3198 let span = self.make_span_ref(&extend_token.span);
3199 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Union(
3200 ast::UnionTypeExtension {
3201 directives, members, name, span,
3202 syntax: Some(Box::new(ast::UnionTypeExtensionSyntax {
3203 equals: equals_token, extend_keyword: extend_token,
3204 leading_pipe, pipes, union_keyword: union_token,
3205 })),
3206 },
3207 )))
3208 } else {
3209 let span = self.make_span(extend_token.span);
3210 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Union(
3211 ast::UnionTypeExtension { directives, members, name, span, syntax: None },
3212 )))
3213 }
3214 }
3215
3216 fn parse_enum_type_extension(
3218 &mut self,
3219 extend_token: GraphQLToken<'src>,
3220 ) -> Result<ast::Definition<'src>, ()> {
3221 let enum_token = self.expect_keyword("enum")?;
3222 let name = self.expect_ast_name()?;
3223 let directives = self.parse_const_directive_annotations()?;
3224 let (values, value_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3225 self.parse_enum_values_definition()?
3226 } else {
3227 (Vec::new(), None)
3228 };
3229 if self.config.retain_syntax {
3230 let span = self.make_span_ref(&extend_token.span);
3231 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Enum(
3232 ast::EnumTypeExtension {
3233 directives, name, span,
3234 syntax: Some(Box::new(ast::EnumTypeExtensionSyntax {
3235 braces: value_delimiters, enum_keyword: enum_token,
3236 extend_keyword: extend_token,
3237 })),
3238 values,
3239 },
3240 )))
3241 } else {
3242 let span = self.make_span(extend_token.span);
3243 Ok(ast::Definition::TypeExtension(ast::TypeExtension::Enum(
3244 ast::EnumTypeExtension { directives, name, span, syntax: None, values },
3245 )))
3246 }
3247 }
3248
3249 fn parse_input_object_type_extension(
3251 &mut self,
3252 extend_token: GraphQLToken<'src>,
3253 ) -> Result<ast::Definition<'src>, ()> {
3254 let input_token = self.expect_keyword("input")?;
3255 let name = self.expect_ast_name()?;
3256 let directives = self.parse_const_directive_annotations()?;
3257 let (fields, field_delimiters) = if self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3258 self.parse_input_fields_definition()?
3259 } else {
3260 (Vec::new(), None)
3261 };
3262 if self.config.retain_syntax {
3263 let span = self.make_span_ref(&extend_token.span);
3264 Ok(ast::Definition::TypeExtension(ast::TypeExtension::InputObject(
3265 ast::InputObjectTypeExtension {
3266 directives, fields, name, span,
3267 syntax: Some(Box::new(ast::InputObjectTypeExtensionSyntax {
3268 braces: field_delimiters, extend_keyword: extend_token,
3269 input_keyword: input_token,
3270 })),
3271 },
3272 )))
3273 } else {
3274 let span = self.make_span(extend_token.span);
3275 Ok(ast::Definition::TypeExtension(ast::TypeExtension::InputObject(
3276 ast::InputObjectTypeExtension { directives, fields, name, span, syntax: None },
3277 )))
3278 }
3279 }
3280
3281 fn document_span(&self) -> ByteSpan {
3287 let end = self.last_end_position.unwrap_or(0);
3288 ByteSpan::new(0, end)
3289 }
3290
3291 pub fn parse_schema_document(mut self) -> ParseResult<'src, ast::Document<'src>> {
3293 let mut definitions = Vec::new();
3294 while !self.token_stream.is_at_end() {
3295 match self.parse_schema_definition_item() {
3296 Ok(def) => definitions.push(def),
3297 Err(()) => self.recover_to_next_definition(),
3298 }
3299 }
3300 self.finish_document(definitions)
3301 }
3302
3303 pub fn parse_executable_document(mut self) -> ParseResult<'src, ast::Document<'src>> {
3305 let mut definitions = Vec::new();
3306 while !self.token_stream.is_at_end() {
3307 match self.parse_executable_definition_item() {
3308 Ok(def) => definitions.push(def),
3309 Err(()) => self.recover_to_next_definition(),
3310 }
3311 }
3312 self.finish_document(definitions)
3313 }
3314
3315 pub fn parse_mixed_document(mut self) -> ParseResult<'src, ast::Document<'src>> {
3317 let mut definitions = Vec::new();
3318 while !self.token_stream.is_at_end() {
3319 match self.parse_mixed_definition_item() {
3320 Ok(def) => definitions.push(def),
3321 Err(()) => self.recover_to_next_definition(),
3322 }
3323 }
3324 self.finish_document(definitions)
3325 }
3326
3327 fn finish_document(
3331 mut self,
3332 definitions: Vec<ast::Definition<'src>>,
3333 ) -> ParseResult<'src, ast::Document<'src>> {
3334 let span = self.document_span();
3335 let syntax = if self.config.retain_syntax {
3336 let trailing_trivia = self.token_stream.peek()
3337 .map(|eof| eof.preceding_trivia.to_vec())
3338 .unwrap_or_default();
3339 Some(Box::new(ast::DocumentSyntax { trailing_trivia }))
3340 } else {
3341 None
3342 };
3343 let document = ast::Document { definitions, span, syntax };
3344 let source_map = self.token_stream.into_source_map();
3345 if self.errors.is_empty() {
3346 ParseResult::new_ok(document, source_map)
3347 } else {
3348 ParseResult::new_recovered(document, self.errors, source_map)
3349 }
3350 }
3351
3352 fn parse_schema_definition_item(&mut self) -> Result<ast::Definition<'src>, ()> {
3354 if let Some(token) = self.token_stream.peek()
3356 && let GraphQLTokenKind::Error(_) = &token.kind {
3357 let token = token.clone();
3358 self.handle_lexer_error(&token);
3359 self.consume_token();
3360 return Err(());
3361 }
3362
3363 let description = self.parse_ast_description();
3364
3365 if self.peek_is_keyword("schema") {
3366 Ok(ast::Definition::SchemaDefinition(self.parse_schema_definition(description)?))
3367 } else if self.peek_is_keyword("scalar") {
3368 Ok(ast::Definition::TypeDefinition(self.parse_scalar_type_definition(description)?))
3369 } else if self.peek_is_keyword("type") {
3370 Ok(ast::Definition::TypeDefinition(self.parse_object_type_definition(description)?))
3371 } else if self.peek_is_keyword("interface") {
3372 Ok(ast::Definition::TypeDefinition(
3373 self.parse_interface_type_definition(description)?,
3374 ))
3375 } else if self.peek_is_keyword("union") {
3376 Ok(ast::Definition::TypeDefinition(self.parse_union_type_definition(description)?))
3377 } else if self.peek_is_keyword("enum") {
3378 Ok(ast::Definition::TypeDefinition(self.parse_enum_type_definition(description)?))
3379 } else if self.peek_is_keyword("input") {
3380 Ok(ast::Definition::TypeDefinition(
3381 self.parse_input_object_type_definition(description)?,
3382 ))
3383 } else if self.peek_is_keyword("directive") {
3384 Ok(ast::Definition::DirectiveDefinition(
3385 self.parse_directive_definition(description)?,
3386 ))
3387 } else if self.peek_is_keyword("extend") {
3388 self.parse_type_extension()
3389 } else if self.peek_is_keyword("query")
3390 || self.peek_is_keyword("mutation")
3391 || self.peek_is_keyword("subscription")
3392 || self.peek_is_keyword("fragment")
3393 || self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3394 let span = self
3396 .token_stream.peek()
3397 .map(|t| t.span)
3398 .unwrap_or_else(|| self.eof_span());
3399 let kind = if self.peek_is_keyword("fragment") {
3400 ast::DefinitionKind::Fragment
3401 } else {
3402 ast::DefinitionKind::Operation
3403 };
3404 self.record_error(GraphQLParseError::new(
3405 format!(
3406 "{} not allowed in schema document",
3407 match kind {
3408 ast::DefinitionKind::Fragment => "fragment definition",
3409 ast::DefinitionKind::Operation => "operation definition",
3410 _ => "definition",
3411 }
3412 ),
3413 GraphQLParseErrorKind::WrongDocumentKind {
3414 found: kind,
3415 document_kind: ast::DocumentKind::Schema,
3416 },
3417 self.resolve_span(span),
3418 ));
3419 self.consume_token();
3424 Err(())
3425 } else {
3426 let span = self
3427 .token_stream.peek()
3428 .map(|t| t.span)
3429 .unwrap_or_else(|| self.eof_span());
3430 let found = self
3431 .token_stream.peek()
3432 .map(|t| Self::token_kind_display(&t.kind))
3433 .unwrap_or_else(|| "end of input".to_string());
3434 self.consume_token();
3439 self.record_error(GraphQLParseError::new(
3440 format!("expected schema definition, found `{found}`"),
3441 GraphQLParseErrorKind::UnexpectedToken {
3442 expected: vec![
3443 "type".to_string(),
3444 "interface".to_string(),
3445 "union".to_string(),
3446 "enum".to_string(),
3447 "scalar".to_string(),
3448 "input".to_string(),
3449 "directive".to_string(),
3450 "schema".to_string(),
3451 "extend".to_string(),
3452 ],
3453 found,
3454 },
3455 self.resolve_span(span),
3456 ));
3457 Err(())
3458 }
3459 }
3460
3461 fn parse_executable_definition_item(&mut self) -> Result<ast::Definition<'src>, ()> {
3463 if let Some(token) = self.token_stream.peek()
3465 && let GraphQLTokenKind::Error(_) = &token.kind {
3466 let token = token.clone();
3467 self.handle_lexer_error(&token);
3468 self.consume_token();
3469 return Err(());
3470 }
3471
3472 if self.peek_is_keyword("query")
3473 || self.peek_is_keyword("mutation")
3474 || self.peek_is_keyword("subscription")
3475 || self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3476 Ok(ast::Definition::OperationDefinition(self.parse_operation_definition()?))
3477 } else if self.peek_is_keyword("fragment") {
3478 Ok(ast::Definition::FragmentDefinition(self.parse_fragment_definition()?))
3479 } else if self.peek_is_keyword("type")
3480 || self.peek_is_keyword("interface")
3481 || self.peek_is_keyword("union")
3482 || self.peek_is_keyword("enum")
3483 || self.peek_is_keyword("scalar")
3484 || self.peek_is_keyword("input")
3485 || self.peek_is_keyword("directive")
3486 || self.peek_is_keyword("schema")
3487 || self.peek_is_keyword("extend") {
3488 let span = self
3490 .token_stream.peek()
3491 .map(|t| t.span)
3492 .unwrap_or_else(|| self.eof_span());
3493 let kind = if self.peek_is_keyword("directive") {
3494 ast::DefinitionKind::DirectiveDefinition
3495 } else if self.peek_is_keyword("schema") || self.peek_is_keyword("extend") {
3496 ast::DefinitionKind::Schema
3497 } else {
3498 ast::DefinitionKind::TypeDefinition
3499 };
3500 self.consume_token();
3501 self.record_error(GraphQLParseError::new(
3502 format!(
3503 "{} not allowed in executable document",
3504 match kind {
3505 ast::DefinitionKind::TypeDefinition => "type definition",
3506 ast::DefinitionKind::DirectiveDefinition => "directive definition",
3507 ast::DefinitionKind::Schema => "schema definition",
3508 _ => "definition",
3509 }
3510 ),
3511 GraphQLParseErrorKind::WrongDocumentKind {
3512 found: kind,
3513 document_kind: ast::DocumentKind::Executable,
3514 },
3515 self.resolve_span(span),
3516 ));
3517 Err(())
3518 } else {
3519 let first_is_string = self
3523 .token_stream.peek()
3524 .map(|t| matches!(&t.kind, GraphQLTokenKind::StringValue(_)))
3525 .unwrap_or(false);
3526
3527 if first_is_string {
3528 let is_type_def = self.token_stream.peek_nth(1).is_some_and(|next| {
3530 if let GraphQLTokenKind::Name(name) = &next.kind {
3531 matches!(
3532 name.as_ref(),
3533 "type"
3534 | "interface"
3535 | "union"
3536 | "enum"
3537 | "scalar"
3538 | "input"
3539 | "directive"
3540 | "schema"
3541 | "extend"
3542 )
3543 } else {
3544 false
3545 }
3546 });
3547
3548 if is_type_def {
3549 let span = self
3550 .token_stream.peek()
3551 .map(|t| t.span)
3552 .unwrap_or_else(|| self.eof_span());
3553 self.consume_token();
3554 self.record_error(GraphQLParseError::new(
3555 "type definition not allowed in executable document",
3556 GraphQLParseErrorKind::WrongDocumentKind {
3557 found: ast::DefinitionKind::TypeDefinition,
3558 document_kind: ast::DocumentKind::Executable,
3559 },
3560 self.resolve_span(span),
3561 ));
3562 return Err(());
3563 }
3564 }
3565
3566 let span = self
3567 .token_stream.peek()
3568 .map(|t| t.span)
3569 .unwrap_or_else(|| self.eof_span());
3570 let found = self
3571 .token_stream.peek()
3572 .map(|t| Self::token_kind_display(&t.kind))
3573 .unwrap_or_else(|| "end of input".to_string());
3574 self.consume_token();
3579 self.record_error(GraphQLParseError::new(
3580 format!(
3581 "expected operation or fragment definition, found `{found}`"
3582 ),
3583 GraphQLParseErrorKind::UnexpectedToken {
3584 expected: vec![
3585 "query".to_string(),
3586 "mutation".to_string(),
3587 "subscription".to_string(),
3588 "fragment".to_string(),
3589 "{".to_string(),
3590 ],
3591 found,
3592 },
3593 self.resolve_span(span),
3594 ));
3595 Err(())
3596 }
3597 }
3598
3599 fn parse_mixed_definition_item(
3601 &mut self,
3602 ) -> Result<ast::Definition<'src>, ()> {
3603 if let Some(token) = self.token_stream.peek()
3605 && let GraphQLTokenKind::Error(_) = &token.kind {
3606 let token = token.clone();
3607 self.handle_lexer_error(&token);
3608 self.consume_token();
3609 return Err(());
3610 }
3611
3612 let description = self.parse_ast_description();
3613
3614 if self.peek_is_keyword("schema") {
3615 Ok(ast::Definition::SchemaDefinition(
3616 self.parse_schema_definition(description)?,
3617 ))
3618 } else if self.peek_is_keyword("scalar") {
3619 Ok(ast::Definition::TypeDefinition(
3620 self.parse_scalar_type_definition(description)?,
3621 ))
3622 } else if self.peek_is_keyword("type") {
3623 Ok(ast::Definition::TypeDefinition(
3624 self.parse_object_type_definition(description)?,
3625 ))
3626 } else if self.peek_is_keyword("interface") {
3627 Ok(ast::Definition::TypeDefinition(
3628 self.parse_interface_type_definition(description)?,
3629 ))
3630 } else if self.peek_is_keyword("union") {
3631 Ok(ast::Definition::TypeDefinition(
3632 self.parse_union_type_definition(description)?,
3633 ))
3634 } else if self.peek_is_keyword("enum") {
3635 Ok(ast::Definition::TypeDefinition(
3636 self.parse_enum_type_definition(description)?,
3637 ))
3638 } else if self.peek_is_keyword("input") {
3639 Ok(ast::Definition::TypeDefinition(
3640 self.parse_input_object_type_definition(description)?,
3641 ))
3642 } else if self.peek_is_keyword("directive") {
3643 Ok(ast::Definition::DirectiveDefinition(
3644 self.parse_directive_definition(description)?,
3645 ))
3646 } else if self.peek_is_keyword("extend") {
3647 self.parse_type_extension()
3648 } else if self.peek_is_keyword("query")
3649 || self.peek_is_keyword("mutation")
3650 || self.peek_is_keyword("subscription")
3651 || self.peek_is(&GraphQLTokenKind::CurlyBraceOpen) {
3652 Ok(ast::Definition::OperationDefinition(
3653 self.parse_operation_definition()?,
3654 ))
3655 } else if self.peek_is_keyword("fragment") {
3656 Ok(ast::Definition::FragmentDefinition(
3657 self.parse_fragment_definition()?,
3658 ))
3659 } else {
3660 let span = self
3661 .token_stream.peek()
3662 .map(|t| t.span)
3663 .unwrap_or_else(|| self.eof_span());
3664 let found = self
3665 .token_stream.peek()
3666 .map(|t| Self::token_kind_display(&t.kind))
3667 .unwrap_or_else(|| "end of input".to_string());
3668 self.consume_token();
3673 self.record_error(GraphQLParseError::new(
3674 format!("expected definition, found `{found}`"),
3675 GraphQLParseErrorKind::UnexpectedToken {
3676 expected: vec![
3677 "type".to_string(),
3678 "query".to_string(),
3679 "fragment".to_string(),
3680 ],
3681 found,
3682 },
3683 self.resolve_span(span),
3684 ));
3685 Err(())
3686 }
3687 }
3688}