@@ -62,11 +62,13 @@ std::string_view ast_node::unescaped_view() const
62
62
joined.append (child->string_view ());
63
63
}
64
64
65
- const_cast <ast_node*>(this )->_unescaped = std::make_unique<unescaped_t >(std::move (joined));
65
+ const_cast <ast_node*>(this )->_unescaped =
66
+ std::make_unique<unescaped_t >(std::move (joined));
66
67
}
67
68
else if (!children.empty ())
68
69
{
69
- const_cast <ast_node*>(this )->_unescaped = std::make_unique<unescaped_t >(children.front ()->string_view ());
70
+ const_cast <ast_node*>(this )->_unescaped =
71
+ std::make_unique<unescaped_t >(children.front ()->string_view ());
70
72
}
71
73
else if (has_content () && is_type<escaped_unicode>())
72
74
{
@@ -77,11 +79,13 @@ std::string_view ast_node::unescaped_view() const
77
79
utf8.reserve ((content.size () + 1 ) / 2 );
78
80
unescape::unescape_j::apply (in, utf8);
79
81
80
- const_cast <ast_node*>(this )->_unescaped = std::make_unique<unescaped_t >(std::move (utf8));
82
+ const_cast <ast_node*>(this )->_unescaped =
83
+ std::make_unique<unescaped_t >(std::move (utf8));
81
84
}
82
85
else
83
86
{
84
- const_cast <ast_node*>(this )->_unescaped = std::make_unique<unescaped_t >(std::string_view {});
87
+ const_cast <ast_node*>(this )->_unescaped =
88
+ std::make_unique<unescaped_t >(std::string_view {});
85
89
}
86
90
}
87
91
@@ -720,6 +724,9 @@ const std::string ast_control<input_object_type_extension_content>::error_messag
720
724
template <>
721
725
const std::string ast_control<document_content>::error_message =
722
726
" Expected http://spec.graphql.org/June2018/#Document" ;
727
+ template <>
728
+ const std::string ast_control<executable_document_content>::error_message =
729
+ " Expected http://spec.graphql.org/June2018/#Document" ;
723
730
724
731
ast parseSchemaString (std::string_view input)
725
732
{
@@ -756,8 +763,21 @@ ast parseString(std::string_view input)
756
763
const auto & data = std::get<std::vector<char >>(result.input ->data );
757
764
memory_input<> in (data.data (), data.size (), " GraphQL" );
758
765
759
- result.root =
760
- parse_tree::parse<document, ast_node, executable_selector, nothing, ast_control>(std::move (in));
766
+ try
767
+ {
768
+ // Try a smaller grammar with only executable definitions first.
769
+ result.root = parse_tree::
770
+ parse<executable_document, ast_node, executable_selector, nothing, ast_control>(
771
+ std::move (in));
772
+ }
773
+ catch (const peg::parse_error&)
774
+ {
775
+ // Try again with the full document grammar so validation can handle the unexepected type
776
+ // definitions if this is a mixed document.
777
+ result.root =
778
+ parse_tree::parse<document, ast_node, executable_selector, nothing, ast_control>(
779
+ std::move (in));
780
+ }
761
781
762
782
return result;
763
783
}
@@ -769,8 +789,21 @@ ast parseFile(std::string_view filename)
769
789
{} };
770
790
auto & in = *std::get<std::unique_ptr<file_input<>>>(result.input ->data );
771
791
772
- result.root =
773
- parse_tree::parse<document, ast_node, executable_selector, nothing, ast_control>(std::move (in));
792
+ try
793
+ {
794
+ // Try a smaller grammar with only executable definitions first.
795
+ result.root = parse_tree::
796
+ parse<executable_document, ast_node, executable_selector, nothing, ast_control>(
797
+ std::move (in));
798
+ }
799
+ catch (const peg::parse_error&)
800
+ {
801
+ // Try again with the full document grammar so validation can handle the unexepected type
802
+ // definitions if this is a mixed document.
803
+ result.root =
804
+ parse_tree::parse<document, ast_node, executable_selector, nothing, ast_control>(
805
+ std::move (in));
806
+ }
774
807
775
808
return result;
776
809
}
@@ -783,9 +816,11 @@ peg::ast operator"" _graphql(const char* text, size_t size)
783
816
784
817
return { std::make_shared<peg::ast_input>(
785
818
peg::ast_input { { std::string_view { text, size } } }),
786
- peg::parse_tree::
787
- parse<peg::document, peg::ast_node, peg::executable_selector, peg::nothing, peg::ast_control>(
788
- std::move (in)) };
819
+ peg::parse_tree::parse<peg::document,
820
+ peg::ast_node,
821
+ peg::executable_selector,
822
+ peg::nothing,
823
+ peg::ast_control>(std::move (in)) };
789
824
}
790
825
791
826
} /* namespace graphql */
0 commit comments