[parser] Better recovery for extra stuff in enum and using enum as identifier

Fixes https://github.com/dart-lang/sdk/issues/48371

Change-Id: I93331485c884c89c179c2fa332f3f975db9507f7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/234043
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 54a1efc..7248789 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -7477,6 +7477,37 @@
     problemMessage: r"""Can't have more than one 'super' initializer.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        String
+            string2)> templateMultipleClauses = const Template<
+        Message Function(String string, String string2)>(
+    problemMessageTemplate:
+        r"""Each '#string' definition can have at most one '#string2' clause.""",
+    correctionMessageTemplate:
+        r"""Try combining all of the '#string2' clauses into a single clause.""",
+    withArguments: _withArgumentsMultipleClauses);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+    codeMultipleClauses =
+    const Code<Message Function(String string, String string2)>(
+        "MultipleClauses",
+        index: 121);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMultipleClauses(String string, String string2) {
+  if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
+  return new Message(codeMultipleClauses,
+      problemMessage:
+          """Each '${string}' definition can have at most one '${string2}' clause.""",
+      correctionMessage: """Try combining all of the '${string2}' clauses into a single clause.""",
+      arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMultipleExtends = messageMultipleExtends;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -8370,6 +8401,37 @@
     correctionMessage: r"""Try removing the type parameters.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        String
