Repository: apollographql/apollo-rs (rust)

Issue:
`recursion_limit` intended use is unclear
<!--
 Please fill out each section below, otherwise, your issue may be closed.
This info allows apollo-rs maintainers to diagnose (and fix!) your issue as
quickly as possible.

Before opening a new issue, please search existing issues:
https://github.com/apollographql/apollo-rs/issues
-->

## Description
This issue may not actually be a bug but i've found the `recursion_limit` option on the parser to not work the way I expect. My expectation is that this feature is guarding against stack overflows and should correlate to the number of stack frames deep the parser is while parsing but this doesn't appear to be the case.

For example, the following query fails when the recursion limit is set to 5:
```graphql
    {
        field
        field2
        field3
        field4
        field5
        field6
    }
```

```rust
    let parser = Parser::new(QUERY)
        .recursion_limit(5)
        .parse()
```

When digging into the code, it appears that sibling fields [happen sequentially](https://github.com/apollographql/apollo-rs/blob/e55a76538ae37b929f0a6c49544ba6d33c67c103/crates/apollo-parser/src/parser/grammar/selection.rs#L74) (allocating a `field(p)` stack, returning, and then allocating another one for the next field) meaning that I would expect the maximum recursion depth to be ~2 for this query but instead I get `Iter([ERROR@75:75 "parser limit(5) reached" ])`.

I admit this could be my misunderstanding this feature but I'd appreciate some clarity on how this feature should be used.

### Steps to reproduce
You can see the full example [here.](https://github.com/apollographql/apollo-rs/compare/main...allancalix:apollo-rs:recursion-limit)

### Expected result
Sibling fields should reset the recursion depth after returning for a single selection set.

### Actual result
Sibling fields do not reset the recursion depth and selection sets with many fields (possibly an arbitrarily large number given the ability to use aliases) hit the recursion limit.

### Environment

- Operating system and version: macos
- Shell (bash/zsh/powershell): fish
- `apollo-rs` crate: parser
- Crate version: `HEAD` as of 2022/04/04

Pull request description:
chore(parser): remove recursion in field parsing, fixes #514
The `selection::selection_set` parser already supports parsing multiple fields, so it looks like this recursion is unnecessary. Tests pass right now but I'll also run the fuzzer for a bit to make sure.

Patch:
diff --git a/crates/apollo-compiler/src/database/ast.rs b/crates/apollo-compiler/src/database/ast.rs
index e6df0c1..37e5760 100644
--- a/crates/apollo-compiler/src/database/ast.rs
+++ b/crates/apollo-compiler/src/database/ast.rs
@@ -93,7 +93,9 @@ mod tests {
         let schema = r#"
         query {
           Q1 {
-            url
+            url {
+              hostname
+            }
           }
         }
         "#;
@@ -104,7 +106,7 @@ mod tests {
 
         assert_eq!(ast.recursion_limit().high, 2);
         assert_eq!(ast.errors().len(), 1);
-        assert_eq!(ast.document().definitions().count(), 2);
+        assert_eq!(ast.document().definitions().count(), 1);
     }
 
     #[test]
@@ -112,7 +114,11 @@ mod tests {
         let schema = r#"
         query {
           Q1 {
-            url
+            Q2 {
+              Q3 {
+                url
+              }
+            }
           }
         }
         "#;
@@ -184,7 +190,7 @@ mod tests {
         assert_eq!(ast.errors().len(), 1);
         assert_eq!(
             ast.errors().next(),
-            Some(&apollo_parser::Error::limit("parser limit(3) reached", 61))
+            Some(&apollo_parser::Error::limit("parser limit(3) reached", 121))
         );
     }
 
diff --git a/crates/apollo-parser/src/parser/grammar/document.rs b/crates/apollo-parser/src/parser/grammar/document.rs
index 2ec289e..756aa54 100644
--- a/crates/apollo-parser/src/parser/grammar/document.rs
+++ b/crates/apollo-parser/src/parser/grammar/document.rs
@@ -14,6 +14,10 @@ pub(crate) fn document(p: &mut Parser) {
     let doc = p.start_node(SyntaxKind::DOCUMENT);
 
     while let Some(node) = p.peek() {
+        if p.recursion_limit.limited() {
+            break;
+        }
+
         match node {
             TokenKind::StringValue => {
                 let def = p.peek_data_n(2).unwrap();
diff --git a/crates/apollo-parser/src/parser/grammar/field.rs b/crates/apollo-parser/src/parser/grammar/field.rs
index 97924fa..f9a9903 100644
--- a/crates/apollo-parser/src/parser/grammar/field.rs
+++ b/crates/apollo-parser/src/parser/grammar/field.rs
@@ -10,16 +10,7 @@ use crate::{
 /// *Field*:
 ///     Alias? Name Arguments? Directives? SelectionSet?
 pub(crate) fn field(p: &mut Parser) {
-    // We need to enforce recursion limits to prevent
-    // excessive resource consumption or (more seriously)
-    // stack overflows.
-    p.recursion_limit.consume();
-    if p.recursion_limit.limited() {
-        p.limit_err(format!("parser limit({}) reached", p.recursion_limit.limit));
-        return;
-    }
-
-    let guard = p.start_node(SyntaxKind::FIELD);
+    let _guard = p.start_node(SyntaxKind::FIELD);
 
     if let Some(TokenKind::Name) = p.peek() {
         if let Some(T![:]) = p.peek_n(2) {
@@ -41,19 +32,6 @@ pub(crate) fn field(p: &mut Parser) {
     if let Some(T!['{']) = p.peek() {
         selection::selection_set(p);
     }
-
-    match p.peek() {
-        Some(TokenKind::Name) => {
-            guard.finish_node();
-
-            field(p)
-        }
-
-        Some(T!['}']) => {
-            guard.finish_node();
-        }
-        _ => guard.finish_node(),
-    }
 }
 
 /// See: https://spec.graphql.org/October2021/#FieldsDefinition
diff --git a/crates/apollo-parser/src/parser/grammar/selection.rs b/crates/apollo-parser/src/parser/grammar/selection.rs
index d9b4e28..2e9df78 100644
--- a/crates/apollo-parser/src/parser/grammar/selection.rs
+++ b/crates/apollo-parser/src/parser/grammar/selection.rs
@@ -312,7 +312,9 @@ query SomeQuery(
         let schema = r#"
         query {
           Q1 {
-            url
+            Q2 {
+              url
+            }
           }
         }
         "#;
@@ -322,7 +324,7 @@ query SomeQuery(
 
         assert_eq!(ast.recursion_limit().high, 2);
         assert_eq!(ast.errors().len(), 1);
-        assert_eq!(ast.document().definitions().count(), 2);
+        assert_eq!(ast.document().definitions().count(), 1);
     }
 
     #[test]
@@ -330,7 +332,9 @@ query SomeQuery(
         let schema = r#"
         query {
           Q1 {
-            url
+            Q2 {
+              url
+            }
           }
         }
         "#;
@@ -338,7 +342,7 @@ query SomeQuery(
 
         let ast = parser.parse();
 
-        assert_eq!(ast.recursion_limit().high, 4);
+        assert_eq!(ast.recursion_limit().high, 3);
         assert_eq!(ast.errors().len(), 0);
         assert_eq!(ast.document().definitions().count(), 1);
     }
@@ -347,9 +351,13 @@ query SomeQuery(
     fn it_errors_when_selection_set_recursion_limit_is_exceeded_with_inline_fragment() {
         let schema = r#"
         query {
-          ... on Page {
-            price
-            name
+          Q1 {
+            Q2 {
+              ... on Page {
+                price
+                name
+              }
+            }
           }
         }
         "#;
@@ -366,8 +374,12 @@ query SomeQuery(
     fn it_errors_when_selection_set_recursion_limit_is_exceeded_fragment_spread() {
         let schema = r#"
         query {
-          product {
-            ...Page
+          Q1 {
+            Q2 {
+              product {
+                ...Page
+              }
+            }
           }
         }
         "#;
@@ -377,7 +389,7 @@ query SomeQuery(
 
         assert_eq!(ast.recursion_limit().high, 3);
         assert_eq!(ast.errors().len(), 1);
-        assert_eq!(ast.document().definitions().count(), 1);
+        assert_eq!(dbg!(ast.document()).definitions().count(), 1);
     }
 
     #[test]
@@ -403,7 +415,7 @@ query SomeQuery(
 
         assert_eq!(ast.recursion_limit().high, 2);
         assert_eq!(ast.errors().len(), 1);
-        assert_eq!(ast.document().definitions().count(), 4);
+        assert_eq!(ast.document().definitions().count(), 1);
     }
 
     #[test]
@@ -411,7 +423,13 @@ query SomeQuery(
         let schema = r#"
         query {
           Q1 {
-            url
+            Q2 {
+              Q3 {
+                Q4 {
+                  Q5 { url }
+                }
+              }
+            }
           },
         }
         "#;
@@ -419,7 +437,7 @@ query SomeQuery(
 
         let ast = parser.parse();
 
-        assert_eq!(ast.recursion_limit().high, 4);
+        assert_eq!(ast.recursion_limit().high, 6);
         assert_eq!(ast.errors().len(), 0);
         assert_eq!(ast.document().definitions().count(), 1);
     }
diff --git a/crates/apollo-parser/src/parser/mod.rs b/crates/apollo-parser/src/parser/mod.rs
index 1af9de6..4a49d48 100644
--- a/crates/apollo-parser/src/parser/mod.rs
+++ b/crates/apollo-parser/src/parser/mod.rs
@@ -495,7 +495,7 @@ mod tests {
         let parser = Parser::new(source).recursion_limit(3).token_limit(200);
         let ast = parser.parse();
         let errors = ast.errors().collect::<Vec<_>>();
-        assert_eq!(errors, &[&Error::limit("parser limit(3) reached", 61),]);
+        assert_eq!(errors, &[&Error::limit("parser limit(3) reached", 121),]);
     }
 
     #[test]
@@ -522,8 +522,6 @@ mod tests {
         );
         assert_eq!(errors.next(), None);
 
-        // TODO(@goto-bus-stop) the comment is positioned wrong:
-        // https://github.com/apollographql/apollo-rs/issues/362
         let tree = expect![[r##"
             DOCUMENT@0..113
               WHITESPACE@0..13 "\n            "


Test patch:
diff --git a/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt b/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt
index fa9861b..8528832 100644
--- a/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt
+++ b/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt
@@ -61,4 +61,4 @@
                         - IDENT@79..85 "String"
             - WHITESPACE@85..86 "\n"
             - R_CURLY@86..87 "}"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt b/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt
index a0e5108..34fc706 100644
--- a/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt
+++ b/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt
@@ -128,4 +128,4 @@
             - WHITESPACE@214..215 "\n"
             - R_CURLY@215..216 "}"
     - WHITESPACE@216..217 "\n"
-recursion limit: 4096, high: 6
+recursion limit: 4096, high: 3
diff --git a/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt b/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt
index 5b77302..76a1c34 100644
--- a/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt
+++ b/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt
@@ -214,4 +214,4 @@
         - DIRECTIVE_LOCATIONS@413..429
             - DIRECTIVE_LOCATION@413..429
                 - FIELD_DEFINITION_KW@413..429 "FIELD_DEFINITION"
-recursion limit: 4096, high: 6
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt b/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt
index f126601..be221ee 100644
--- a/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt
+++ b/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt
@@ -143,4 +143,4 @@
             - WHITESPACE@204..205 "\n"
             - R_CURLY@205..206 "}"
     - WHITESPACE@206..207 "\n"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt b/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt
index 9282982..6ba1f25 100644
--- a/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt
+++ b/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt
@@ -477,4 +477,4 @@
                     - R_CURLY@1262..1263 "}"
             - WHITESPACE@1263..1264 "\n"
             - R_CURLY@1264..1265 "}"
-recursion limit: 4096, high: 31
+recursion limit: 4096, high: 8
diff --git a/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt b/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt
index c964a7b..6ae5537 100644
--- a/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt
+++ b/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt
@@ -231,4 +231,4 @@
                         - IDENT@429..432 "Int"
             - WHITESPACE@432..433 "\n"
             - R_CURLY@433..434 "}"
-recursion limit: 4096, high: 5
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt b/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt
index 5f4c319..c549ffb 100644
--- a/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt
+++ b/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt
@@ -186,4 +186,4 @@
                     - BANG@369..370 "!"
             - WHITESPACE@370..371 "\n"
             - R_CURLY@371..372 "}"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt b/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt
index 515fa83..f425e91 100644
--- a/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt
+++ b/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt
@@ -300,4 +300,4 @@
                         - IDENT@591..598 "Boolean"
             - WHITESPACE@598..599 "\n"
             - R_CURLY@599..600 "}"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt b/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt
index 628821c..4b20f87 100644
--- a/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt
+++ b/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt
@@ -110,4 +110,4 @@
             - WHITESPACE@201..202 "\n"
             - R_CURLY@202..203 "}"
     - WHITESPACE@203..204 "\n"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt b/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt
index 29d1490..2374236 100644
--- a/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt
+++ b/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt
@@ -147,4 +147,4 @@
             - WHITESPACE@317..318 "\n"
             - R_CURLY@318..319 "}"
     - WHITESPACE@319..320 "\n"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt b/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt
index 8a166fa..b615cf1 100644
--- a/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt
+++ b/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt
@@ -238,4 +238,4 @@
             - WHITESPACE@590..591 "\n"
             - R_CURLY@591..592 "}"
     - WHITESPACE@592..593 "\n"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt b/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt
index a3a4971..7ce6f56 100644
--- a/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt
+++ b/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt
@@ -541,4 +541,4 @@
             - WHITESPACE@979..980 "\n"
             - R_CURLY@980..981 "}"
     - WHITESPACE@981..982 "\n"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt b/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt
index e65d017..1a114be 100644
--- a/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt
+++ b/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt
@@ -281,4 +281,4 @@
             - WHITESPACE@503..504 "\n"
             - R_CURLY@504..505 "}"
     - WHITESPACE@505..506 "\n"
-recursion limit: 4096, high: 2
+recursion limit: 4096, high: 1
diff --git a/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt b/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt
index f164a8a..8cde270 100644
--- a/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt
+++ b/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt
@@ -88,4 +88,4 @@
             - WHITESPACE@164..165 "\n"
             - R_CURLY@165..166 "}"
     - WHITESPACE@166..167 "\n"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 1
diff --git a/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt b/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt
index 0c08214..aa87921 100644
--- a/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt
+++ b/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt
@@ -113,4 +113,4 @@
                     - R_CURLY@210..211 "}"
             - WHITESPACE@211..212 "\n"
             - R_CURLY@212..213 "}"
-recursion limit: 4096, high: 10
+recursion limit: 4096, high: 4
diff --git a/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt b/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt
index f62c70b..7fb23e2 100644
--- a/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt
+++ b/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt
@@ -72,4 +72,4 @@
                     - IDENT@123..133 "__typename"
             - WHITESPACE@133..134 "\n"
             - R_CURLY@134..135 "}"
-recursion limit: 4096, high: 3
+recursion limit: 4096, high: 1
diff --git a/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt b/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt
index 5f9b816..8890d1b 100644
--- a/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt
+++ b/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt
@@ -152,4 +152,4 @@
                     - R_CURLY@289..290 "}"
             - WHITESPACE@290..291 "\n"
             - R_CURLY@291..292 "}"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt b/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt
index 5b8f631..0b3b67b 100644
--- a/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt
+++ b/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt
@@ -214,4 +214,4 @@
             - WHITESPACE@300..301 "\n"
             - R_CURLY@301..302 "}"
     - WHITESPACE@302..303 "\n"
-recursion limit: 4096, high: 4
+recursion limit: 4096, high: 2
diff --git a/crates/apollo-parser/test_data/parser/err/0007_fragment_definition_with_invalid_fragment_name.txt b/crates/apollo-parser/test_data/parser/err/0007_fragment_definition_with_invalid_fragment_name.txt
index 1057c6a..0a61706 100644
--- a/crates/apollo-parser/test_data/parser/err/0007_fragment_definition_with_invalid_fragment_name.txt
+++ b/crates/apollo-parser/test_data/parser/err/0007_fragment_definition_with_invalid_fragment_name.txt
@@ -25,4 +25,4 @@
             - WHITESPACE@34..35 "\n"
             - R_CURLY@35..36 "}"
 - ERROR@9:11 "Fragment Name cannot be 'on'" on
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0008_fragment_definition_with_invalid_type_condition.txt b/crates/apollo-parser/test_data/parser/err/0008_fragment_definition_with_invalid_type_condition.txt
index 46349a9..1c968f3 100644
--- a/crates/apollo-parser/test_data/parser/err/0008_fragment_definition_with_invalid_type_condition.txt
+++ b/crates/apollo-parser/test_data/parser/err/0008_fragment_definition_with_invalid_type_condition.txt
@@ -26,4 +26,4 @@
             - WHITESPACE@44..45 "\n"
             - R_CURLY@45..46 "}"
 - ERROR@22:26 "exptected 'on'" User
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0025_document_with_incorrect_definition_and_selection_set.txt b/crates/apollo-parser/test_data/parser/err/0025_document_with_incorrect_definition_and_selection_set.txt
index a7cc237..f778af1 100644
--- a/crates/apollo-parser/test_data/parser/err/0025_document_with_incorrect_definition_and_selection_set.txt
+++ b/crates/apollo-parser/test_data/parser/err/0025_document_with_incorrect_definition_and_selection_set.txt
@@ -15,4 +15,4 @@
             - WHITESPACE@39..40 "\n"
             - R_CURLY@40..41 "}"
 - ERROR@0:14 "expected definition" uasdf21230jkdw
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0026_invalid_definition_squished_between_two_valid_definitions.txt b/crates/apollo-parser/test_data/parser/err/0026_invalid_definition_squished_between_two_valid_definitions.txt
index 0ac9a05..543e571 100644
--- a/crates/apollo-parser/test_data/parser/err/0026_invalid_definition_squished_between_two_valid_definitions.txt
+++ b/crates/apollo-parser/test_data/parser/err/0026_invalid_definition_squished_between_two_valid_definitions.txt
@@ -56,4 +56,4 @@
             - WHITESPACE@138..139 "\n"
             - R_CURLY@139..140 "}"
 - ERROR@99:113 "expected definition" uasdf21230jkdw
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0031_argument_with_erronous_string_value.txt b/crates/apollo-parser/test_data/parser/err/0031_argument_with_erronous_string_value.txt
index 6a181fc..a17c9b8 100644
--- a/crates/apollo-parser/test_data/parser/err/0031_argument_with_erronous_string_value.txt
+++ b/crates/apollo-parser/test_data/parser/err/0031_argument_with_erronous_string_value.txt
@@ -18,4 +18,4 @@
             - R_CURLY@15..16 "}"
 - ERROR@13:25 "unexpected escaped character" "\string ID"
 - ERROR@25:26 "expected a valid Value" )
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt b/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt
index d331ee9..529032b 100644
--- a/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt
+++ b/crates/apollo-parser/test_data/parser/err/0035_unterminated_string_value_in_object_value.txt
@@ -56,4 +56,4 @@
 - ERROR@116:116 "expected }" EOF
 - ERROR@116:116 "expected R_PAREN, got EOF" EOF
 - ERROR@116:116 "expected R_CURLY, got EOF" EOF
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0042_document_with_incorrect_token.txt b/crates/apollo-parser/test_data/parser/err/0042_document_with_incorrect_token.txt
index 99349b9..da833fb 100644
--- a/crates/apollo-parser/test_data/parser/err/0042_document_with_incorrect_token.txt
+++ b/crates/apollo-parser/test_data/parser/err/0042_document_with_incorrect_token.txt
@@ -42,4 +42,4 @@
             - R_CURLY@82..83 "}"
 - ERROR@0:1 "expected a StringValue, Name or OperationDefinition" @
 - ERROR@49:50 "expected a StringValue, Name or OperationDefinition" }
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/err/0046_incomplete_spreads.txt b/crates/apollo-parser/test_data/parser/err/0046_incomplete_spreads.txt
index 125aefc..7321aa3 100644
--- a/crates/apollo-parser/test_data/parser/err/0046_incomplete_spreads.txt
+++ b/crates/apollo-parser/test_data/parser/err/0046_incomplete_spreads.txt
@@ -16,4 +16,4 @@
             - R_CURLY@15..16 "}"
     - WHITESPACE@16..17 "\n"
 - ERROR@10:13 "expected an Inline Fragment or a Fragment Spread" ...
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 2
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0002_selection_simple.txt b/crates/apollo-parser/test_data/parser/ok/0002_selection_simple.txt
index 8424269..382112b 100644
--- a/crates/apollo-parser/test_data/parser/ok/0002_selection_simple.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0002_selection_simple.txt
@@ -12,4 +12,4 @@
                     - IDENT@14..23 "faveSnack"
             - WHITESPACE@23..24 "\n"
             - R_CURLY@24..25 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0003_selection_with_fields.txt b/crates/apollo-parser/test_data/parser/ok/0003_selection_with_fields.txt
index 8c18bb5..028edd1 100644
--- a/crates/apollo-parser/test_data/parser/ok/0003_selection_with_fields.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0003_selection_with_fields.txt
@@ -56,4 +56,4 @@
                     - IDENT@168..177 "faveSnack"
             - WHITESPACE@177..178 "\n"
             - R_CURLY@178..179 "}"
-recursion limit: 4096, high: 13
\ No newline at end of file
+recursion limit: 4096, high: 4
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0004_selection_with_fields_aliases_arguments.txt b/crates/apollo-parser/test_data/parser/ok/0004_selection_with_fields_aliases_arguments.txt
index 2a4f24b..d9e6bb1 100644
--- a/crates/apollo-parser/test_data/parser/ok/0004_selection_with_fields_aliases_arguments.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0004_selection_with_fields_aliases_arguments.txt
@@ -71,4 +71,4 @@
                     - R_PAREN@199..200 ")"
             - WHITESPACE@200..201 "\n"
             - R_CURLY@201..202 "}"
-recursion limit: 4096, high: 13
\ No newline at end of file
+recursion limit: 4096, high: 4
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0005_selection_with_inline_fragments.txt b/crates/apollo-parser/test_data/parser/ok/0005_selection_with_inline_fragments.txt
index 885feb1..a394dcb 100644
--- a/crates/apollo-parser/test_data/parser/ok/0005_selection_with_inline_fragments.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0005_selection_with_inline_fragments.txt
@@ -40,4 +40,4 @@
                     - R_CURLY@88..89 "}"
             - WHITESPACE@89..90 "\n"
             - R_CURLY@90..91 "}"
-recursion limit: 4096, high: 4
\ No newline at end of file
+recursion limit: 4096, high: 2
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0006_selection_with_fragment_spread.txt b/crates/apollo-parser/test_data/parser/ok/0006_selection_with_fragment_spread.txt
index 2b2b4d8..7a87568 100644
--- a/crates/apollo-parser/test_data/parser/ok/0006_selection_with_fragment_spread.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0006_selection_with_fragment_spread.txt
@@ -113,4 +113,4 @@
             - WHITESPACE@207..208 "\n"
             - R_CURLY@208..209 "}"
     - WHITESPACE@209..210 "\n"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0012_fragment_definition.txt b/crates/apollo-parser/test_data/parser/ok/0012_fragment_definition.txt
index b3f9c2b..bbcad57 100644
--- a/crates/apollo-parser/test_data/parser/ok/0012_fragment_definition.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0012_fragment_definition.txt
@@ -45,4 +45,4 @@
                     - R_PAREN@80..81 ")"
             - WHITESPACE@81..82 "\n"
             - R_CURLY@82..83 "}"
-recursion limit: 4096, high: 4
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0013_fragment_definition_with_fragment_spread.txt b/crates/apollo-parser/test_data/parser/ok/0013_fragment_definition_with_fragment_spread.txt
index ac1b2d1..31521db 100644
--- a/crates/apollo-parser/test_data/parser/ok/0013_fragment_definition_with_fragment_spread.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0013_fragment_definition_with_fragment_spread.txt
@@ -31,4 +31,4 @@
                         - IDENT@55..73 "standardProfilePic"
             - WHITESPACE@73..74 "\n"
             - R_CURLY@74..75 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0020_operation_type_definition.txt b/crates/apollo-parser/test_data/parser/ok/0020_operation_type_definition.txt
index a050b34..bb302c3 100644
--- a/crates/apollo-parser/test_data/parser/ok/0020_operation_type_definition.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0020_operation_type_definition.txt
@@ -51,4 +51,4 @@
                     - IDENT@113..117 "lion"
             - WHITESPACE@117..118 "\n"
             - R_CURLY@118..119 "}"
-recursion limit: 4096, high: 8
\ No newline at end of file
+recursion limit: 4096, high: 3
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0021_operation_type_definition_with_arguments.txt b/crates/apollo-parser/test_data/parser/ok/0021_operation_type_definition_with_arguments.txt
index 14b1e2e..fc9596d 100644
--- a/crates/apollo-parser/test_data/parser/ok/0021_operation_type_definition_with_arguments.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0021_operation_type_definition_with_arguments.txt
@@ -41,4 +41,4 @@
                     - IDENT@65..70 "treat"
             - WHITESPACE@70..71 "\n"
             - R_CURLY@71..72 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0022_operation_type_definition_with_arguments_and_directives.txt b/crates/apollo-parser/test_data/parser/ok/0022_operation_type_definition_with_arguments_and_directives.txt
index 66b5fd5..0f619bc 100644
--- a/crates/apollo-parser/test_data/parser/ok/0022_operation_type_definition_with_arguments_and_directives.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0022_operation_type_definition_with_arguments_and_directives.txt
@@ -53,4 +53,4 @@
                     - IDENT@86..91 "treat"
             - WHITESPACE@91..92 "\n"
             - R_CURLY@92..93 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0030_values.txt b/crates/apollo-parser/test_data/parser/ok/0030_values.txt
index b9254f7..db09e15 100644
--- a/crates/apollo-parser/test_data/parser/ok/0030_values.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0030_values.txt
@@ -83,4 +83,4 @@
                     - R_PAREN@111..112 ")"
             - WHITESPACE@112..113 "\n"
             - R_CURLY@113..114 "}"
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0031_variables_with_default.txt b/crates/apollo-parser/test_data/parser/ok/0031_variables_with_default.txt
index 3fd9b08..e5b5f72 100644
--- a/crates/apollo-parser/test_data/parser/ok/0031_variables_with_default.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0031_variables_with_default.txt
@@ -50,4 +50,4 @@
                     - IDENT@66..72 "animal"
             - WHITESPACE@72..73 "\n"
             - R_CURLY@73..74 "}"
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0034_query_shorthand_followed_by_fragment_definition.txt b/crates/apollo-parser/test_data/parser/ok/0034_query_shorthand_followed_by_fragment_definition.txt
index 00d39d8..06ba42e 100644
--- a/crates/apollo-parser/test_data/parser/ok/0034_query_shorthand_followed_by_fragment_definition.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0034_query_shorthand_followed_by_fragment_definition.txt
@@ -37,4 +37,4 @@
                     - IDENT@62..66 "name"
             - WHITESPACE@66..67 "\n"
             - R_CURLY@67..68 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0035_query_with_variables.txt b/crates/apollo-parser/test_data/parser/ok/0035_query_with_variables.txt
index e34f299..1862c07 100644
--- a/crates/apollo-parser/test_data/parser/ok/0035_query_with_variables.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0035_query_with_variables.txt
@@ -27,4 +27,4 @@
                     - IDENT@27..31 "name"
             - WHITESPACE@31..32 "\n"
             - R_CURLY@32..33 "}"
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0036_parses_variable_definition_with_list_type.txt b/crates/apollo-parser/test_data/parser/ok/0036_parses_variable_definition_with_list_type.txt
index 258e66d..67b6aec 100644
--- a/crates/apollo-parser/test_data/parser/ok/0036_parses_variable_definition_with_list_type.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0036_parses_variable_definition_with_list_type.txt
@@ -44,4 +44,4 @@
                     - R_PAREN@57..58 ")"
             - WHITESPACE@58..59 "\n"
             - R_CURLY@59..60 "}"
-recursion limit: 4096, high: 3
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0037_operation_type_definition_with_inline_fragment.txt b/crates/apollo-parser/test_data/parser/ok/0037_operation_type_definition_with_inline_fragment.txt
index c2f3d0c..d391e86 100644
--- a/crates/apollo-parser/test_data/parser/ok/0037_operation_type_definition_with_inline_fragment.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0037_operation_type_definition_with_inline_fragment.txt
@@ -105,4 +105,4 @@
                     - R_CURLY@190..191 "}"
             - WHITESPACE@191..192 "\n"
             - R_CURLY@192..193 "}"
-recursion limit: 4096, high: 4
\ No newline at end of file
+recursion limit: 4096, high: 2
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/parser/ok/0039_variable_with_directives.txt b/crates/apollo-parser/test_data/parser/ok/0039_variable_with_directives.txt
index 381f98d..a77fa5e 100644
--- a/crates/apollo-parser/test_data/parser/ok/0039_variable_with_directives.txt
+++ b/crates/apollo-parser/test_data/parser/ok/0039_variable_with_directives.txt
@@ -66,4 +66,4 @@
                     - IDENT@103..109 "animal"
             - WHITESPACE@109..110 "\n"
             - R_CURLY@110..111 "}"
-recursion limit: 4096, high: 2
\ No newline at end of file
+recursion limit: 4096, high: 1
\ No newline at end of file