+            string2)> templateOutOfOrderClauses = const Template<
+        Message Function(String string, String string2)>(
+    problemMessageTemplate:
+        r"""The '#string' clause must come before the '#string2' clause.""",
+    correctionMessageTemplate:
+        r"""Try moving the '#string' clause before the '#string2' clause.""",
+    withArguments: _withArgumentsOutOfOrderClauses);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+    codeOutOfOrderClauses =
+    const Code<Message Function(String string, String string2)>(
+        "OutOfOrderClauses",
+        index: 122);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOutOfOrderClauses(String string, String string2) {
+  if (string.isEmpty) throw 'No string provided';
+  if (string2.isEmpty) throw 'No string provided';
+  return new Message(codeOutOfOrderClauses,
+      problemMessage:
+          """The '${string}' clause must come before the '${string2}' clause.""",
+      correctionMessage: """Try moving the '${string}' clause before the '${string2}' clause.""",
+      arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateOverriddenMethodCause =
     const Template<Message Function(String name)>(
         problemMessageTemplate: r"""This is the overridden method ('#name').""",
@@ -10324,6 +10386,15 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeUnexpectedTokens = messageUnexpectedTokens;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageUnexpectedTokens = const MessageCode(
+    "UnexpectedTokens",
+    index: 123,
+    problemMessage: r"""Unexpected tokens.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string, Token token)>
     templateUnmatchedToken =
     const Template<Message Function(String string, Token token)>(
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
index 6e4c96b..4621543 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/identifier_context_impl.dart
@@ -124,8 +124,12 @@
     }
 
     // Recovery
-    if (isOneOfOrEof(identifier, followingValues) ||
-        looksLikeStartOfNextTopLevelDeclaration(identifier)) {
+    if (isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
@@ -603,8 +607,12 @@
         isOneOfOrEof(identifier.next!, followingValues)) {
       parser.reportRecoverableErrorWithToken(
           identifier, codes.templateBuiltInIdentifierInDeclaration);
-    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
-        isOneOfOrEof(identifier, followingValues)) {
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (isOneOfOrEof(identifier, followingValues)) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
@@ -802,8 +810,12 @@
     }
 
     // Recovery
-    if (isOneOfOrEof(identifier, followingValues) ||
-        looksLikeStartOfNextTopLevelDeclaration(identifier)) {
+    if (isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: codes.templateExpectedIdentifier.withArguments(identifier));
+    } else if (looksLikeStartOfNextTopLevelDeclaration(identifier) &&
+        (identifier.next == null ||
+            !isOneOfOrEof(identifier.next!, followingValues))) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: codes.templateExpectedIdentifier.withArguments(identifier));
     } else {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index c637b62..4aa4443 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -76,6 +76,9 @@
         looksLikeExpressionStart,
         okNextValueInFormalParameter;
 
+import 'identifier_context_impl.dart'
+    show looksLikeStartOfNextTopLevelDeclaration;
+
 import 'listener.dart' show Listener;
 
 import 'literal_entry_info.dart'
@@ -2005,11 +2008,140 @@
     token = computeTypeParamOrArg(
             token, /* inDeclaration = */ true, /* allowsVariance = */ true)
         .parseVariables(token, this);
+    List<String> lookForNext = const ['{', 'with', 'implements'];
+    if (!isOneOf(token.next!, lookForNext)) {
+      // Recovery: Possible unexpected tokens before any clauses.
+      Token? skipToken = recoverySmallLookAheadSkipTokens(token, lookForNext);
+      if (skipToken != null) {
+        token = skipToken;
+      }
+    }
+
+    Token beforeWith = token;
     token = parseEnumWithClauseOpt(token);
+
+    while (!isOneOf(token.next!, const ['{', 'implements'])) {
+      // Recovery: Skip unexpected tokens and more with clauses.
+      // Note that if we find a "with" we've seen one already (otherwise the
+      // parseEnumWithClauseOpt call above would have found this 'with').
+      Token? skipToken = recoveryEnumWith(token,
+              codes.templateMultipleClauses.withArguments("enum", "with")) ??
+          recoverySmallLookAheadSkipTokens(token, lookForNext);
+
+      if (skipToken != null) {
+        // Skipped tokens.
+        token = skipToken;
+      } else {
+        break;
+      }
+    }
+
     token = parseClassOrMixinOrEnumImplementsOpt(token);
+
+    bool? hasWithClauses;
+    while (!optional('{', token.next!)) {
+      if (hasWithClauses == null) {
+        hasWithClauses = optional('with', beforeWith.next!);
+      }
+
+      // Recovery: Skip unexpected tokens and more with/implements clauses.
+      Token? skipToken = recoveryEnumWith(
+          token,
+          hasWithClauses
+              ? codes.templateMultipleClauses.withArguments("enum", "with")
+              : codes.templateOutOfOrderClauses
+                  .withArguments("with", "implements"));
+      if (skipToken != null) {
+        hasWithClauses = true;
+      }
+      if (skipToken == null) {
+        // Note that if we find a "implements" we've seen one already (otherwise
+        // the parseClassOrMixinOrEnumImplementsOpt call above would have found
+        // this 'implements').
+        skipToken = recoveryEnumImplements(token,
+            codes.templateMultipleClauses.withArguments("enum", "implements"));
+      }
+      if (skipToken == null) {
+        skipToken = recoverySmallLookAheadSkipTokens(token, lookForNext);
+      }
+
+      if (skipToken != null) {
+        // Skipped tokens.
+        token = skipToken;
+      } else {
+        break;
+      }
+    }
+
     return token;
   }
 
+  Token? recoveryEnumWith(Token token, codes.Message message) {
+    if (optional('with', token.next!)) {
+      reportRecoverableError(token.next!, message);
+      Listener originalListener = listener;
+      listener = new NullListener();
+      token = parseEnumWithClauseOpt(token);
+      listener = originalListener;
+      return token;
+    }
+    return null;
+  }
+
+  Token? recoveryEnumImplements(Token token, codes.Message message) {
+    if (optional('implements', token.next!)) {
+      reportRecoverableError(token.next!, message);
+      Listener originalListener = listener;
+      listener = new NullListener();
+      token = parseClassOrMixinOrEnumImplementsOpt(token);
+      listener = originalListener;
+      return token;
+    }
+    return null;
+  }
+
+  /// Allow a small lookahead (currently up to 3 tokens) trying to find any in
+  /// [lookFor].
+  ///
+  /// If any wanted token is found an error is issued about unexpected tokens,
+  /// and the last skipped token is returned.
+  /// Otherwise null is returned.
+  Token? recoverySmallLookAheadSkipTokens(
+      final Token token, Iterable<String> lookFor) {
+    // Recovery: Allow a small lookahead for '{'. E.g. the user might be in
+    // the middle of writing 'with' or 'implements'.
+    Token skipToken = token.next!;
+    bool foundWanted = false;
+
+    if (looksLikeStartOfNextTopLevelDeclaration(skipToken)) return null;
+
+    int skipped = 0;
+    while (skipped < 3) {
+      skipped++;
+      if (isOneOf(skipToken.next!, lookFor)) {
+        foundWanted = true;
+        break;
+      }
+
+      skipToken = skipToken.next!;
+      if (looksLikeStartOfNextTopLevelDeclaration(skipToken)) return null;
+    }
+
+    if (foundWanted) {
+      // Give error and skip the tokens.
+      if (skipped == 1) {
+        reportRecoverableError(
+            skipToken, codes.templateUnexpectedToken.withArguments(skipToken));
+      } else {
+        reportRecoverableErrorWithEnd(
+            token.next!, skipToken, codes.messageUnexpectedTokens);
+      }
+      return skipToken;
+    }
+
+    return null;
+  }
+
   Token parseEnumElement(Token token) {
     Token beginToken = token;
     token = parseMetadataStar(token);
diff --git a/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart b/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
index baaedd1..5ebb1ac 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/enum_test.dart
@@ -29,7 +29,6 @@
   @override
   TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/48371')
   Future<void> test_afterName_w() async {
     var response = await getTestCodeSuggestions('''
 enum E w^ {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index d0f8738..61ddf10 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -841,6 +841,7 @@
   ParserErrorCode.MIXED_PARAMETER_GROUPS,
   ParserErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
   ParserErrorCode.MODIFIER_OUT_OF_ORDER,
+  ParserErrorCode.MULTIPLE_CLAUSES,
   ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES,
   ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES,
   ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES,
@@ -864,6 +865,7 @@
   ParserErrorCode.NON_USER_DEFINABLE_OPERATOR,
   ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS,
   ParserErrorCode.NULL_AWARE_CASCADE_OUT_OF_ORDER,
+  ParserErrorCode.OUT_OF_ORDER_CLAUSES,
   ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
   ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
   ParserErrorCode.PREFIX_AFTER_COMBINATOR,
@@ -887,6 +889,7 @@
   ParserErrorCode.TYPEDEF_IN_CLASS,
   ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
   ParserErrorCode.UNEXPECTED_TOKEN,
+  ParserErrorCode.UNEXPECTED_TOKENS,
   ParserErrorCode.VAR_AND_TYPE,
   ParserErrorCode.VAR_AS_TYPE_NAME,
   ParserErrorCode.VAR_CLASS,
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index e9762a2..c175e22 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -135,6 +135,9 @@
   ParserErrorCode.CONSTRUCTOR_WITH_TYPE_ARGUMENTS,
   ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR,
   ParserErrorCode.TYPE_PARAMETER_ON_OPERATOR,
+  ParserErrorCode.MULTIPLE_CLAUSES,
+  ParserErrorCode.OUT_OF_ORDER_CLAUSES,
+  ParserErrorCode.UNEXPECTED_TOKENS,
 ];
 
 class ParserErrorCode extends ErrorCode {
@@ -1294,6 +1297,13 @@
     correctionMessage: "Try re-ordering the modifiers.",
   );
 
+  static const ParserErrorCode MULTIPLE_CLAUSES = ParserErrorCode(
+    'MULTIPLE_CLAUSES',
+    "Each '{0}' definition can have at most one '{1}' clause.",
+    correctionMessage:
+        "Try combining all of the '{1}' clauses into a single clause.",
+  );
+
   static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = ParserErrorCode(
     'MULTIPLE_EXTENDS_CLAUSES',
     "Each class definition can have at most one extends clause.",
@@ -1468,6 +1478,12 @@
         "sequence.",
   );
 
+  static const ParserErrorCode OUT_OF_ORDER_CLAUSES = ParserErrorCode(
+    'OUT_OF_ORDER_CLAUSES',
+    "The '{0}' clause must come before the '{1}' clause.",
+    correctionMessage: "Try moving the '{0}' clause before the '{1}' clause.",
+  );
+
   static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT =
       ParserErrorCode(
     'POSITIONAL_AFTER_NAMED_ARGUMENT',
@@ -1636,6 +1652,11 @@
     correctionMessage: "Try removing the text.",
   );
 
+  static const ParserErrorCode UNEXPECTED_TOKENS = ParserErrorCode(
+    'UNEXPECTED_TOKENS',
+    "Unexpected tokens.",
+  );
+
   static const ParserErrorCode VAR_AND_TYPE = ParserErrorCode(
     'VAR_AND_TYPE',
     "Variables can't be declared using both 'var' and a type name.",
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 72c975a..b3403f3 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -482,6 +482,24 @@
   analyzerCode: MULTIPLE_IMPLEMENTS_CLAUSES
   script: "class A implements B implements C, D {}"
 
+MultipleClauses:
+  problemMessage: "Each '#string' definition can have at most one '#string2' clause."
+  correctionMessage: "Try combining all of the '#string2' clauses into a single clause."
+  experiments: enhanced-enums
+  analyzerCode: ParserErrorCode.MULTIPLE_CLAUSES
+  index: 121
+  script:
+    - "class B {} enum A implements B implements C, D { v; }"
+    - "class B {} enum A with B with C, D { v; }"
+
+OutOfOrderClauses:
+  problemMessage: "The '#string' clause must come before the '#string2' clause."
+  correctionMessage: "Try moving the '#string' clause before the '#string2' clause."
+  experiments: enhanced-enums
+  analyzerCode: ParserErrorCode.OUT_OF_ORDER_CLAUSES
+  index: 122
+  script: "class B {} class D {} enum A implements B with D { v; }"
+
 MultipleOnClauses:
   index: 26
   problemMessage: "Each mixin definition can have at most one on clause."
@@ -1321,6 +1339,12 @@
   script:
     - "import 'b.dart' d as b;"
 
+UnexpectedTokens:
+  problemMessage: "Unexpected tokens."
+  analyzerCode: ParserErrorCode.UNEXPECTED_TOKENS
+  index: 123
+  script: "enum E w Foo { v; }"
+
 LiteralWithClassAndNew:
   problemMessage: "A #string literal can't be prefixed by 'new #lexeme'."
   correctionMessage: "Try removing 'new' and '#lexeme'"
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart
new file mode 100644
index 0000000..4b9525a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart
@@ -0,0 +1,65 @@
+enum E w /*cursor, about to type 'with'*/ {
+  v
+}
+
+enum E w /*cursor, about to type 'with'*/ implements Foo {
+  v
+}
+
+enum E implements Foo with Bar {
+  v
+}
+
+enum E implements Foo implements Bar implements Bar2 {
+  v
+}
+
+enum E w /*cursor, about to type 'with' instead of implements*/ Foo {
+  v
+}
+
+enum E implemen /*cursor, about to type 'implements'*/ {
+  v
+}
+
+enum E implements Foo w/*about to write 'with'*/ {
+  v
+}
+
+enum E with /* cursor */ {
+  v
+}
+
+enum E impl implements Foo {
+  v
+}
+
+// Right order
+enum E with Foo implements Bar {
+  v
+}
+
+// Wrong order
+enum E implements Bar with Foo {
+  v
+}
+
+// Right order but with "gunk" before and between.
+enum E gunk1 with Foo gunk2 implements Bar {
+  v
+}
+
+// Wrong order but with "gunk" before and between.
+enum E gunk1 implements Bar gunk2 with Foo {
+  v
+}
+
+// (Partially) right order but additional clauses.
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+  v
+}
+
+// Wrong order and additional clauses.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+  v
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.expect
new file mode 100644
index 0000000..5837f2d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.expect
@@ -0,0 +1,512 @@
+Problems reported:
+
+parser/error_recovery/issue_48371:1:8: Unexpected token 'w'.
+enum E w /*cursor, about to type 'with'*/ {
+       ^
+
+parser/error_recovery/issue_48371:5:8: Unexpected token 'w'.
+enum E w /*cursor, about to type 'with'*/ implements Foo {
+       ^
+
+parser/error_recovery/issue_48371:9:23: The 'with' clause must come before the 'implements' clause.
+enum E implements Foo with Bar {
+                      ^^^^
+
+parser/error_recovery/issue_48371:13:23: Each 'enum' definition can have at most one 'implements' clause.
+enum E implements Foo implements Bar implements Bar2 {
+                      ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:13:38: Each 'enum' definition can have at most one 'implements' clause.
+enum E implements Foo implements Bar implements Bar2 {
+                                     ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:17:8: Unexpected tokens.
+enum E w /*cursor, about to type 'with' instead of implements*/ Foo {
+       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+parser/error_recovery/issue_48371:21:8: Unexpected token 'implemen'.
+enum E implemen /*cursor, about to type 'implements'*/ {
+       ^^^^^^^^
+
+parser/error_recovery/issue_48371:25:23: Unexpected token 'w'.
+enum E implements Foo w/*about to write 'with'*/ {
+                      ^
+
+parser/error_recovery/issue_48371:29:26: Expected a type, but got '{'.
+enum E with /* cursor */ {
+                         ^
+
+parser/error_recovery/issue_48371:33:8: Unexpected token 'impl'.
+enum E impl implements Foo {
+       ^^^^
+
+parser/error_recovery/issue_48371:43:23: The 'with' clause must come before the 'implements' clause.
+enum E implements Bar with Foo {
+                      ^^^^
+
+parser/error_recovery/issue_48371:48:8: Unexpected token 'gunk1'.
+enum E gunk1 with Foo gunk2 implements Bar {
+       ^^^^^
+
+parser/error_recovery/issue_48371:48:23: Unexpected token 'gunk2'.
+enum E gunk1 with Foo gunk2 implements Bar {
+                      ^^^^^
+
+parser/error_recovery/issue_48371:53:8: Unexpected token 'gunk1'.
+enum E gunk1 implements Bar gunk2 with Foo {
+       ^^^^^
+
+parser/error_recovery/issue_48371:53:29: Unexpected token 'gunk2'.
+enum E gunk1 implements Bar gunk2 with Foo {
+                            ^^^^^
+
+parser/error_recovery/issue_48371:53:35: The 'with' clause must come before the 'implements' clause.
+enum E gunk1 implements Bar gunk2 with Foo {
+                                  ^^^^
+
+parser/error_recovery/issue_48371:58:17: Each 'enum' definition can have at most one 'with' clause.
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+                ^^^^
+
+parser/error_recovery/issue_48371:58:42: Each 'enum' definition can have at most one 'implements' clause.
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+                                         ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:58:58: Each 'enum' definition can have at most one 'with' clause.
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+                                                         ^^^^
+
+parser/error_recovery/issue_48371:58:68: Each 'enum' definition can have at most one 'implements' clause.
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+                                                                   ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:63:23: Each 'enum' definition can have at most one 'implements' clause.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+                      ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:63:39: The 'with' clause must come before the 'implements' clause.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+                                      ^^^^
+
+parser/error_recovery/issue_48371:63:48: Each 'enum' definition can have at most one 'with' clause.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+                                               ^^^^
+
+parser/error_recovery/issue_48371:63:58: Each 'enum' definition can have at most one 'implements' clause.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+                                                         ^^^^^^^^^^
+
+parser/error_recovery/issue_48371:63:74: Each 'enum' definition can have at most one 'with' clause.
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+                                                                         ^^^^
+
+beginCompilationUnit(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(w)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(w)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+      handleEnumNoWithClause()
+      handleIdentifier(Foo, typeReference)
+      handleNoTypeArguments({)
+      handleType(Foo, null)
+      handleImplements(implements, 1)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implements)
+      handleEnumNoWithClause()
+      handleIdentifier(Foo, typeReference)
+      handleNoTypeArguments(with)
+      handleType(Foo, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implements)
+      handleEnumNoWithClause()
+      handleIdentifier(Foo, typeReference)
+      handleNoTypeArguments(implements)
+      handleType(Foo, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(w)
+      handleRecoverableError(UnexpectedTokens, w, Foo)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implemen)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'implemen'., null, {lexeme: implemen}], implemen, implemen)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implements)
+      handleEnumNoWithClause()
+      handleIdentifier(Foo, typeReference)
+      handleNoTypeArguments(w)
+      handleType(Foo, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(with)
+      beginTypeList({)
+        handleRecoverableError(Message[ExpectedType, Expected a type, but got '{'., null, {lexeme: {}], {, {)
+        handleIdentifier(, typeReference)
+        handleNoTypeArguments({)
+        handleType(, null)
+      endTypeList(1)
+      handleEnumWithClause(with)
+      handleImplements(null, 0)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(impl)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'impl'., null, {lexeme: impl}], impl, impl)
+      handleEnumNoWithClause()
+      handleIdentifier(Foo, typeReference)
+      handleNoTypeArguments({)
+      handleType(Foo, null)
+      handleImplements(implements, 1)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(with)
+      beginTypeList(Foo)
+        handleIdentifier(Foo, typeReference)
+        handleNoTypeArguments(implements)
+        handleType(Foo, null)
+      endTypeList(1)
+      handleEnumWithClause(with)
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments({)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implements)
+      handleEnumNoWithClause()
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments(with)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(gunk1)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}], gunk1, gunk1)
+      beginTypeList(Foo)
+        handleIdentifier(Foo, typeReference)
+        handleNoTypeArguments(gunk2)
+        handleType(Foo, null)
+      endTypeList(1)
+      handleEnumWithClause(with)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}], gunk2, gunk2)
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments({)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(gunk1)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}], gunk1, gunk1)
+      handleEnumNoWithClause()
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments(gunk2)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}], gunk2, gunk2)
+      handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(with)
+      beginTypeList(Foo)
+        handleIdentifier(Foo, typeReference)
+        handleNoTypeArguments(with)
+        handleType(Foo, null)
+      endTypeList(1)
+      handleEnumWithClause(with)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments(implements)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(implements)
+      handleEnumNoWithClause()
+      handleIdentifier(Bar, typeReference)
+      handleNoTypeArguments(implements)
+      handleType(Bar, null)
+      handleImplements(implements, 1)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+      handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(v)
+      endMetadataStar(0)
+      handleIdentifier(v, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(})
+      beginConstructorReference(v)
+        handleNoTypeArguments(})
+        handleNoConstructorReferenceContinuationAfterTypeArguments(})
+      endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+      handleNoArguments(v)
+      handleEnumElement({)
+      handleEnumElements(}, 1)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration()
+endCompilationUnit(15, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.intertwined.expect
new file mode 100644
index 0000000..98d94b2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.intertwined.expect
@@ -0,0 +1,681 @@
+parseUnit(enum)
+  skipErrorTokens(enum)
+  listener: beginCompilationUnit(enum)
+  syntheticPreviousToken(enum)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(w)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(w, Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+          parseEnumWithClauseOpt(w)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(w)
+            listener: handleImplements(null, 0)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(w)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(w, Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+          parseEnumWithClauseOpt(w)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(w)
+            listener: handleIdentifier(Foo, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(Foo, null)
+            listener: handleImplements(implements, 1)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implements)
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleIdentifier(Foo, typeReference)
+            listener: handleNoTypeArguments(with)
+            listener: handleType(Foo, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Foo, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+            reportRecoverableError(with, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+              listener: handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+            parseEnumWithClauseOpt(Foo)
+              parseTypeList(with)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implements)
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleIdentifier(Foo, typeReference)
+            listener: handleNoTypeArguments(implements)
+            listener: handleType(Foo, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Foo, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(Foo, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+          recoveryEnumWith(Bar, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(Bar, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Bar)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(w)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableErrorWithEnd(w, Foo, UnexpectedTokens)
+              listener: handleRecoverableError(UnexpectedTokens, w, Foo)
+          parseEnumWithClauseOpt(Foo)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(Foo)
+            listener: handleImplements(null, 0)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implemen)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(implemen, Message[UnexpectedToken, Unexpected token 'implemen'., null, {lexeme: implemen}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'implemen'., null, {lexeme: implemen}], implemen, implemen)
+          parseEnumWithClauseOpt(implemen)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(implemen)
+            listener: handleImplements(null, 0)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implements)
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleIdentifier(Foo, typeReference)
+            listener: handleNoTypeArguments(w)
+            listener: handleType(Foo, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Foo, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(Foo, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+          recoverySmallLookAheadSkipTokens(Foo, [{, with, implements])
+            reportRecoverableError(w, Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'w'., null, {lexeme: w}], w, w)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(with)
+          parseEnumWithClauseOpt(E)
+            parseTypeList(with)
+              listener: beginTypeList({)
+              reportRecoverableErrorWithToken({, Instance of 'Template<(Token) => Message>')
+                listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '{'., null, {lexeme: {}], {, {)
+              rewriter()
+              listener: handleIdentifier(, typeReference)
+              listener: handleNoTypeArguments({)
+              listener: handleType(, null)
+              listener: endTypeList(1)
+            listener: handleEnumWithClause(with)
+          parseClassOrMixinOrEnumImplementsOpt()
+            listener: handleImplements(null, 0)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(impl)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(impl, Message[UnexpectedToken, Unexpected token 'impl'., null, {lexeme: impl}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'impl'., null, {lexeme: impl}], impl, impl)
+          parseEnumWithClauseOpt(impl)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(impl)
+            listener: handleIdentifier(Foo, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(Foo, null)
+            listener: handleImplements(implements, 1)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(with)
+          parseEnumWithClauseOpt(E)
+            parseTypeList(with)
+              listener: beginTypeList(Foo)
+              listener: handleIdentifier(Foo, typeReference)
+              listener: handleNoTypeArguments(implements)
+              listener: handleType(Foo, null)
+              listener: endTypeList(1)
+            listener: handleEnumWithClause(with)
+          parseClassOrMixinOrEnumImplementsOpt(Foo)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implements)
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments(with)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Bar, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+            reportRecoverableError(with, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+              listener: handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+            parseEnumWithClauseOpt(Bar)
+              parseTypeList(with)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(gunk1)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(gunk1, Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}], gunk1, gunk1)
+          parseEnumWithClauseOpt(gunk1)
+            parseTypeList(with)
+              listener: beginTypeList(Foo)
+              listener: handleIdentifier(Foo, typeReference)
+              listener: handleNoTypeArguments(gunk2)
+              listener: handleType(Foo, null)
+              listener: endTypeList(1)
+            listener: handleEnumWithClause(with)
+          recoveryEnumWith(Foo, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoverySmallLookAheadSkipTokens(Foo, [{, with, implements])
+            reportRecoverableError(gunk2, Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}], gunk2, gunk2)
+          parseClassOrMixinOrEnumImplementsOpt(gunk2)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments({)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(gunk1)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+            reportRecoverableError(gunk1, Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk1'., null, {lexeme: gunk1}], gunk1, gunk1)
+          parseEnumWithClauseOpt(gunk1)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(gunk1)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments(gunk2)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Bar, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(Bar, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+          recoverySmallLookAheadSkipTokens(Bar, [{, with, implements])
+            reportRecoverableError(gunk2, Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}])
+              listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token 'gunk2'., null, {lexeme: gunk2}], gunk2, gunk2)
+          recoveryEnumWith(gunk2, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+            reportRecoverableError(with, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+              listener: handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+            parseEnumWithClauseOpt(gunk2)
+              parseTypeList(with)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(with)
+          parseEnumWithClauseOpt(E)
+            parseTypeList(with)
+              listener: beginTypeList(Foo)
+              listener: handleIdentifier(Foo, typeReference)
+              listener: handleNoTypeArguments(with)
+              listener: handleType(Foo, null)
+              listener: endTypeList(1)
+            listener: handleEnumWithClause(with)
+          recoveryEnumWith(Foo, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+            reportRecoverableError(with, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+            parseEnumWithClauseOpt(Foo)
+              parseTypeList(with)
+          parseClassOrMixinOrEnumImplementsOpt(Foo2)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments(implements)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Bar, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoveryEnumImplements(Bar, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Bar)
+          recoveryEnumWith(Bar2, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+            reportRecoverableError(with, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+            parseEnumWithClauseOpt(Bar2)
+              parseTypeList(with)
+          recoveryEnumWith(Foo3, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoveryEnumImplements(Foo3, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Foo3)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(implements)
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleIdentifier(Bar, typeReference)
+            listener: handleNoTypeArguments(implements)
+            listener: handleType(Bar, null)
+            listener: handleImplements(implements, 1)
+          recoveryEnumWith(Bar, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(Bar, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Bar)
+          recoveryEnumWith(Bar2, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+            reportRecoverableError(with, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+              listener: handleRecoverableError(Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}], with, with)
+            parseEnumWithClauseOpt(Bar2)
+              parseTypeList(with)
+          recoveryEnumWith(Foo, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+            reportRecoverableError(with, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+            parseEnumWithClauseOpt(Foo)
+              parseTypeList(with)
+          recoveryEnumWith(Foo2, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoveryEnumImplements(Foo2, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+            reportRecoverableError(implements, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}], implements, implements)
+            parseClassOrMixinOrEnumImplementsOpt(Foo2)
+          recoveryEnumWith(Bar3, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+            reportRecoverableError(with, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+              listener: handleRecoverableError(Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}], with, with)
+            parseEnumWithClauseOpt(Bar3)
+              parseTypeList(with)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(v)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(v, enumValueDeclaration)
+          parseConstructorReference(v, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(})
+            listener: beginConstructorReference(v)
+            listener: handleNoTypeArguments(})
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(})
+            listener: endConstructorReference(v, null, }, ConstructorReferenceContext.Const)
+          listener: handleNoArguments(v)
+          listener: handleEnumElement({)
+        listener: handleEnumElements(}, 1)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(enum)
+  listener: endCompilationUnit(15, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.parser.expect
new file mode 100644
index 0000000..ccf057b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.parser.expect
@@ -0,0 +1,135 @@
+NOTICE: Stream was rewritten by parser!
+
+enum E w {
+v
+}
+
+enum E w implements Foo {
+v
+}
+
+enum E implements Foo with Bar {
+v
+}
+
+enum E implements Foo implements Bar implements Bar2 {
+v
+}
+
+enum E w Foo {
+v
+}
+
+enum E implemen {
+v
+}
+
+enum E implements Foo w {
+v
+}
+
+enum E with *synthetic*{
+v
+}
+
+enum E impl implements Foo {
+v
+}
+
+
+enum E with Foo implements Bar {
+v
+}
+
+
+enum E implements Bar with Foo {
+v
+}
+
+
+enum E gunk1 with Foo gunk2 implements Bar {
+v
+}
+
+
+enum E gunk1 implements Bar gunk2 with Foo {
+v
+}
+
+
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+v
+}
+
+
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+v
+}
+
+
+enum[KeywordToken] E[StringToken] w[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] w[StringToken] implements[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] with[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] w[StringToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implemen[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] w[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] [SyntheticStringToken]{[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] impl[StringToken] implements[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] Foo[StringToken] implements[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Bar[StringToken] with[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] gunk1[StringToken] with[KeywordToken] Foo[StringToken] gunk2[StringToken] implements[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] gunk1[StringToken] implements[KeywordToken] Bar[StringToken] gunk2[StringToken] with[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] Foo[StringToken] with[KeywordToken] Foo2[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] with[KeywordToken] Foo3[StringToken] implements[KeywordToken] Bar3[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] with[KeywordToken] Foo[StringToken] with[KeywordToken] Foo2[StringToken] implements[KeywordToken] Bar3[StringToken] with[KeywordToken] Foo3[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.scanner.expect
new file mode 100644
index 0000000..2f0b51f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371.dart.scanner.expect
@@ -0,0 +1,133 @@
+enum E w {
+v
+}
+
+enum E w implements Foo {
+v
+}
+
+enum E implements Foo with Bar {
+v
+}
+
+enum E implements Foo implements Bar implements Bar2 {
+v
+}
+
+enum E w Foo {
+v
+}
+
+enum E implemen {
+v
+}
+
+enum E implements Foo w {
+v
+}
+
+enum E with {
+v
+}
+
+enum E impl implements Foo {
+v
+}
+
+
+enum E with Foo implements Bar {
+v
+}
+
+
+enum E implements Bar with Foo {
+v
+}
+
+
+enum E gunk1 with Foo gunk2 implements Bar {
+v
+}
+
+
+enum E gunk1 implements Bar gunk2 with Foo {
+v
+}
+
+
+enum E with Foo with Foo2 implements Bar implements Bar2 with Foo3 implements Bar3 {
+v
+}
+
+
+enum E implements Bar implements Bar2 with Foo with Foo2 implements Bar3 with Foo3 {
+v
+}
+
+
+enum[KeywordToken] E[StringToken] w[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] w[StringToken] implements[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] with[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] w[StringToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implemen[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Foo[StringToken] w[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken] impl[StringToken] implements[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] Foo[StringToken] implements[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Bar[StringToken] with[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] gunk1[StringToken] with[KeywordToken] Foo[StringToken] gunk2[StringToken] implements[KeywordToken] Bar[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] gunk1[StringToken] implements[KeywordToken] Bar[StringToken] gunk2[StringToken] with[KeywordToken] Foo[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] with[KeywordToken] Foo[StringToken] with[KeywordToken] Foo2[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] with[KeywordToken] Foo3[StringToken] implements[KeywordToken] Bar3[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+
+
+enum[KeywordToken] E[StringToken] implements[KeywordToken] Bar[StringToken] implements[KeywordToken] Bar2[StringToken] with[KeywordToken] Foo[StringToken] with[KeywordToken] Foo2[StringToken] implements[KeywordToken] Bar3[StringToken] with[KeywordToken] Foo3[StringToken] {[BeginToken]
+v[StringToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart
new file mode 100644
index 0000000..3c1a3f0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart
@@ -0,0 +1,3 @@
+library enum;
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect
new file mode 100644
index 0000000..998ca28
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.expect
@@ -0,0 +1,30 @@
+Problems reported:
+
+parser/error_recovery/issue_48371_prime1:1:9: 'enum' can't be used as an identifier because it's a keyword.
+library enum;
+        ^^^^
+
+beginCompilationUnit(library)
+  beginMetadataStar(library)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(library)
+    beginLibraryName(library)
+      handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+      handleIdentifier(enum, libraryName)
+    endLibraryName(library, ;)
+  endTopLevelDeclaration(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(;, null, null)
+      handleNoType(;)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect
new file mode 100644
index 0000000..7fa7ad9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.intertwined.expect
@@ -0,0 +1,50 @@
+parseUnit(library)
+  skipErrorTokens(library)
+  listener: beginCompilationUnit(library)
+  syntheticPreviousToken(library)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(library)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, library, null, Instance of 'DirectiveContext')
+      parseLibraryName(library)
+        listener: beginUncategorizedTopLevelDeclaration(library)
+        listener: beginLibraryName(library)
+        parseQualified(library, libraryName, libraryNameContinuation)
+          ensureIdentifier(library, libraryName)
+            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+              listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+            listener: handleIdentifier(enum, libraryName)
+        ensureSemicolon(enum)
+        listener: endLibraryName(library, ;)
+  listener: endTopLevelDeclaration(main)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(;, null, null, ;, Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(;, null, null)
+        listener: handleNoType(;)
+        ensureIdentifierPotentiallyRecovered(;, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(library)
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.parser.expect
new file mode 100644
index 0000000..b9b70ef
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.parser.expect
@@ -0,0 +1,7 @@
+library enum;
+
+main() {}
+
+library[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.scanner.expect
new file mode 100644
index 0000000..b9b70ef
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime1.dart.scanner.expect
@@ -0,0 +1,7 @@
+library enum;
+
+main() {}
+
+library[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart
new file mode 100644
index 0000000..5292968
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart
@@ -0,0 +1,3 @@
+import "lib.dart" as enum;
+
+main() {}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.expect
new file mode 100644
index 0000000..ed3d9d4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.expect
@@ -0,0 +1,37 @@
+Problems reported:
+
+parser/error_recovery/issue_48371_prime2:1:22: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum;
+                     ^^^^
+
+beginCompilationUnit(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, as)
+      beginConditionalUris(as)
+      endConditionalUris(0)
+      handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+      handleIdentifier(enum, importPrefixDeclaration)
+      handleImportPrefix(null, as)
+      beginCombinators(;)
+      endCombinators(0)
+    endImport(import, ;)
+  endTopLevelDeclaration(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(;, null, null)
+      handleNoType(;)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.intertwined.expect
new file mode 100644
index 0000000..6a0e66a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.intertwined.expect
@@ -0,0 +1,61 @@
+parseUnit(import)
+  skipErrorTokens(import)
+  listener: beginCompilationUnit(import)
+  syntheticPreviousToken(import)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, as)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(as)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          ensureIdentifier(as, importPrefixDeclaration)
+            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+              listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+            listener: handleIdentifier(enum, importPrefixDeclaration)
+          listener: handleImportPrefix(null, as)
+        parseCombinatorStar(enum)
+          listener: beginCombinators(;)
+          listener: endCombinators(0)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(main)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(;, null, null, ;, Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(;, null, null)
+        listener: handleNoType(;)
+        ensureIdentifierPotentiallyRecovered(;, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(import)
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.parser.expect
new file mode 100644
index 0000000..42d3699
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.parser.expect
@@ -0,0 +1,9 @@
+import "lib.dart" as enum;
+
+main() {}
+
+
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.scanner.expect
new file mode 100644
index 0000000..42d3699
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime2.dart.scanner.expect
@@ -0,0 +1,9 @@
+import "lib.dart" as enum;
+
+main() {}
+
+
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart
new file mode 100644
index 0000000..6c44311
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart
@@ -0,0 +1,11 @@
+enum /* about to add an enum here */
+
+class A {
+  void foo(int x) {
+    print(x * 42);
+  }
+} 
+
+enum E /* about to add an enum here */
+
+int f() {}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.expect
new file mode 100644
index 0000000..fcc44cc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.expect
@@ -0,0 +1,111 @@
+Problems reported:
+
+parser/error_recovery/issue_48371_prime3:3:1: Expected an identifier, but got 'class'.
+class A {
+^^^^^
+
+parser/error_recovery/issue_48371_prime3:3:1: Expected a enum body, but got 'class'.
+class A {
+^^^^^
+
+parser/error_recovery/issue_48371_prime3:11:1: Expected a enum body, but got 'int'.
+int f() {}
+^^^
+
+beginCompilationUnit(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'class'., Try inserting an identifier before 'class'., {lexeme: class}], class, class)
+    handleIdentifier(, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(class)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'class'., An enum definition must have a body with at least one constant name., {lexeme: class}], class, class)
+      handleEnumHeader(enum, {)
+      handleEnumElements(, 0)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrMixinOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(A, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, null, null, A)
+      handleNoType(A)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
+        beginMetadataStar(void)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(DeclarationKind.Class, null, null, null, null, null, foo)
+            handleVoidKeyword(void)
+            handleIdentifier(foo, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(int)
+              endMetadataStar(0)
+              beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(x)
+                handleType(int, null)
+                handleIdentifier(x, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              handleIdentifier(print, expression)
+              handleNoTypeArguments(()
+              beginArguments(()
+                handleIdentifier(x, expression)
+                handleNoTypeArguments(*)
+                handleNoArguments(*)
+                handleSend(x, *)
+                beginBinaryExpression(*)
+                  handleLiteralInt(42)
+                endBinaryExpression(*)
+              endArguments(1, (, ))
+              handleSend(print, ;)
+              handleExpressionStatement(;)
+            endBlockFunctionBody(1, {, })
+          endClassMethod(null, void, (, null, })
+        endMember()
+      endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      handleNoTypeVariables(int)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {lexeme: int}], int, int)
+      handleEnumHeader(enum, {)
+      handleEnumElements(E, 0)
+    endEnum(enum, {, 0)
+  endTopLevelDeclaration(int)
+  beginMetadataStar(int)
+  endMetadataStar(0)
+  beginTopLevelMember(int)
+    beginTopLevelMethod(}, null, null)
+      handleIdentifier(int, typeReference)
+      handleNoTypeArguments(f)
+      handleType(int, null)
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(int, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(4, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect
new file mode 100644
index 0000000..a5c120b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.intertwined.expect
@@ -0,0 +1,218 @@
+parseUnit(enum)
+  skipErrorTokens(enum)
+  listener: beginCompilationUnit(enum)
+  syntheticPreviousToken(enum)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          insertSyntheticIdentifier(enum, enumDeclaration, message: Message[ExpectedIdentifier, Expected an identifier, but got 'class'., Try inserting an identifier before 'class'., {lexeme: class}], messageOnToken: null)
+            reportRecoverableError(class, Message[ExpectedIdentifier, Expected an identifier, but got 'class'., Try inserting an identifier before 'class'., {lexeme: class}])
+              listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'class'., Try inserting an identifier before 'class'., {lexeme: class}], class, class)
+            rewriter()
+          listener: handleIdentifier(, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(, enum)
+          listener: handleNoTypeVariables(class)
+          recoverySmallLookAheadSkipTokens(, [{, with, implements])
+          parseEnumWithClauseOpt()
+            listener: handleEnumNoWithClause()
+          recoveryEnumWith(, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoverySmallLookAheadSkipTokens(, [{, with, implements])
+          parseClassOrMixinOrEnumImplementsOpt()
+            listener: handleImplements(null, 0)
+          recoveryEnumWith(, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+          recoverySmallLookAheadSkipTokens(, [{, with, implements])
+        ensureBlock(, Instance of 'Template<(Token) => Message>', null)
+          reportRecoverableError(class, Message[ExpectedEnumBody, Expected a enum body, but got 'class'., An enum definition must have a body with at least one constant name., {lexeme: class}])
+            listener: handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'class'., An enum definition must have a body with at least one constant name., {lexeme: class}], class, class)
+          insertBlock()
+            rewriter()
+            rewriter()
+        listener: handleEnumHeader(enum, {)
+        listener: handleEnumElements(, 0)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(class)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, class, null, Instance of 'DirectiveContext')
+      parseClassOrNamedMixinApplication(null, null, null, class)
+        listener: beginClassOrMixinOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(A, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, null, null, A)
+        parseClass(A, class, class, A)
+          parseClassHeaderOpt(A, class, class)
+            parseClassExtendsOpt(A)
+              listener: handleNoType(A)
+              listener: handleClassExtends(null, 1)
+            parseClassWithClauseOpt(A)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinOrEnumImplementsOpt(A)
+              listener: handleImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(A, DeclarationKind.Class, A)
+            listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
+            notEofOrValue(}, void)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, A)
+              parseMetadataStar({)
+                listener: beginMetadataStar(void)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseMethod({, null, null, null, null, null, null, {, Instance of 'VoidType', null, foo, DeclarationKind.Class, A, false)
+                listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, foo)
+                listener: handleVoidKeyword(void)
+                ensureIdentifierPotentiallyRecovered(void, methodDeclaration, false)
+                  listener: handleIdentifier(foo, methodDeclaration)
+                parseQualifiedRestOpt(foo, methodDeclarationContinuation)
+                parseMethodTypeVar(foo)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(foo, foo, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(foo, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(int)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(x)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(x, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, print)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                        looksLikeLocalFunction(print)
+                        parseExpressionStatement({)
+                          parseExpression({)
+                            parsePrecedenceExpression({, 1, true)
+                              parseUnaryExpression({, true)
+                                parsePrimary({, expression)
+                                  parseSendOrFunctionLiteral({, expression)
+                                    looksLikeFunctionBody(;)
+                                    parseSend({, expression)
+                                      isNextIdentifier({)
+                                      ensureIdentifier({, expression)
+                                        listener: handleIdentifier(print, expression)
+                                      listener: handleNoTypeArguments(()
+                                      parseArgumentsOpt(print)
+                                        parseArguments(print)
+                                          parseArgumentsRest(()
+                                            listener: beginArguments(()
+                                            parseExpression(()
+                                              parsePrecedenceExpression((, 1, true)
+                                                parseUnaryExpression((, true)
+                                                  parsePrimary((, expression)
+                                                    parseSendOrFunctionLiteral((, expression)
+                                                      parseSend((, expression)
+                                                        isNextIdentifier(()
+                                                        ensureIdentifier((, expression)
+                                                          listener: handleIdentifier(x, expression)
+                                                        listener: handleNoTypeArguments(*)
+                                                        parseArgumentsOpt(x)
+                                                          listener: handleNoArguments(*)
+                                                        listener: handleSend(x, *)
+                                                listener: beginBinaryExpression(*)
+                                                parsePrecedenceExpression(*, 15, true)
+                                                  parseUnaryExpression(*, true)
+                                                    parsePrimary(*, expression)
+                                                      parseLiteralInt(*)
+                                                        listener: handleLiteralInt(42)
+                                                listener: endBinaryExpression(*)
+                                            listener: endArguments(1, (, ))
+                                      listener: handleSend(print, ;)
+                          ensureSemicolon())
+                          listener: handleExpressionStatement(;)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(1, {, })
+                listener: endClassMethod(null, void, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(enum)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, enum, null, Instance of 'DirectiveContext')
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: handleNoTypeVariables(int)
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+          parseEnumWithClauseOpt(E)
+            listener: handleEnumNoWithClause()
+          recoveryEnumWith(E, Message[MultipleClauses, Each 'enum' definition can have at most one 'with' clause., Try combining all of the 'with' clauses into a single clause., {string: enum, string2: with}])
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+          parseClassOrMixinOrEnumImplementsOpt(E)
+            listener: handleImplements(null, 0)
+          recoveryEnumWith(E, Message[OutOfOrderClauses, The 'with' clause must come before the 'implements' clause., Try moving the 'with' clause before the 'implements' clause., {string: with, string2: implements}])
+          recoveryEnumImplements(E, Message[MultipleClauses, Each 'enum' definition can have at most one 'implements' clause., Try combining all of the 'implements' clauses into a single clause., {string: enum, string2: implements}])
+          recoverySmallLookAheadSkipTokens(E, [{, with, implements])
+        ensureBlock(E, Instance of 'Template<(Token) => Message>', null)
+          reportRecoverableError(int, Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {lexeme: int}])
+            listener: handleRecoverableError(Message[ExpectedEnumBody, Expected a enum body, but got 'int'., An enum definition must have a body with at least one constant name., {lexeme: int}], int, int)
+          insertBlock(E)
+            rewriter()
+            rewriter()
+        listener: handleEnumHeader(enum, {)
+        listener: handleEnumElements(E, 0)
+        listener: endEnum(enum, {, 0)
+  listener: endTopLevelDeclaration(int)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(int)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(})
+      listener: beginTopLevelMember(int)
+      parseTopLevelMethod(}, null, null, }, Instance of 'SimpleType', null, f, false)
+        listener: beginTopLevelMethod(}, null, null)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(f)
+        listener: handleType(int, null)
+        ensureIdentifierPotentiallyRecovered(int, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(int, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(enum)
+  listener: endCompilationUnit(4, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.parser.expect
new file mode 100644
index 0000000..3866e50b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.parser.expect
@@ -0,0 +1,27 @@
+NOTICE: Stream was rewritten by parser!
+
+enum
+
+*synthetic*{}class A {
+void foo(int x) {
+print(x * 42);
+}
+}
+
+enum E
+
+{}int f() {}
+
+
+enum[KeywordToken]
+
+[SyntheticStringToken]{[SyntheticBeginToken]}[SyntheticToken]class[KeywordToken] A[StringToken] {[BeginToken]
+void[KeywordToken] foo[StringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken] *[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken]
+
+{[SyntheticBeginToken]}[SyntheticToken]int[StringToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.scanner.expect
new file mode 100644
index 0000000..9f59c93
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime3.dart.scanner.expect
@@ -0,0 +1,25 @@
+enum
+
+class A {
+void foo(int x) {
+print(x * 42);
+}
+}
+
+enum E
+
+int f() {}
+
+
+enum[KeywordToken]
+
+class[KeywordToken] A[StringToken] {[BeginToken]
+void[KeywordToken] foo[StringToken]([BeginToken]int[StringToken] x[StringToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken] *[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+
+enum[KeywordToken] E[StringToken]
+
+int[StringToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart
new file mode 100644
index 0000000..970f1dc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart
@@ -0,0 +1,10 @@
+import "lib.dart" show enum;
+import "lib.dart" hide enum;
+import "lib.dart" as enum show enum hide enum;
+import "lib.dart" show enum hide enum as enum;
+import "lib.dart" show enum, x, enum;
+import "lib.dart" hide enum, x, enum;
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+
+main() {}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.expect
new file mode 100644
index 0000000..67258db
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.expect
@@ -0,0 +1,318 @@
+Problems reported:
+
+parser/error_recovery/issue_48371_prime4:1:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:2:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" hide enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:3:22: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum hide enum;
+                     ^^^^
+
+parser/error_recovery/issue_48371_prime4:3:32: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum hide enum;
+                               ^^^^
+
+parser/error_recovery/issue_48371_prime4:3:42: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum hide enum;
+                                         ^^^^
+
+parser/error_recovery/issue_48371_prime4:4:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum hide enum as enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:4:34: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum hide enum as enum;
+                                 ^^^^
+
+parser/error_recovery/issue_48371_prime4:4:42: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum hide enum as enum;
+                                         ^^^^
+
+parser/error_recovery/issue_48371_prime4:4:39: The prefix ('as' clause) should come before any show/hide combinators.
+import "lib.dart" show enum hide enum as enum;
+                                      ^^
+
+parser/error_recovery/issue_48371_prime4:5:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:5:33: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum;
+                                ^^^^
+
+parser/error_recovery/issue_48371_prime4:6:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" hide enum, x, enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:6:33: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" hide enum, x, enum;
+                                ^^^^
+
+parser/error_recovery/issue_48371_prime4:7:22: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+                     ^^^^
+
+parser/error_recovery/issue_48371_prime4:7:32: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+                               ^^^^
+
+parser/error_recovery/issue_48371_prime4:7:41: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+                                        ^^^^
+
+parser/error_recovery/issue_48371_prime4:7:51: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+                                                  ^^^^
+
+parser/error_recovery/issue_48371_prime4:7:60: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+                                                           ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:24: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                       ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:33: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                                ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:43: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                                          ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:52: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                                                   ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:60: 'enum' can't be used as an identifier because it's a keyword.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                                                           ^^^^
+
+parser/error_recovery/issue_48371_prime4:8:57: The prefix ('as' clause) should come before any show/hide combinators.
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+                                                        ^^
+
+beginCompilationUnit(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, show)
+      beginConditionalUris(show)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endShow(show)
+      endCombinators(1)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, hide)
+      beginConditionalUris(hide)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(hide)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endHide(hide)
+      endCombinators(1)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, as)
+      beginConditionalUris(as)
+      endConditionalUris(0)
+      handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+      handleIdentifier(enum, importPrefixDeclaration)
+      handleImportPrefix(null, as)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endShow(show)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endHide(hide)
+      endCombinators(2)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, show)
+      beginConditionalUris(show)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endShow(show)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(1)
+        endHide(hide)
+      endCombinators(2)
+    endImport(import, null)
+    beginConditionalUris(as)
+    endConditionalUris(0)
+    handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+    handleIdentifier(enum, importPrefixDeclaration)
+    handleImportPrefix(null, as)
+    handleRecoverableError(PrefixAfterCombinator, as, as)
+    beginCombinators(;)
+    endCombinators(0)
+    handleRecoverImport(;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, show)
+      beginConditionalUris(show)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endShow(show)
+      endCombinators(1)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, hide)
+      beginConditionalUris(hide)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(hide)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endHide(hide)
+      endCombinators(1)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, as)
+      beginConditionalUris(as)
+      endConditionalUris(0)
+      handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+      handleIdentifier(enum, importPrefixDeclaration)
+      handleImportPrefix(null, as)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endShow(show)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endHide(hide)
+      endCombinators(2)
+    endImport(import, ;)
+  endTopLevelDeclaration(import)
+  beginMetadataStar(import)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(import)
+    beginImport(import)
+      beginLiteralString("lib.dart")
+      endLiteralString(0, show)
+      beginConditionalUris(show)
+      endConditionalUris(0)
+      handleImportPrefix(null, null)
+      beginCombinators(show)
+        beginShow(show)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endShow(show)
+        beginHide(hide)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifier(x, combinator)
+          handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+          handleIdentifier(enum, combinator)
+          handleIdentifierList(3)
+        endHide(hide)
+      endCombinators(2)
+    endImport(import, null)
+    beginConditionalUris(as)
+    endConditionalUris(0)
+    handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+    handleIdentifier(enum, importPrefixDeclaration)
+    handleImportPrefix(null, as)
+    handleRecoverableError(PrefixAfterCombinator, as, as)
+    beginCombinators(;)
+    endCombinators(0)
+    handleRecoverImport(;)
+  endTopLevelDeclaration(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(;, null, null)
+      handleNoType(;)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(9, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.intertwined.expect
new file mode 100644
index 0000000..f5536b4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.intertwined.expect
@@ -0,0 +1,432 @@
+parseUnit(import)
+  skipErrorTokens(import)
+  listener: beginCompilationUnit(import)
+  syntheticPreviousToken(import)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, show)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(show)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(show)
+          parseShow("lib.dart")
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endShow(show)
+          listener: endCombinators(1)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, hide)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(hide)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(hide)
+          parseHide("lib.dart")
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endHide(hide)
+          listener: endCombinators(1)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, as)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(as)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          ensureIdentifier(as, importPrefixDeclaration)
+            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+              listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+            listener: handleIdentifier(enum, importPrefixDeclaration)
+          listener: handleImportPrefix(null, as)
+        parseCombinatorStar(enum)
+          listener: beginCombinators(show)
+          parseShow(enum)
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endShow(show)
+          parseHide(enum)
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endHide(hide)
+          listener: endCombinators(2)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, show)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(show)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(show)
+          parseShow("lib.dart")
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endShow(show)
+          parseHide(enum)
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(1)
+            listener: endHide(hide)
+          listener: endCombinators(2)
+        listener: endImport(import, null)
+        parseImportRecovery("lib.dart")
+          parseConditionalUriStar("lib.dart")
+          parseImportPrefixOpt("lib.dart")
+          parseCombinatorStar("lib.dart")
+            parseShow("lib.dart")
+              parseIdentifierList(show)
+                ensureIdentifier(show, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+            parseHide(enum)
+              parseIdentifierList(hide)
+                ensureIdentifier(hide, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+          skipUnexpectedTokenOpt(enum, [if, deferred, as, hide, show, ;])
+          parseConditionalUriStar(enum)
+            listener: beginConditionalUris(as)
+            listener: endConditionalUris(0)
+          parseImportPrefixOpt(enum)
+            ensureIdentifier(as, importPrefixDeclaration)
+              reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+              listener: handleIdentifier(enum, importPrefixDeclaration)
+            listener: handleImportPrefix(null, as)
+          reportRecoverableError(as, PrefixAfterCombinator)
+            listener: handleRecoverableError(PrefixAfterCombinator, as, as)
+          parseCombinatorStar(enum)
+            listener: beginCombinators(;)
+            listener: endCombinators(0)
+          listener: handleRecoverImport(;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, show)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(show)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(show)
+          parseShow("lib.dart")
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endShow(show)
+          listener: endCombinators(1)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, hide)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(hide)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(hide)
+          parseHide("lib.dart")
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endHide(hide)
+          listener: endCombinators(1)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, as)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(as)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          ensureIdentifier(as, importPrefixDeclaration)
+            reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+              listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+            listener: handleIdentifier(enum, importPrefixDeclaration)
+          listener: handleImportPrefix(null, as)
+        parseCombinatorStar(enum)
+          listener: beginCombinators(show)
+          parseShow(enum)
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endShow(show)
+          parseHide(enum)
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endHide(hide)
+          listener: endCombinators(2)
+        listener: endImport(import, ;)
+  listener: endTopLevelDeclaration(import)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(import)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, import, null, Instance of 'DirectiveContext')
+      parseImport(import)
+        listener: beginUncategorizedTopLevelDeclaration(import)
+        listener: beginImport(import)
+        ensureLiteralString(import)
+          parseLiteralString(import)
+            parseSingleLiteralString(import)
+              listener: beginLiteralString("lib.dart")
+              listener: endLiteralString(0, show)
+        parseConditionalUriStar("lib.dart")
+          listener: beginConditionalUris(show)
+          listener: endConditionalUris(0)
+        parseImportPrefixOpt("lib.dart")
+          listener: handleImportPrefix(null, null)
+        parseCombinatorStar("lib.dart")
+          listener: beginCombinators(show)
+          parseShow("lib.dart")
+            listener: beginShow(show)
+            parseIdentifierList(show)
+              ensureIdentifier(show, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endShow(show)
+          parseHide(enum)
+            listener: beginHide(hide)
+            parseIdentifierList(hide)
+              ensureIdentifier(hide, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              ensureIdentifier(,, combinator)
+                listener: handleIdentifier(x, combinator)
+              ensureIdentifier(,, combinator)
+                reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                  listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+                listener: handleIdentifier(enum, combinator)
+              listener: handleIdentifierList(3)
+            listener: endHide(hide)
+          listener: endCombinators(2)
+        listener: endImport(import, null)
+        parseImportRecovery("lib.dart")
+          parseConditionalUriStar("lib.dart")
+          parseImportPrefixOpt("lib.dart")
+          parseCombinatorStar("lib.dart")
+            parseShow("lib.dart")
+              parseIdentifierList(show)
+                ensureIdentifier(show, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                ensureIdentifier(,, combinator)
+                ensureIdentifier(,, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+            parseHide(enum)
+              parseIdentifierList(hide)
+                ensureIdentifier(hide, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                ensureIdentifier(,, combinator)
+                ensureIdentifier(,, combinator)
+                  reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+          skipUnexpectedTokenOpt(enum, [if, deferred, as, hide, show, ;])
+          parseConditionalUriStar(enum)
+            listener: beginConditionalUris(as)
+            listener: endConditionalUris(0)
+          parseImportPrefixOpt(enum)
+            ensureIdentifier(as, importPrefixDeclaration)
+              reportRecoverableErrorWithToken(enum, Instance of 'Template<(Token) => Message>')
+                listener: handleRecoverableError(Message[ExpectedIdentifierButGotKeyword, 'enum' can't be used as an identifier because it's a keyword., Try renaming this to be an identifier that isn't a keyword., {lexeme: enum}], enum, enum)
+              listener: handleIdentifier(enum, importPrefixDeclaration)
+            listener: handleImportPrefix(null, as)
+          reportRecoverableError(as, PrefixAfterCombinator)
+            listener: handleRecoverableError(PrefixAfterCombinator, as, as)
+          parseCombinatorStar(enum)
+            listener: beginCombinators(;)
+            listener: endCombinators(0)
+          listener: handleRecoverImport(;)
+  listener: endTopLevelDeclaration(main)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(;, null, null, ;, Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(;, null, null)
+        listener: handleNoType(;)
+        ensureIdentifierPotentiallyRecovered(;, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(0, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(import)
+  listener: endCompilationUnit(9, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.parser.expect
new file mode 100644
index 0000000..79afafe
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.parser.expect
@@ -0,0 +1,23 @@
+import "lib.dart" show enum;
+import "lib.dart" hide enum;
+import "lib.dart" as enum show enum hide enum;
+import "lib.dart" show enum hide enum as enum;
+import "lib.dart" show enum, x, enum;
+import "lib.dart" hide enum, x, enum;
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+
+main() {}
+
+
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] hide[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken] show[KeywordToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.scanner.expect
new file mode 100644
index 0000000..79afafe
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_48371_prime4.dart.scanner.expect
@@ -0,0 +1,23 @@
+import "lib.dart" show enum;
+import "lib.dart" hide enum;
+import "lib.dart" as enum show enum hide enum;
+import "lib.dart" show enum hide enum as enum;
+import "lib.dart" show enum, x, enum;
+import "lib.dart" hide enum, x, enum;
+import "lib.dart" as enum show enum, x, enum hide enum, x, enum;
+import "lib.dart" show enum, x, enum hide enum, x, enum as enum;
+
+main() {}
+
+
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] hide[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken] show[KeywordToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] as[KeywordToken] enum[KeywordToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken];[SimpleToken]
+import[KeywordToken] "lib.dart"[StringToken] show[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] hide[KeywordToken] enum[KeywordToken],[SimpleToken] x[StringToken],[SimpleToken] enum[KeywordToken] as[KeywordToken] enum[KeywordToken];[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
index 0e5c582..7277cfb 100644
--- a/pkg/front_end/test/parser_test_parser.dart
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -547,6 +547,34 @@
   }
 
   @override
+  Token? recoveryEnumWith(Token token, codes.Message message) {
+    doPrint('recoveryEnumWith(' '$token, ' '$message)');
+    indent++;
+    var result = super.recoveryEnumWith(token, message);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token? recoveryEnumImplements(Token token, codes.Message message) {
+    doPrint('recoveryEnumImplements(' '$token, ' '$message)');
+    indent++;
+    var result = super.recoveryEnumImplements(token, message);
+    indent--;
+    return result;
+  }
+
+  @override
+  Token? recoverySmallLookAheadSkipTokens(
+      final Token token, Iterable<String> lookFor) {
+    doPrint('recoverySmallLookAheadSkipTokens(' '$token, ' '$lookFor)');
+    indent++;
+    var result = super.recoverySmallLookAheadSkipTokens(token, lookFor);
+    indent--;
+    return result;
+  }
+
+  @override
   Token parseEnumElement(Token token) {
     doPrint('parseEnumElement(' '$token)');
     indent++;
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index ce825bb..e4445e6 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -719,6 +719,7 @@
 locationd
 logged
 logically
+lookahead
 lots
 lp
 lparen
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 1714002..7313d71 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -334,6 +334,7 @@
 illustrate
 image
 images
+implemen
 implementor
 implementors
 imprecision