// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library fasta.parser.parser;

import '../scanner.dart' show ErrorToken;

import '../scanner/recover.dart' show closeBraceFor, skipToEof;

import '../scanner/keyword.dart' show Keyword;

import '../scanner/precedence.dart'
    show
        ASSIGNMENT_PRECEDENCE,
        AS_INFO,
        CASCADE_PRECEDENCE,
        EQUALITY_PRECEDENCE,
        GT_INFO,
        IS_INFO,
        MINUS_MINUS_INFO,
        OPEN_PAREN_INFO,
        OPEN_SQUARE_BRACKET_INFO,
        PERIOD_INFO,
        PLUS_PLUS_INFO,
        POSTFIX_PRECEDENCE,
        PrecedenceInfo,
        QUESTION_INFO,
        QUESTION_PERIOD_INFO,
        RELATIONAL_PRECEDENCE,
        SCRIPT_INFO;

import '../scanner/token.dart'
    show
        BeginGroupToken,
        KeywordToken,
        SymbolToken,
        Token,
        isUserDefinableOperator;

import '../scanner/token_constants.dart'
    show
        COMMA_TOKEN,
        DOUBLE_TOKEN,
        EOF_TOKEN,
        EQ_TOKEN,
        FUNCTION_TOKEN,
        GT_TOKEN,
        GT_GT_TOKEN,
        HASH_TOKEN,
        HEXADECIMAL_TOKEN,
        IDENTIFIER_TOKEN,
        INT_TOKEN,
        KEYWORD_TOKEN,
        LT_TOKEN,
        OPEN_CURLY_BRACKET_TOKEN,
        OPEN_PAREN_TOKEN,
        OPEN_SQUARE_BRACKET_TOKEN,
        PERIOD_TOKEN,
        SEMICOLON_TOKEN,
        STRING_INTERPOLATION_IDENTIFIER_TOKEN,
        STRING_INTERPOLATION_TOKEN,
        STRING_TOKEN;

import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET;

import '../util/link.dart' show Link;

import 'listener.dart' show Listener;

import 'error_kind.dart' show ErrorKind;

import 'identifier_context.dart' show IdentifierContext;

/// Returns true if [token] is the symbol or keyword [value].
bool optional(String value, Token token) {
  return identical(value, token.stringValue);
}

class FormalParameterType {
  final String type;
  const FormalParameterType(this.type);
  bool get isRequired => this == REQUIRED;
  bool get isPositional => this == POSITIONAL;
  bool get isNamed => this == NAMED;
  static final REQUIRED = const FormalParameterType('required');
  static final POSITIONAL = const FormalParameterType('positional');
  static final NAMED = const FormalParameterType('named');
}

/**
 * An event generating parser of Dart programs. This parser expects
 * all tokens in a linked list (aka a token stream).
 *
 * The class [Scanner] is used to generate a token stream. See the
 * file scanner.dart.
 *
 * Subclasses of the class [Listener] are used to listen to events.
 *
 * Most methods of this class belong in one of two major categories:
 * parse methods and peek methods. Parse methods all have the prefix
 * parse, and peek methods all have the prefix peek.
 *
 * Parse methods generate events (by calling methods on [listener])
 * and return the next token to parse. Peek methods do not generate
 * events (except for errors) and may return null.
 *
 * Parse methods are generally named parseGrammarProductionSuffix. The
 * suffix can be one of "opt", or "star". "opt" means zero or one
 * matches, "star" means zero or more matches. For example,
 * [parseMetadataStar] corresponds to this grammar snippet: [:
 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :].
 */
class Parser {
  final Listener listener;

  bool mayParseFunctionExpressions = true;

  bool asyncAwaitKeywordsEnabled;

  Parser(this.listener, {this.asyncAwaitKeywordsEnabled: false});

  Token parseUnit(Token token) {
    listener.beginCompilationUnit(token);
    int count = 0;
    while (!identical(token.kind, EOF_TOKEN)) {
      token = parseTopLevelDeclaration(token);
      count++;
    }
    listener.endCompilationUnit(count, token);
    return token;
  }

  Token parseTopLevelDeclaration(Token token) {
    token = _parseTopLevelDeclaration(token);
    listener.endTopLevelDeclaration(token);
    return token;
  }

  Token _parseTopLevelDeclaration(Token token) {
    if (identical(token.info, SCRIPT_INFO)) {
      return parseScript(token);
    }
    token = parseMetadataStar(token);
    final String value = token.stringValue;
    if ((identical(value, 'abstract') && optional('class', token.next)) ||
        identical(value, 'class')) {
      return parseClassOrNamedMixinApplication(token);
    } else if (identical(value, 'enum')) {
      return parseEnum(token);
    } else if (identical(value, 'typedef')) {
      return parseTypedef(token);
    } else if (identical(value, 'library')) {
      return parseLibraryName(token);
    } else if (identical(value, 'import')) {
      return parseImport(token);
    } else if (identical(value, 'export')) {
      return parseExport(token);
    } else if (identical(value, 'part')) {
      return parsePartOrPartOf(token);
    } else {
      return parseTopLevelMember(token);
    }
  }

  /// library qualified ';'
  Token parseLibraryName(Token token) {
    Token libraryKeyword = token;
    listener.beginLibraryName(libraryKeyword);
    assert(optional('library', token));
    token = parseQualified(token.next, IdentifierContext.libraryName,
        IdentifierContext.libraryNameContinuation);
    Token semicolon = token;
    token = expect(';', token);
    listener.endLibraryName(libraryKeyword, semicolon);
    return token;
  }

  /// import uri (if (test) uri)* (as identifier)? combinator* ';'
  Token parseImport(Token token) {
    Token importKeyword = token;
    listener.beginImport(importKeyword);
    assert(optional('import', token));
    token = parseLiteralStringOrRecoverExpression(token.next);
    token = parseConditionalUris(token);
    Token deferredKeyword;
    if (optional('deferred', token)) {
      deferredKeyword = token;
      token = token.next;
    }
    Token asKeyword;
    if (optional('as', token)) {
      asKeyword = token;
      token = parseIdentifier(
          token.next, IdentifierContext.importPrefixDeclaration);
    }
    token = parseCombinators(token);
    Token semicolon = token;
    token = expect(';', token);
    listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon);
    return token;
  }

  /// if (test) uri
  Token parseConditionalUris(Token token) {
    listener.beginConditionalUris(token);
    int count = 0;
    while (optional('if', token)) {
      count++;
      token = parseConditionalUri(token);
    }
    listener.endConditionalUris(count);
    return token;
  }

  Token parseConditionalUri(Token token) {
    listener.beginConditionalUri(token);
    Token ifKeyword = token;
    token = expect('if', token);
    token = expect('(', token);
    token = parseDottedName(token);
    Token equalitySign;
    if (optional('==', token)) {
      equalitySign = token;
      token = parseLiteralStringOrRecoverExpression(token.next);
    }
    token = expect(')', token);
    token = parseLiteralStringOrRecoverExpression(token);
    listener.endConditionalUri(ifKeyword, equalitySign);
    return token;
  }

  Token parseDottedName(Token token) {
    listener.beginDottedName(token);
    Token firstIdentifier = token;
    token = parseIdentifier(token, IdentifierContext.dottedName);
    int count = 1;
    while (optional('.', token)) {
      token =
          parseIdentifier(token.next, IdentifierContext.dottedNameContinuation);
      count++;
    }
    listener.endDottedName(count, firstIdentifier);
    return token;
  }

  /// export uri conditional-uris* combinator* ';'
  Token parseExport(Token token) {
    Token exportKeyword = token;
    listener.beginExport(exportKeyword);
    assert(optional('export', token));
    token = parseLiteralStringOrRecoverExpression(token.next);
    token = parseConditionalUris(token);
    token = parseCombinators(token);
    Token semicolon = token;
    token = expect(';', token);
    listener.endExport(exportKeyword, semicolon);
    return token;
  }

  Token parseCombinators(Token token) {
    listener.beginCombinators(token);
    int count = 0;
    while (true) {
      String value = token.stringValue;
      if (identical('hide', value)) {
        token = parseHide(token);
      } else if (identical('show', value)) {
        token = parseShow(token);
      } else {
        listener.endCombinators(count);
        break;
      }
      count++;
    }
    return token;
  }

  /// hide identifierList
  Token parseHide(Token token) {
    Token hideKeyword = token;
    listener.beginHide(hideKeyword);
    assert(optional('hide', token));
    token = parseIdentifierList(token.next);
    listener.endHide(hideKeyword);
    return token;
  }

  /// show identifierList
  Token parseShow(Token token) {
    Token showKeyword = token;
    listener.beginShow(showKeyword);
    assert(optional('show', token));
    token = parseIdentifierList(token.next);
    listener.endShow(showKeyword);
    return token;
  }

  /// identifier (, identifier)*
  Token parseIdentifierList(Token token) {
    listener.beginIdentifierList(token);
    token = parseIdentifier(token, IdentifierContext.combinator);
    int count = 1;
    while (optional(',', token)) {
      token = parseIdentifier(token.next, IdentifierContext.combinator);
      count++;
    }
    listener.endIdentifierList(count);
    return token;
  }

  /// type (, type)*
  Token parseTypeList(Token token) {
    listener.beginTypeList(token);
    token = parseType(token);
    int count = 1;
    while (optional(',', token)) {
      token = parseType(token.next);
      count++;
    }
    listener.endTypeList(count);
    return token;
  }

  Token parsePartOrPartOf(Token token) {
    assert(optional('part', token));
    if (optional('of', token.next)) {
      return parsePartOf(token);
    } else {
      return parsePart(token);
    }
  }

  Token parsePart(Token token) {
    Token partKeyword = token;
    listener.beginPart(token);
    assert(optional('part', token));
    token = parseLiteralStringOrRecoverExpression(token.next);
    Token semicolon = token;
    token = expect(';', token);
    listener.endPart(partKeyword, semicolon);
    return token;
  }

  Token parsePartOf(Token token) {
    listener.beginPartOf(token);
    assert(optional('part', token));
    assert(optional('of', token.next));
    Token partKeyword = token;
    token = token.next.next;
    bool hasName = token.isIdentifier();
    if (hasName) {
      token = parseQualified(token, IdentifierContext.partName,
          IdentifierContext.partNameContinuation);
    } else {
      token = parseLiteralStringOrRecoverExpression(token);
    }
    Token semicolon = token;
    token = expect(';', token);
    listener.endPartOf(partKeyword, semicolon, hasName);
    return token;
  }

  Token parseMetadataStar(Token token, {bool forParameter: false}) {
    listener.beginMetadataStar(token);
    int count = 0;
    while (optional('@', token)) {
      token = parseMetadata(token);
      count++;
    }
    listener.endMetadataStar(count, forParameter);
    return token;
  }

  /**
   * Parse
   * [: '@' qualified (‘.’ identifier)? (arguments)? :]
   */
  Token parseMetadata(Token token) {
    listener.beginMetadata(token);
    Token atToken = token;
    assert(optional('@', token));
    token = parseIdentifier(token.next, IdentifierContext.metadataReference);
    token =
        parseQualifiedRestOpt(token, IdentifierContext.metadataContinuation);
    token = parseTypeArgumentsOpt(token);
    Token period = null;
    if (optional('.', token)) {
      period = token;
      token = parseIdentifier(
          token.next, IdentifierContext.metadataContinuationAfterTypeArguments);
    }
    token = parseArgumentsOpt(token);
    listener.endMetadata(atToken, period, token);
    return token;
  }

  Token parseScript(Token token) {
    listener.handleScript(token);
    return token.next;
  }

  Token parseTypedef(Token token) {
    Token typedefKeyword = token;
    listener.beginFunctionTypeAlias(token);
    Token equals;
    if (optional('=', peekAfterNominalType(token.next))) {
      token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration);
      token = parseTypeVariablesOpt(token);
      equals = token;
      token = expect('=', token);
      token = parseType(token);
    } else {
      token = parseReturnTypeOpt(token.next);
      token = parseIdentifier(token, IdentifierContext.typedefDeclaration);
      token = parseTypeVariablesOpt(token);
      token = parseFormalParameters(token);
    }
    listener.endFunctionTypeAlias(typedefKeyword, equals, token);
    return expect(';', token);
  }

  Token parseMixinApplication(Token token) {
    listener.beginMixinApplication(token);
    token = parseType(token);
    Token withKeyword = token;
    token = expect('with', token);
    token = parseTypeList(token);
    listener.endMixinApplication(withKeyword);
    return token;
  }

  Token parseReturnTypeOpt(Token token) {
    if (identical(token.stringValue, 'void')) {
      if (isGeneralizedFunctionType(token.next)) {
        return parseType(token);
      } else {
        listener.handleVoidKeyword(token);
        return token.next;
      }
    } else {
      return parseTypeOpt(token);
    }
  }

  Token parseFormalParametersOpt(Token token) {
    if (optional('(', token)) {
      return parseFormalParameters(token);
    } else {
      listener.handleNoFormalParameters(token);
      return token;
    }
  }

  Token skipFormalParameters(Token token) {
    // TODO(ahe): Shouldn't this be `beginFormalParameters`?
    listener.beginOptionalFormalParameters(token);
    if (!optional('(', token)) {
      if (optional(';', token)) {
        reportRecoverableError(token, ErrorKind.ExpectedOpenParens);
        return token;
      }
      return reportUnrecoverableError(
          token, ErrorKind.ExpectedButGot, {"expected": "("})?.next;
    }
    BeginGroupToken beginGroupToken = token;
    Token endToken = beginGroupToken.endGroup;
    listener.endFormalParameters(0, token, endToken);
    return endToken.next;
  }

  /// Parses the formal parameter list of a function.
  ///
  /// If [inFunctionType] is true, then the names may be omitted (except for
  /// named arguments). If it is false, then the types may be omitted.
  Token parseFormalParameters(Token token, {bool inFunctionType: false}) {
    Token begin = token;
    listener.beginFormalParameters(begin);
    expect('(', token);
    int parameterCount = 0;
    do {
      token = token.next;
      if (optional(')', token)) {
        break;
      }
      ++parameterCount;
      String value = token.stringValue;
      if (identical(value, '[')) {
        token = parseOptionalFormalParameters(token, false,
            inFunctionType: inFunctionType);
        break;
      } else if (identical(value, '{')) {
        token = parseOptionalFormalParameters(token, true,
            inFunctionType: inFunctionType);
        break;
      } else if (identical(value, '[]')) {
        --parameterCount;
        reportRecoverableError(token, ErrorKind.EmptyOptionalParameterList);
        token = token.next;
        break;
      }
      token = parseFormalParameter(token, FormalParameterType.REQUIRED,
          inFunctionType: inFunctionType);
    } while (optional(',', token));
    listener.endFormalParameters(parameterCount, begin, token);
    return expect(')', token);
  }

  Token parseFormalParameter(Token token, FormalParameterType kind,
      {bool inFunctionType: false}) {
    token = parseMetadataStar(token, forParameter: true);
    listener.beginFormalParameter(token);

    // Skip over `covariant` token, if the next token is an identifier or
    // modifier.
    // This enables the case where `covariant` is the name of the parameter:
    //    void foo(covariant);
    Token covariantKeyword;
    if (identical(token.stringValue, 'covariant') &&
        (token.next.isIdentifier() || isModifier(token.next))) {
      covariantKeyword = token;
      token = token.next;
    }
    token = parseModifiers(token);
    bool isNamedParameter = kind == FormalParameterType.NAMED;

    Token thisKeyword = null;
    if (inFunctionType && isNamedParameter) {
      token = parseType(token);
      token =
          parseIdentifier(token, IdentifierContext.formalParameterDeclaration);
    } else if (inFunctionType) {
      token = parseType(token);
      if (token.isIdentifier()) {
        token = parseIdentifier(
            token, IdentifierContext.formalParameterDeclaration);
      } else {
        listener.handleNoName(token);
      }
    } else {
      token = parseReturnTypeOpt(token);
      if (optional('this', token)) {
        thisKeyword = token;
        token = expect('.', token.next);
        token = parseIdentifier(token, IdentifierContext.fieldInitializer);
      } else {
        token = parseIdentifier(
            token, IdentifierContext.formalParameterDeclaration);
      }
    }

    if (optional('(', token)) {
      Token inlineFunctionTypeStart = token;
      listener.beginFunctionTypedFormalParameter(token);
      listener.handleNoTypeVariables(token);
      token = parseFormalParameters(token);
      listener.endFunctionTypedFormalParameter(
          covariantKeyword, thisKeyword, kind);
      // Generalized function types don't allow inline function types.
      // The following isn't allowed:
      //    int Function(int bar(String x)).
      if (inFunctionType) {
        reportRecoverableError(
            inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType);
      }
    } else if (optional('<', token)) {
      Token inlineFunctionTypeStart = token;
      listener.beginFunctionTypedFormalParameter(token);
      token = parseTypeVariablesOpt(token);
      token = parseFormalParameters(token);
      listener.endFunctionTypedFormalParameter(
          covariantKeyword, thisKeyword, kind);
      // Generalized function types don't allow inline function types.
      // The following isn't allowed:
      //    int Function(int bar(String x)).
      if (inFunctionType) {
        reportRecoverableError(
            inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType);
      }
    }
    String value = token.stringValue;
    if ((identical('=', value)) || (identical(':', value))) {
      // TODO(ahe): Validate that these are only used for optional parameters.
      Token equal = token;
      token = parseExpression(token.next);
      listener.handleValuedFormalParameter(equal, token);
      if (kind.isRequired) {
        reportRecoverableError(equal, ErrorKind.RequiredParameterWithDefault);
      } else if (kind.isPositional && identical(':', value)) {
        reportRecoverableError(equal, ErrorKind.PositionalParameterWithEquals);
      }
    } else {
      listener.handleFormalParameterWithoutValue(token);
    }
    listener.endFormalParameter(covariantKeyword, thisKeyword, kind);
    return token;
  }

  Token parseOptionalFormalParameters(Token token, bool isNamed,
      {bool inFunctionType: false}) {
    Token begin = token;
    listener.beginOptionalFormalParameters(begin);
    assert((isNamed && optional('{', token)) || optional('[', token));
    int parameterCount = 0;
    do {
      token = token.next;
      if (isNamed && optional('}', token)) {
        break;
      } else if (!isNamed && optional(']', token)) {
        break;
      }
      var type =
          isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
      token = parseFormalParameter(token, type, inFunctionType: inFunctionType);
      ++parameterCount;
    } while (optional(',', token));
    if (parameterCount == 0) {
      reportRecoverableError(
          token,
          isNamed
              ? ErrorKind.EmptyNamedParameterList
              : ErrorKind.EmptyOptionalParameterList);
    }
    listener.endOptionalFormalParameters(parameterCount, begin, token);
    if (isNamed) {
      return expect('}', token);
    } else {
      return expect(']', token);
    }
  }

  Token parseTypeOpt(Token token) {
    if (isGeneralizedFunctionType(token)) {
      // Function type without return type.
      return parseType(token);
    }
    Token peek = peekAfterIfType(token);
    if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
      return parseType(token);
    }
    listener.handleNoType(token);
    return token;
  }

  bool isValidTypeReference(Token token) {
    final kind = token.kind;
    if (identical(kind, IDENTIFIER_TOKEN)) return true;
    if (identical(kind, KEYWORD_TOKEN)) {
      Keyword keyword = (token as KeywordToken).keyword;
      String value = keyword.syntax;
      return keyword.isPseudo ||
          (identical(value, 'dynamic')) ||
          (identical(value, 'void'));
    }
    return false;
  }

  /// Returns true if [token] matches '<' type (',' type)* '>' '(', and
  /// otherwise returns false. The final '(' is not part of the grammar
  /// construct `typeArguments`, but it is required here such that type
  /// arguments in generic method invocations can be recognized, and as few as
  /// possible other constructs will pass (e.g., 'a < C, D > 3').
  bool isValidMethodTypeArguments(Token token) {
    return tryParseMethodTypeArguments(token) != null;
  }

  /// Returns token after match if [token] matches '<' type (',' type)* '>' '(',
  /// and otherwise returns null. Does not produce listener events. With respect
  /// to the final '(', please see the description of
  /// [isValidMethodTypeArguments].
  Token tryParseMethodTypeArguments(Token token) {
    if (!identical(token.kind, LT_TOKEN)) return null;
    BeginGroupToken beginToken = token;
    Token endToken = beginToken.endGroup;
    if (endToken == null || !identical(endToken.next.kind, OPEN_PAREN_TOKEN)) {
      return null;
    }
    token = tryParseType(token.next);
    while (token != null && identical(token.kind, COMMA_TOKEN)) {
      token = tryParseType(token.next);
    }
    if (token == null || !identical(token.kind, GT_TOKEN)) return null;
    return token.next;
  }

  /// Returns token after match if [token] matches typeName typeArguments?, and
  /// otherwise returns null. Does not produce listener events.
  Token tryParseType(Token token) {
    token = tryParseQualified(token);
    if (token == null) return null;
    Token tokenAfterQualified = token;
    token = tryParseNestedTypeArguments(token);
    return token == null ? tokenAfterQualified : token;
  }

  /// Returns token after match if [token] matches identifier ('.' identifier)?,
  /// and otherwise returns null. Does not produce listener events.
  Token tryParseQualified(Token token) {
    if (!isValidTypeReference(token)) return null;
    token = token.next;
    if (!identical(token.kind, PERIOD_TOKEN)) return token;
    token = token.next;
    if (!identical(token.kind, IDENTIFIER_TOKEN)) return null;
    return token.next;
  }

  /// Returns token after match if [token] matches '<' type (',' type)* '>',
  /// and otherwise returns null. Does not produce listener events. The final
  /// '>' may be the first character in a '>>' token, in which case a synthetic
  /// '>' token is created and returned, representing the second '>' in the
  /// '>>' token.
  Token tryParseNestedTypeArguments(Token token) {
    if (!identical(token.kind, LT_TOKEN)) return null;
    // If the initial '<' matches the first '>' in a '>>' token, we will have
    // `token.endGroup == null`, so we cannot rely on `token.endGroup == null`
    // to imply that the match must fail. Hence no `token.endGroup == null`
    // test here.
    token = tryParseType(token.next);
    while (token != null && identical(token.kind, COMMA_TOKEN)) {
      token = tryParseType(token.next);
    }
    if (token == null) return null;
    if (identical(token.kind, GT_TOKEN)) return token.next;
    if (!identical(token.kind, GT_GT_TOKEN)) return null;
    // [token] is '>>' of which the final '>' that we are parsing is the first
    // character. In order to keep the parsing process on track we must return
    // a synthetic '>' corresponding to the second character of that '>>'.
    Token syntheticToken = new SymbolToken(GT_INFO, token.charOffset + 1);
    syntheticToken.next = token.next;
    return syntheticToken;
  }

  Token parseQualified(Token token, IdentifierContext context,
      IdentifierContext continuationContext) {
    token = parseIdentifier(token, context);
    while (optional('.', token)) {
      token = parseQualifiedRest(token, continuationContext);
    }
    return token;
  }

  Token parseQualifiedRestOpt(
      Token token, IdentifierContext continuationContext) {
    if (optional('.', token)) {
      return parseQualifiedRest(token, continuationContext);
    } else {
      return token;
    }
  }

  Token parseQualifiedRest(Token token, IdentifierContext context) {
    assert(optional('.', token));
    Token period = token;
    token = parseIdentifier(token.next, context);
    listener.handleQualified(period);
    return token;
  }

  Token skipBlock(Token token) {
    if (!optional('{', token)) {
      return reportUnrecoverableError(token, ErrorKind.ExpectedBlockToSkip)
          ?.next;
    }
    BeginGroupToken beginGroupToken = token;
    Token endGroup = beginGroupToken.endGroup;
    if (endGroup == null) {
      return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
          ?.next;
    } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
      return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
          ?.next;
    }
    return beginGroupToken.endGroup;
  }

  Token parseEnum(Token token) {
    listener.beginEnum(token);
    Token enumKeyword = token;
    token = parseIdentifier(token.next, IdentifierContext.enumDeclaration);
    token = expect('{', token);
    int count = 0;
    if (!optional('}', token)) {
      token = parseIdentifier(token, IdentifierContext.enumValueDeclaration);
      count++;
      while (optional(',', token)) {
        token = token.next;
        if (optional('}', token)) break;
        token = parseIdentifier(token, IdentifierContext.enumValueDeclaration);
        count++;
      }
    }
    Token endBrace = token;
    token = expect('}', token);
    listener.endEnum(enumKeyword, endBrace, count);
    return token;
  }

  Token parseClassOrNamedMixinApplication(Token token) {
    Token begin = token;
    Token abstractKeyword;
    Token classKeyword = token;
    if (optional('abstract', token)) {
      abstractKeyword = token;
      token = token.next;
      classKeyword = token;
    }
    assert(optional('class', classKeyword));
    int modifierCount = 0;
    if (abstractKeyword != null) {
      parseModifier(abstractKeyword);
      modifierCount++;
    }
    listener.handleModifiers(modifierCount);
    bool isMixinApplication = optional('=', peekAfterNominalType(token));
    Token name = token.next;

    if (isMixinApplication) {
      token = parseIdentifier(name, IdentifierContext.namedMixinDeclaration);
      listener.beginNamedMixinApplication(begin, name);
    } else {
      token = parseIdentifier(name, IdentifierContext.classDeclaration);
      listener.beginClassDeclaration(begin, name);
    }

    token = parseTypeVariablesOpt(token);

    if (optional('=', token)) {
      Token equals = token;
      token = token.next;
      return parseNamedMixinApplication(
          token, begin, classKeyword, name, equals);
    } else {
      return parseClass(token, begin, classKeyword, name);
    }
  }

  Token parseNamedMixinApplication(
      Token token, Token begin, Token classKeyword, Token name, Token equals) {
    token = parseMixinApplication(token);
    Token implementsKeyword = null;
    if (optional('implements', token)) {
      implementsKeyword = token;
      token = parseTypeList(token.next);
    }
    listener.endNamedMixinApplication(
        begin, classKeyword, equals, implementsKeyword, token);
    return expect(';', token);
  }

  Token parseClass(Token token, Token begin, Token classKeyword, Token name) {
    Token extendsKeyword;
    if (optional('extends', token)) {
      extendsKeyword = token;
      if (optional('with', peekAfterNominalType(token.next))) {
        token = parseMixinApplication(token.next);
      } else {
        token = parseType(token.next);
      }
    } else {
      extendsKeyword = null;
      listener.handleNoType(token);
    }
    Token implementsKeyword;
    int interfacesCount = 0;
    if (optional('implements', token)) {
      implementsKeyword = token;
      do {
        token = parseType(token.next);
        ++interfacesCount;
      } while (optional(',', token));
    }
    token = parseClassBody(token);
    listener.endClassDeclaration(interfacesCount, begin, classKeyword,
        extendsKeyword, implementsKeyword, token);
    return token.next;
  }

  Token parseStringPart(Token token) {
    if (token.kind != STRING_TOKEN) {
      token = reportUnrecoverableError(token, ErrorKind.ExpectedString)?.next;
    }
    listener.handleStringPart(token);
    return token.next;
  }

  Token parseIdentifier(Token token, IdentifierContext context) {
    if (!token.isIdentifier()) {
      token =
          reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier)?.next;
    }
    listener.handleIdentifier(token, context);
    return token.next;
  }

  Token expect(String string, Token token) {
    if (!identical(string, token.stringValue)) {
      return reportUnrecoverableError(
          token, ErrorKind.ExpectedButGot, {"expected": string})?.next;
    }
    return token.next;
  }

  Token parseTypeVariable(Token token) {
    listener.beginTypeVariable(token);
    token = parseMetadataStar(token);
    token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration);
    Token extendsOrSuper = null;
    if (optional('extends', token) || optional('super', token)) {
      extendsOrSuper = token;
      token = parseType(token.next);
    } else {
      listener.handleNoType(token);
    }
    listener.endTypeVariable(token, extendsOrSuper);
    return token;
  }

  /**
   * Returns true if the stringValue of the [token] is either [value1],
   * [value2], or [value3].
   */
  bool isOneOf3(Token token, String value1, String value2, String value3) {
    String stringValue = token.stringValue;
    return value1 == stringValue ||
        value2 == stringValue ||
        value3 == stringValue;
  }

  /**
   * Returns true if the stringValue of the [token] is either [value1],
   * [value2], [value3], or [value4].
   */
  bool isOneOf4(
      Token token, String value1, String value2, String value3, String value4) {
    String stringValue = token.stringValue;
    return value1 == stringValue ||
        value2 == stringValue ||
        value3 == stringValue ||
        value4 == stringValue;
  }

  bool notEofOrValue(String value, Token token) {
    return !identical(token.kind, EOF_TOKEN) &&
        !identical(value, token.stringValue);
  }

  bool isGeneralizedFunctionType(Token token) {
    return optional('Function', token) &&
        (optional('<', token.next) || optional('(', token.next));
  }

  Token parseType(Token token) {
    Token begin = token;
    if (isGeneralizedFunctionType(token)) {
      // A function type without return type.
      // Push the non-existing return type first. The loop below will
      // generate the full type.
      listener.handleNoType(token);
    } else if (identical(token.stringValue, 'void') &&
        isGeneralizedFunctionType(token.next)) {
      listener.handleVoidKeyword(token);
      token = token.next;
    } else {
      if (isValidTypeReference(token)) {
        token = parseIdentifier(token, IdentifierContext.typeReference);
        token = parseQualifiedRestOpt(
            token, IdentifierContext.typeReferenceContinuation);
      } else {
        token = reportUnrecoverableError(token, ErrorKind.ExpectedType)?.next;
        listener.handleInvalidTypeReference(token);
      }
      token = parseTypeArgumentsOpt(token);
      listener.handleType(begin, token);
    }

    // While we see a `Function(` treat the pushed type as return type.
    // For example: `int Function() Function(int) Function(String x)`.
    while (isGeneralizedFunctionType(token)) {
      token = parseFunctionType(token);
    }
    return token;
  }

  /// Parses a generalized function type.
  ///
  /// The return type must already be pushed.
  Token parseFunctionType(Token token) {
    assert(optional('Function', token));
    Token functionToken = token;
    token = token.next;
    token = parseTypeVariablesOpt(token);
    token = parseFormalParameters(token, inFunctionType: true);
    listener.handleFunctionType(functionToken, token);
    return token;
  }

  Token parseTypeArgumentsOpt(Token token) {
    return parseStuff(
        token,
        (t) => listener.beginTypeArguments(t),
        (t) => parseType(t),
        (c, bt, et) => listener.endTypeArguments(c, bt, et),
        (t) => listener.handleNoTypeArguments(t));
  }

  Token parseTypeVariablesOpt(Token token) {
    return parseStuff(
        token,
        (t) => listener.beginTypeVariables(t),
        (t) => parseTypeVariable(t),
        (c, bt, et) => listener.endTypeVariables(c, bt, et),
        (t) => listener.handleNoTypeVariables(t));
  }

  // TODO(ahe): Clean this up.
  Token parseStuff(Token token, Function beginStuff, Function stuffParser,
      Function endStuff, Function handleNoStuff) {
    if (optional('<', token)) {
      Token begin = token;
      beginStuff(begin);
      int count = 0;
      do {
        token = stuffParser(token.next);
        ++count;
      } while (optional(',', token));
      Token next = token.next;
      if (identical(token.stringValue, '>>')) {
        token = new SymbolToken(GT_INFO, token.charOffset);
        token.next = new SymbolToken(GT_INFO, token.charOffset + 1);
        token.next.next = next;
      }
      endStuff(count, begin, token);
      return expect('>', token);
    }
    handleNoStuff(token);
    return token;
  }

  Token parseTopLevelMember(Token token) {
    Token start = token;
    listener.beginTopLevelMember(token);

    Link<Token> identifiers = findMemberName(token);
    if (identifiers.isEmpty) {
      return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration)
          ?.next;
    }
    Token afterName = identifiers.head;
    identifiers = identifiers.tail;

    if (identifiers.isEmpty) {
      return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration)
          ?.next;
    }
    Token name = identifiers.head;
    identifiers = identifiers.tail;
    Token getOrSet;
    if (!identifiers.isEmpty) {
      String value = identifiers.head.stringValue;
      if ((identical(value, 'get')) || (identical(value, 'set'))) {
        getOrSet = identifiers.head;
        identifiers = identifiers.tail;
      }
    }
    Token type;
    if (!identifiers.isEmpty) {
      if (isValidTypeReference(identifiers.head)) {
        type = identifiers.head;
        identifiers = identifiers.tail;
      }
    }

    token = afterName;
    bool isField;
    while (true) {
      // Loop to allow the listener to rewrite the token stream for
      // error handling.
      final String value = token.stringValue;
      if ((identical(value, '(')) ||
          (identical(value, '{')) ||
          (identical(value, '=>'))) {
        isField = false;
        break;
      } else if ((identical(value, '=')) || (identical(value, ','))) {
        isField = true;
        break;
      } else if (identical(value, ';')) {
        if (getOrSet != null) {
          // If we found a "get" keyword, this must be an abstract
          // getter.
          isField = (!identical(getOrSet.stringValue, 'get'));
          // TODO(ahe): This feels like a hack.
        } else {
          isField = true;
        }
        break;
      } else {
        token =
            reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
        if (identical(token.kind, EOF_TOKEN)) return token;
      }
    }
    var modifiers = identifiers.reverse();
    return isField
        ? parseFields(start, modifiers, type, getOrSet, name, true)
        : parseTopLevelMethod(start, modifiers, type, getOrSet, name);
  }

  bool isVarFinalOrConst(Token token) {
    String value = token.stringValue;
    return identical('var', value) ||
        identical('final', value) ||
        identical('const', value);
  }

  Token expectVarFinalOrConst(
      Link<Token> modifiers, bool hasType, bool allowStatic) {
    int modifierCount = 0;
    Token staticModifier;
    if (allowStatic &&
        !modifiers.isEmpty &&
        optional('static', modifiers.head)) {
      staticModifier = modifiers.head;
      modifierCount++;
      parseModifier(staticModifier);
      modifiers = modifiers.tail;
    }
    if (modifiers.isEmpty) {
      listener.handleModifiers(modifierCount);
      return null;
    }
    if (modifiers.tail.isEmpty) {
      Token modifier = modifiers.head;
      if (isVarFinalOrConst(modifier)) {
        modifierCount++;
        parseModifier(modifier);
        listener.handleModifiers(modifierCount);
        // TODO(ahe): The caller checks for "var Type name", perhaps we should
        // check here instead.
        return modifier;
      }
    }

    // Slow case to report errors.
    List<Token> modifierList = modifiers.toList();
    Token varFinalOrConst =
        modifierList.firstWhere(isVarFinalOrConst, orElse: () => null);
    if (allowStatic && staticModifier == null) {
      staticModifier = modifierList.firstWhere(
          (modifier) => optional('static', modifier),
          orElse: () => null);
      if (staticModifier != null) {
        modifierCount++;
        parseModifier(staticModifier);
        modifierList.remove(staticModifier);
      }
    }
    bool hasTypeOrModifier = hasType;
    if (varFinalOrConst != null) {
      parseModifier(varFinalOrConst);
      modifierCount++;
      hasTypeOrModifier = true;
      modifierList.remove(varFinalOrConst);
    }
    listener.handleModifiers(modifierCount);
    var kind = hasTypeOrModifier
        ? ErrorKind.ExtraneousModifier
        : ErrorKind.ExtraneousModifierReplace;
    for (Token modifier in modifierList) {
      reportRecoverableError(modifier, kind, {'modifier': modifier});
    }
    return null;
  }

  /// Removes the optional `covariant` token from the modifiers, if there
  /// is no `static` in the list, and `covariant` is the first modifier.
  Link<Token> removeOptCovariantTokenIfNotStatic(Link<Token> modifiers) {
    if (modifiers.isEmpty ||
        !identical(modifiers.first.stringValue, 'covariant')) {
      return modifiers;
    }
    for (Token modifier in modifiers.tail) {
      if (identical(modifier.stringValue, 'static')) {
        return modifiers;
      }
    }
    return modifiers.tail;
  }

  Token parseFields(Token start, Link<Token> modifiers, Token type,
      Token getOrSet, Token name, bool isTopLevel) {
    bool hasType = type != null;

    Token covariantKeyword;
    if (getOrSet == null && !isTopLevel) {
      // TODO(ahe): replace the method removeOptCovariantTokenIfNotStatic with
      // a better mechanism.
      Link<Token> newModifiers = removeOptCovariantTokenIfNotStatic(modifiers);
      if (!identical(newModifiers, modifiers)) {
        covariantKeyword = modifiers.first;
        modifiers = newModifiers;
      }
    }

    Token varFinalOrConst =
        expectVarFinalOrConst(modifiers, hasType, !isTopLevel);
    bool isVar = false;
    bool hasModifier = false;
    if (varFinalOrConst != null) {
      hasModifier = true;
      isVar = optional('var', varFinalOrConst);
    }

    if (getOrSet != null) {
      var kind = (hasModifier || hasType)
          ? ErrorKind.ExtraneousModifier
          : ErrorKind.ExtraneousModifierReplace;
      reportRecoverableError(getOrSet, kind, {'modifier': getOrSet});
    }

    if (!hasType) {
      listener.handleNoType(name);
    } else if (optional('void', type) &&
        !isGeneralizedFunctionType(type.next)) {
      listener.handleNoType(name);
      // TODO(ahe): This error is reported twice, second time is from
      // [parseVariablesDeclarationMaybeSemicolon] via
      // [PartialFieldListElement.parseNode].
      reportRecoverableError(type, ErrorKind.InvalidVoid);
    } else {
      parseType(type);
      if (isVar) {
        reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier,
            {'modifier': modifiers.head});
      }
    }

    IdentifierContext context = isTopLevel
        ? IdentifierContext.topLevelVariableDeclaration
        : IdentifierContext.fieldDeclaration;
    Token token = parseIdentifier(name, context);

    int fieldCount = 1;
    token = parseFieldInitializerOpt(token);
    while (optional(',', token)) {
      token = parseIdentifier(token.next, context);
      token = parseFieldInitializerOpt(token);
      ++fieldCount;
    }
    Token semicolon = token;
    token = expectSemicolon(token);
    if (isTopLevel) {
      listener.endTopLevelFields(fieldCount, start, semicolon);
    } else {
      listener.endFields(fieldCount, covariantKeyword, start, semicolon);
    }
    return token;
  }

  Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type,
      Token getOrSet, Token name) {
    listener.beginTopLevelMethod(start, name);
    Token externalModifier;
    // TODO(johnniwinther): Move error reporting to resolution to give more
    // specific error messages.
    for (Token modifier in modifiers) {
      if (externalModifier == null && optional('external', modifier)) {
        externalModifier = modifier;
      } else {
        reportRecoverableError(
            modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
      }
    }
    if (externalModifier != null) {
      parseModifier(externalModifier);
      listener.handleModifiers(1);
    } else {
      listener.handleModifiers(0);
    }

    if (type == null) {
      listener.handleNoType(name);
    } else {
      parseReturnTypeOpt(type);
    }
    Token token =
        parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration);

    if (getOrSet == null) {
      token = parseTypeVariablesOpt(token);
    } else {
      listener.handleNoTypeVariables(token);
    }
    token = parseFormalParametersOpt(token);
    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
    token = parseAsyncModifier(token);
    token = parseFunctionBody(token, false, externalModifier != null);
    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
    Token endToken = token;
    token = token.next;
    listener.endTopLevelMethod(start, getOrSet, endToken);
    return token;
  }

  /// Looks ahead to find the name of a member. Returns a link of the modifiers,
  /// set/get, (operator) name, and either the start of the method body or the
  /// end of the declaration.
  ///
  /// Examples:
  ///
  ///     int get foo;
  /// results in
  ///     [';', 'foo', 'get', 'int']
  ///
  ///
  ///     static const List<int> foo = null;
  /// results in
  ///     ['=', 'foo', 'List', 'const', 'static']
  ///
  ///
  ///     get foo async* { return null }
  /// results in
  ///     ['{', 'foo', 'get']
  ///
  ///
  ///     operator *(arg) => null;
  /// results in
  ///     ['(', '*', 'operator']
  ///
  Link<Token> findMemberName(Token token) {
    // TODO(ahe): This method is rather broken for examples like this:
    //
    //     get<T>(){}
    //
    // In addition, the loop below will include things that can't be
    // identifiers. This may be desirable (for error recovery), or
    // not. Regardless, this method probably needs an overhaul.
    Link<Token> identifiers = const Link<Token>();

    // `true` if 'get' has been seen.
    bool isGetter = false;
    // `true` if an identifier has been seen after 'get'.
    bool hasName = false;

    while (token.kind != EOF_TOKEN) {
      if (optional('get', token)) {
        isGetter = true;
      } else if (hasName &&
          (optional("sync", token) || optional("async", token))) {
        // Skip.
        token = token.next;
        if (optional("*", token)) {
          // Skip.
          token = token.next;
        }
        continue;
      } else if (optional("(", token) ||
          optional("{", token) ||
          optional("=>", token)) {
        // A method.
        identifiers = identifiers.prepend(token);
        return listener.handleMemberName(identifiers);
      } else if (optional("=", token) ||
          optional(";", token) ||
          optional(",", token)) {
        // A field or abstract getter.
        identifiers = identifiers.prepend(token);
        return listener.handleMemberName(identifiers);
      } else if (isGetter) {
        hasName = true;
      }
      identifiers = identifiers.prepend(token);

      if (!isGeneralizedFunctionType(token)) {
        // Read a potential return type.
        if (isValidTypeReference(token)) {
          // type ...
          if (optional('.', token.next)) {
            // type '.' ...
            if (token.next.next.isIdentifier()) {
              // type '.' identifier
              token = token.next.next;
            }
          }
          if (optional('<', token.next)) {
            if (token.next is BeginGroupToken) {
              BeginGroupToken beginGroup = token.next;
              if (beginGroup.endGroup == null) {
                reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
              } else {
                token = beginGroup.endGroup;
              }
            }
          }
        }
        token = token.next;
      }
      while (isGeneralizedFunctionType(token)) {
        token = token.next;
        if (optional('<', token)) {
          if (token is BeginGroupToken) {
            BeginGroupToken beginGroup = token;
            if (beginGroup.endGroup == null) {
              reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
            } else {
              token = beginGroup.endGroup.next;
            }
          }
        }
        if (!optional('(', token)) {
          if (optional(';', token)) {
            reportRecoverableError(token, ErrorKind.ExpectedOpenParens);
          }
          token = expect("(", token);
        }
        if (token is BeginGroupToken) {
          BeginGroupToken beginGroup = token;
          if (beginGroup.endGroup == null) {
            reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
          } else {
            token = beginGroup.endGroup.next;
          }
        }
      }
    }
    return listener.handleMemberName(const Link<Token>());
  }

  Token parseFieldInitializerOpt(Token token) {
    if (optional('=', token)) {
      Token assignment = token;
      listener.beginFieldInitializer(token);
      token = parseExpression(token.next);
      listener.endFieldInitializer(assignment);
    } else {
      listener.handleNoFieldInitializer(token);
    }
    return token;
  }

  Token parseVariableInitializerOpt(Token token) {
    if (optional('=', token)) {
      Token assignment = token;
      listener.beginVariableInitializer(token);
      token = parseExpression(token.next);
      listener.endVariableInitializer(assignment);
    } else {
      listener.handleNoVariableInitializer(token);
    }
    return token;
  }

  Token parseInitializersOpt(Token token) {
    if (optional(':', token)) {
      return parseInitializers(token);
    } else {
      listener.handleNoInitializers();
      return token;
    }
  }

  Token parseInitializers(Token token) {
    Token begin = token;
    listener.beginInitializers(begin);
    expect(':', token);
    int count = 0;
    bool old = mayParseFunctionExpressions;
    mayParseFunctionExpressions = false;
    do {
      token = token.next;
      listener.beginInitializer(token);
      token = parseExpression(token);
      listener.endInitializer(token);
      ++count;
    } while (optional(',', token));
    mayParseFunctionExpressions = old;
    listener.endInitializers(count, begin, token);
    return token;
  }

  Token parseLiteralStringOrRecoverExpression(Token token) {
    if (identical(token.kind, STRING_TOKEN)) {
      return parseLiteralString(token);
    } else {
      reportRecoverableError(token, ErrorKind.ExpectedString);
      return parseRecoverExpression(token);
    }
  }

  Token expectSemicolon(Token token) {
    return expect(';', token);
  }

  bool isModifier(Token token) {
    final String value = token.stringValue;
    return (identical('final', value)) ||
        (identical('var', value)) ||
        (identical('const', value)) ||
        (identical('abstract', value)) ||
        (identical('static', value)) ||
        (identical('external', value));
  }

  Token parseModifier(Token token) {
    assert(isModifier(token));
    listener.handleModifier(token);
    return token.next;
  }

  void parseModifierList(Link<Token> tokens) {
    int count = 0;
    for (; !tokens.isEmpty; tokens = tokens.tail) {
      Token token = tokens.head;
      if (isModifier(token)) {
        parseModifier(token);
      } else {
        reportUnrecoverableError(token, ErrorKind.UnexpectedToken);
        // Skip the remaining modifiers.
        break;
      }
      count++;
    }
    listener.handleModifiers(count);
  }

  Token parseModifiers(Token token) {
    // TODO(ahe): The calling convention of this method probably needs to
    // change. For example, this is parsed as a local variable declaration:
    // `abstract foo;`. Ideally, this example should be handled as a local
    // variable having the type `abstract` (which should be reported as
    // `ErrorKind.BuiltInIdentifierAsType` by [parseIdentifier]).
    int count = 0;
    while (identical(token.kind, KEYWORD_TOKEN)) {
      if (!isModifier(token)) break;
      token = parseModifier(token);
      count++;
    }
    listener.handleModifiers(count);
    return token;
  }

  /**
   * Returns the first token after the type starting at [token].
   *
   * This method assumes that [token] is an identifier (or void).
   * Use [peekAfterIfType] if [token] isn't known to be an identifier.
   */
  Token peekAfterType(Token token) {
    // We are looking at "identifier ...".
    Token peek = token;
    if (!isGeneralizedFunctionType(token)) {
      peek = peekAfterNominalType(token);
    }

    // We might have just skipped over the return value of the function type.
    // Check again, if we are now at a function type position.
    while (isGeneralizedFunctionType(peek)) {
      peek = peekAfterFunctionType(peek.next);
    }
    return peek;
  }

  /**
   * Returns the first token after the nominal type starting at [token].
   *
   * This method assumes that [token] is an identifier (or void).
   */
  Token peekAfterNominalType(Token token) {
    Token peek = token.next;
    if (identical(peek.kind, PERIOD_TOKEN)) {
      if (peek.next.isIdentifier()) {
        // Look past a library prefix.
        peek = peek.next.next;
      }
    }
    // We are looking at "qualified ...".
    if (identical(peek.kind, LT_TOKEN)) {
      // Possibly generic type.
      // We are looking at "qualified '<'".
      BeginGroupToken beginGroupToken = peek;
      Token gtToken = beginGroupToken.endGroup;
      if (gtToken != null) {
        // We are looking at "qualified '<' ... '>' ...".
        peek = gtToken.next;
      }
    }
    return peek;
  }

  /**
   * Returns the first token after the function type starting at [token].
   *
   * The token must be at the token *after* the `Function` token position. That
   * is, the return type and the `Function` token must have already been
   * skipped.
   *
   * This function only skips over one function type syntax.
   * If necessary, this function must be called multiple times.
   *
   * Example:
   * ```
   * int Function() Function<T>(int)
   *             ^          ^
   * A call to this function must be either at `(` or at `<`.
   * If `token` pointed to the first `(`, then the returned
   * token points to the second `Function` token.
   */
  Token peekAfterFunctionType(Token token) {
    // Possible inputs are:
    //    ( ... )
    //    < ... >( ... )

    Token peek = token;
    // If there is a generic argument to the function, skip over that one first.
    if (identical(peek.kind, LT_TOKEN)) {
      BeginGroupToken beginGroupToken = peek;
      Token closeToken = beginGroupToken.endGroup;
      if (closeToken != null) {
        peek = closeToken.next;
      }
    }

    // Now we just need to skip over the formals.
    expect('(', peek);

    BeginGroupToken beginGroupToken = peek;
    Token closeToken = beginGroupToken.endGroup;
    if (closeToken != null) {
      peek = closeToken.next;
    }

    return peek;
  }

  /**
   * If [token] is the start of a type, returns the token after that type.
   * If [token] is not the start of a type, null is returned.
   */
  Token peekAfterIfType(Token token) {
    if (!optional('void', token) && !token.isIdentifier()) {
      return null;
    }
    return peekAfterType(token);
  }

  Token skipClassBody(Token token) {
    if (!optional('{', token)) {
      return reportUnrecoverableError(token, ErrorKind.ExpectedClassBodyToSkip)
          ?.next;
    }
    BeginGroupToken beginGroupToken = token;
    Token endGroup = beginGroupToken.endGroup;
    if (endGroup == null) {
      return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
          ?.next;
    } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
      return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
          ?.next;
    }
    return endGroup;
  }

  Token parseClassBody(Token token) {
    Token begin = token;
    listener.beginClassBody(token);
    if (!optional('{', token)) {
      token =
          reportUnrecoverableError(token, ErrorKind.ExpectedClassBody)?.next;
    }
    token = token.next;
    int count = 0;
    while (notEofOrValue('}', token)) {
      token = parseMember(token);
      ++count;
    }
    expect('}', token);
    listener.endClassBody(count, begin, token);
    return token;
  }

  bool isGetOrSet(Token token) {
    final String value = token.stringValue;
    return (identical(value, 'get')) || (identical(value, 'set'));
  }

  bool isFactoryDeclaration(Token token) {
    if (optional('external', token)) token = token.next;
    if (optional('const', token)) token = token.next;
    return optional('factory', token);
  }

  Token parseMember(Token token) {
    token = parseMetadataStar(token);
    Token start = token;
    listener.beginMember(token);
    if (isFactoryDeclaration(token)) {
      token = parseFactoryMethod(token);
      listener.endMember();
      assert(token != null);
      return token;
    }

    Link<Token> identifiers = findMemberName(token);
    if (identifiers.isEmpty) {
      return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration)
          ?.next;
    }
    Token afterName = identifiers.head;
    identifiers = identifiers.tail;

    if (identifiers.isEmpty) {
      return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration)
          ?.next;
    }
    Token name = identifiers.head;
    identifiers = identifiers.tail;
    if (!identifiers.isEmpty) {
      if (optional('operator', identifiers.head)) {
        name = identifiers.head;
        identifiers = identifiers.tail;
      }
    }
    Token getOrSet;
    if (!identifiers.isEmpty) {
      if (isGetOrSet(identifiers.head)) {
        getOrSet = identifiers.head;
        identifiers = identifiers.tail;
      }
    }
    Token type;
    if (!identifiers.isEmpty) {
      if (isValidTypeReference(identifiers.head)) {
        type = identifiers.head;
        identifiers = identifiers.tail;
      }
    }

    token = afterName;
    bool isField;
    while (true) {
      // Loop to allow the listener to rewrite the token stream for
      // error handling.
      final String value = token.stringValue;
      if ((identical(value, '(')) ||
          (identical(value, '.')) ||
          (identical(value, '{')) ||
          (identical(value, '=>')) ||
          (identical(value, '<'))) {
        isField = false;
        break;
      } else if (identical(value, ';')) {
        if (getOrSet != null) {
          // If we found a "get" keyword, this must be an abstract
          // getter.
          isField = !optional("get", getOrSet);
          // TODO(ahe): This feels like a hack.
        } else {
          isField = true;
        }
        break;
      } else if ((identical(value, '=')) || (identical(value, ','))) {
        isField = true;
        break;
      } else {
        token =
            reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
        if (identical(token.kind, EOF_TOKEN)) {
          // TODO(ahe): This is a hack, see parseTopLevelMember.
          listener.endFields(1, null, start, token);
          listener.endMember();
          return token;
        }
      }
    }

    var modifiers = identifiers.reverse();
    token = isField
        ? parseFields(start, modifiers, type, getOrSet, name, false)
        : parseMethod(start, modifiers, type, getOrSet, name);
    listener.endMember();
    return token;
  }

  Token parseMethod(Token start, Link<Token> modifiers, Token type,
      Token getOrSet, Token name) {
    listener.beginMethod(start, name);
    Token externalModifier;
    Token staticModifier;
    Token constModifier;
    int modifierCount = 0;
    int allowedModifierCount = 1;
    // TODO(johnniwinther): Move error reporting to resolution to give more
    // specific error messages.
    for (Token modifier in modifiers) {
      if (externalModifier == null && optional('external', modifier)) {
        modifierCount++;
        externalModifier = modifier;
        if (modifierCount != allowedModifierCount) {
          reportRecoverableError(
              modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
        }
        allowedModifierCount++;
      } else if (staticModifier == null && optional('static', modifier)) {
        modifierCount++;
        staticModifier = modifier;
        if (modifierCount != allowedModifierCount) {
          reportRecoverableError(
              modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
        }
      } else if (constModifier == null && optional('const', modifier)) {
        modifierCount++;
        constModifier = modifier;
        if (modifierCount != allowedModifierCount) {
          reportRecoverableError(
              modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
        }
      } else {
        reportRecoverableError(
            modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
      }
    }
    if (getOrSet != null && constModifier != null) {
      reportRecoverableError(constModifier, ErrorKind.ExtraneousModifier,
          {'modifier': constModifier});
    }
    parseModifierList(modifiers);

    if (type == null) {
      listener.handleNoType(name);
    } else {
      parseReturnTypeOpt(type);
    }
    Token token;
    if (optional('operator', name)) {
      token = parseOperatorName(name);
      if (staticModifier != null) {
        reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier,
            {'modifier': staticModifier});
      }
    } else {
      token = parseIdentifier(name, IdentifierContext.methodDeclaration);
    }

    token = parseQualifiedRestOpt(
        token, IdentifierContext.methodDeclarationContinuation);
    if (getOrSet == null) {
      token = parseTypeVariablesOpt(token);
    } else {
      listener.handleNoTypeVariables(token);
    }
    token = parseFormalParametersOpt(token);
    token = parseInitializersOpt(token);
    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
    token = parseAsyncModifier(token);
    if (optional('=', token)) {
      token = parseRedirectingFactoryBody(token);
    } else {
      token = parseFunctionBody(
          token, false, staticModifier == null || externalModifier != null);
    }
    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
    listener.endMethod(getOrSet, start, token);
    return token.next;
  }

  Token parseFactoryMethod(Token token) {
    assert(isFactoryDeclaration(token));
    Token start = token;
    bool isExternal = false;
    int modifierCount = 0;
    while (isModifier(token)) {
      if (optional('external', token)) {
        isExternal = true;
      }
      token = parseModifier(token);
      modifierCount++;
    }
    listener.handleModifiers(modifierCount);
    Token factoryKeyword = token;
    listener.beginFactoryMethod(factoryKeyword);
    token = expect('factory', token);
    token = parseConstructorReference(token);
    token = parseFormalParameters(token);
    token = parseAsyncModifier(token);
    if (optional('=', token)) {
      token = parseRedirectingFactoryBody(token);
    } else {
      token = parseFunctionBody(token, false, isExternal);
    }
    listener.endFactoryMethod(start, factoryKeyword, token);
    return token.next;
  }

  Token parseOperatorName(Token token) {
    assert(optional('operator', token));
    if (isUserDefinableOperator(token.next.stringValue)) {
      Token operator = token;
      token = token.next;
      listener.handleOperatorName(operator, token);
      return token.next;
    } else {
      return parseIdentifier(token, IdentifierContext.operatorName);
    }
  }

  Token parseFunction(Token token, Token getOrSet) {
    listener.beginFunction(token);
    token = parseModifiers(token);
    if (identical(getOrSet, token)) {
      // get <name>  => ...
      token = token.next;
      listener.handleNoType(token);
      listener.beginFunctionName(token);
      if (optional('operator', token)) {
        token = parseOperatorName(token);
      } else {
        token =
            parseIdentifier(token, IdentifierContext.localAccessorDeclaration);
      }
    } else if (optional('operator', token)) {
      // operator <op> (...
      listener.handleNoType(token);
      listener.beginFunctionName(token);
      token = parseOperatorName(token);
    } else {
      // <type>? <get>? <name>
      token = parseReturnTypeOpt(token);
      if (identical(getOrSet, token)) {
        token = token.next;
      }
      listener.beginFunctionName(token);
      if (optional('operator', token)) {
        token = parseOperatorName(token);
      } else {
        token =
            parseIdentifier(token, IdentifierContext.localFunctionDeclaration);
      }
    }
    token = parseQualifiedRestOpt(
        token, IdentifierContext.localFunctionDeclarationContinuation);
    listener.endFunctionName(token);
    if (getOrSet == null) {
      token = parseTypeVariablesOpt(token);
    } else {
      listener.handleNoTypeVariables(token);
    }
    token = parseFormalParametersOpt(token);
    token = parseInitializersOpt(token);
    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
    token = parseAsyncModifier(token);
    token = parseFunctionBody(token, false, true);
    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
    listener.endFunction(getOrSet, token);
    return token.next;
  }

  Token parseUnnamedFunction(Token token) {
    listener.beginUnnamedFunction(token);
    token = parseFormalParameters(token);
    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
    token = parseAsyncModifier(token);
    bool isBlock = optional('{', token);
    token = parseFunctionBody(token, true, false);
    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
    listener.endUnnamedFunction(token);
    return isBlock ? token.next : token;
  }

  Token parseFunctionDeclaration(Token token) {
    listener.beginFunctionDeclaration(token);
    token = parseFunction(token, null);
    listener.endFunctionDeclaration(token);
    return token;
  }

  Token parseFunctionExpression(Token token) {
    listener.beginFunction(token);
    listener.handleModifiers(0);
    token = parseReturnTypeOpt(token);
    listener.beginFunctionName(token);
    token = parseIdentifier(token, IdentifierContext.functionExpressionName);
    listener.endFunctionName(token);
    token = parseTypeVariablesOpt(token);
    token = parseFormalParameters(token);
    listener.handleNoInitializers();
    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
    token = parseAsyncModifier(token);
    bool isBlock = optional('{', token);
    token = parseFunctionBody(token, true, false);
    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
    listener.endFunction(null, token);
    return isBlock ? token.next : token;
  }

  Token parseConstructorReference(Token token) {
    Token start = token;
    listener.beginConstructorReference(start);
    token = parseIdentifier(token, IdentifierContext.constructorReference);
    token = parseQualifiedRestOpt(
        token, IdentifierContext.constructorReferenceContinuation);
    token = parseTypeArgumentsOpt(token);
    Token period = null;
    if (optional('.', token)) {
      period = token;
      token = parseIdentifier(token.next,
          IdentifierContext.constructorReferenceContinuationAfterTypeArguments);
    } else {
      listener
          .handleNoConstructorReferenceContinuationAfterTypeArguments(token);
    }
    listener.endConstructorReference(start, period, token);
    return token;
  }

  Token parseRedirectingFactoryBody(Token token) {
    listener.beginRedirectingFactoryBody(token);
    assert(optional('=', token));
    Token equals = token;
    token = parseConstructorReference(token.next);
    Token semicolon = token;
    expectSemicolon(token);
    listener.endRedirectingFactoryBody(equals, semicolon);
    return token;
  }

  Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) {
    assert(!isExpression);
    token = skipAsyncModifier(token);
    String value = token.stringValue;
    if (identical(value, ';')) {
      if (!allowAbstract) {
        reportRecoverableError(token, ErrorKind.ExpectedBody);
      }
      listener.handleNoFunctionBody(token);
    } else {
      if (identical(value, '=>')) {
        token = parseExpression(token.next);
        expectSemicolon(token);
        listener.handleFunctionBodySkipped(token, true);
      } else if (identical(value, '=')) {
        reportRecoverableError(token, ErrorKind.ExpectedBody);
        token = parseExpression(token.next);
        expectSemicolon(token);
        listener.handleFunctionBodySkipped(token, true);
      } else {
        token = skipBlock(token);
        listener.handleFunctionBodySkipped(token, false);
      }
    }
    return token;
  }

  Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
    if (optional(';', token)) {
      if (!allowAbstract) {
        reportRecoverableError(token, ErrorKind.ExpectedBody);
      }
      listener.handleEmptyFunctionBody(token);
      return token;
    } else if (optional('=>', token)) {
      Token begin = token;
      token = parseExpression(token.next);
      if (!isExpression) {
        expectSemicolon(token);
        listener.handleExpressionFunctionBody(begin, token);
      } else {
        listener.handleExpressionFunctionBody(begin, null);
      }
      return token;
    } else if (optional('=', token)) {
      Token begin = token;
      // Recover from a bad factory method.
      reportRecoverableError(token, ErrorKind.ExpectedBody);
      token = parseExpression(token.next);
      if (!isExpression) {
        expectSemicolon(token);
        listener.handleExpressionFunctionBody(begin, token);
      } else {
        listener.handleExpressionFunctionBody(begin, null);
      }
      return token;
    }
    Token begin = token;
    int statementCount = 0;
    if (!optional('{', token)) {
      token =
          reportUnrecoverableError(token, ErrorKind.ExpectedFunctionBody)?.next;
      listener.handleInvalidFunctionBody(token);
      return token;
    }

    listener.beginBlockFunctionBody(begin);
    token = token.next;
    while (notEofOrValue('}', token)) {
      token = parseStatement(token);
      ++statementCount;
    }
    listener.endBlockFunctionBody(statementCount, begin, token);
    expect('}', token);
    return token;
  }

  Token skipAsyncModifier(Token token) {
    String value = token.stringValue;
    if (identical(value, 'async')) {
      token = token.next;
      value = token.stringValue;

      if (identical(value, '*')) {
        token = token.next;
      }
    } else if (identical(value, 'sync')) {
      token = token.next;
      value = token.stringValue;

      if (identical(value, '*')) {
        token = token.next;
      }
    }
    return token;
  }

  Token parseAsyncModifier(Token token) {
    Token async;
    Token star;
    asyncAwaitKeywordsEnabled = false;
    if (optional('async', token)) {
      asyncAwaitKeywordsEnabled = true;
      async = token;
      token = token.next;
      if (optional('*', token)) {
        star = token;
        token = token.next;
      }
    } else if (optional('sync', token)) {
      async = token;
      token = token.next;
      if (optional('*', token)) {
        asyncAwaitKeywordsEnabled = true;
        star = token;
        token = token.next;
      } else {
        reportRecoverableError(async, ErrorKind.InvalidSyncModifier);
      }
    }
    listener.handleAsyncModifier(async, star);
    return token;
  }

  int statementDepth = 0;
  Token parseStatement(Token token) {
    if (statementDepth++ > 500) {
      // This happens for degenerate programs, for example, a lot of nested
      // if-statements. The language test deep_nesting2_negative_test, for
      // example, provokes this.
      return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next;
    }
    Token result = parseStatementX(token);
    statementDepth--;
    return result;
  }

  Token parseStatementX(Token token) {
    final value = token.stringValue;
    if (identical(token.kind, IDENTIFIER_TOKEN)) {
      return parseExpressionStatementOrDeclaration(token);
    } else if (identical(value, '{')) {
      return parseBlock(token);
    } else if (identical(value, 'return')) {
      return parseReturnStatement(token);
    } else if (identical(value, 'var') || identical(value, 'final')) {
      return parseVariablesDeclaration(token);
    } else if (identical(value, 'if')) {
      return parseIfStatement(token);
    } else if (asyncAwaitKeywordsEnabled && identical(value, 'await')) {
      if (identical(token.next.stringValue, 'for')) {
        return parseForStatement(token, token.next);
      } else {
        return parseExpressionStatement(token);
      }
    } else if (identical(value, 'for')) {
      return parseForStatement(null, token);
    } else if (identical(value, 'rethrow')) {
      return parseRethrowStatement(token);
    } else if (identical(value, 'throw') && optional(';', token.next)) {
      // TODO(kasperl): Stop dealing with throw here.
      return parseRethrowStatement(token);
    } else if (identical(value, 'void')) {
      return parseExpressionStatementOrDeclaration(token);
    } else if (identical(value, 'while')) {
      return parseWhileStatement(token);
    } else if (identical(value, 'do')) {
      return parseDoWhileStatement(token);
    } else if (identical(value, 'try')) {
      return parseTryStatement(token);
    } else if (identical(value, 'switch')) {
      return parseSwitchStatement(token);
    } else if (identical(value, 'break')) {
      return parseBreakStatement(token);
    } else if (identical(value, 'continue')) {
      return parseContinueStatement(token);
    } else if (identical(value, 'assert')) {
      return parseAssertStatement(token);
    } else if (identical(value, ';')) {
      return parseEmptyStatement(token);
    } else if (asyncAwaitKeywordsEnabled && identical(value, 'yield')) {
      return parseYieldStatement(token);
    } else if (identical(value, 'const')) {
      return parseExpressionStatementOrConstDeclaration(token);
    } else if (token.isIdentifier()) {
      return parseExpressionStatementOrDeclaration(token);
    } else {
      return parseExpressionStatement(token);
    }
  }

  Token parseYieldStatement(Token token) {
    Token begin = token;
    listener.beginYieldStatement(begin);
    assert(identical('yield', token.stringValue));
    token = token.next;
    Token starToken;
    if (optional('*', token)) {
      starToken = token;
      token = token.next;
    }
    token = parseExpression(token);
    listener.endYieldStatement(begin, starToken, token);
    return expectSemicolon(token);
  }

  Token parseReturnStatement(Token token) {
    Token begin = token;
    listener.beginReturnStatement(begin);
    assert(identical('return', token.stringValue));
    token = token.next;
    if (optional(';', token)) {
      listener.endReturnStatement(false, begin, token);
    } else {
      token = parseExpression(token);
      listener.endReturnStatement(true, begin, token);
    }
    return expectSemicolon(token);
  }

  Token peekIdentifierAfterType(Token token) {
    Token peek = peekAfterType(token);
    if (peek != null && peek.isIdentifier()) {
      // We are looking at "type identifier".
      return peek;
    } else {
      return null;
    }
  }

  Token peekIdentifierAfterOptionalType(Token token) {
    Token peek = peekAfterIfType(token);
    if (peek != null && peek.isIdentifier()) {
      // We are looking at "type identifier".
      return peek;
    } else if (token.isIdentifier()) {
      // We are looking at "identifier".
      return token;
    } else {
      return null;
    }
  }

  Token parseExpressionStatementOrDeclaration(Token token) {
    assert(token.isIdentifier() || identical(token.stringValue, 'void'));
    Token identifier = peekIdentifierAfterType(token);
    if (identifier != null) {
      assert(identifier.isIdentifier());
      Token afterId = identifier.next;
      int afterIdKind = afterId.kind;
      if (identical(afterIdKind, EQ_TOKEN) ||
          identical(afterIdKind, SEMICOLON_TOKEN) ||
          identical(afterIdKind, COMMA_TOKEN)) {
        // We are looking at "type identifier" followed by '=', ';', ','.
        return parseVariablesDeclaration(token);
      } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
        // We are looking at "type identifier '('".
        BeginGroupToken beginParen = afterId;
        Token endParen = beginParen.endGroup;
        // TODO(eernst): Check for NPE as described in issue 26252.
        Token afterParens = endParen.next;
        if (optional('{', afterParens) ||
            optional('=>', afterParens) ||
            optional('async', afterParens) ||
            optional('sync', afterParens)) {
          // We are looking at "type identifier '(' ... ')'" followed
          // by '{', '=>', 'async', or 'sync'.
          return parseFunctionDeclaration(token);
        }
      } else if (identical(afterIdKind, LT_TOKEN)) {
        // We are looking at "type identifier '<'".
        BeginGroupToken beginAngle = afterId;
        Token endAngle = beginAngle.endGroup;
        if (endAngle != null &&
            identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
          BeginGroupToken beginParen = endAngle.next;
          Token endParen = beginParen.endGroup;
          if (endParen != null) {
            Token afterParens = endParen.next;
            if (optional('{', afterParens) ||
                optional('=>', afterParens) ||
                optional('async', afterParens) ||
                optional('sync', afterParens)) {
              // We are looking at "type identifier '<' ... '>' '(' ... ')'"
              // followed by '{', '=>', 'async', or 'sync'.
              return parseFunctionDeclaration(token);
            }
          }
        }
      }
      // Fall-through to expression statement.
    } else {
      if (optional(':', token.next)) {
        return parseLabeledStatement(token);
      } else if (optional('(', token.next)) {
        BeginGroupToken begin = token.next;
        // TODO(eernst): Check for NPE as described in issue 26252.
        String afterParens = begin.endGroup.next.stringValue;
        if (identical(afterParens, '{') ||
            identical(afterParens, '=>') ||
            identical(afterParens, 'async') ||
            identical(afterParens, 'sync')) {
          return parseFunctionDeclaration(token);
        }
      } else if (optional('<', token.next)) {
        BeginGroupToken beginAngle = token.next;
        Token endAngle = beginAngle.endGroup;
        if (endAngle != null &&
            identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
          BeginGroupToken beginParen = endAngle.next;
          Token endParen = beginParen.endGroup;
          if (endParen != null) {
            String afterParens = endParen.next.stringValue;
            if (identical(afterParens, '{') ||
                identical(afterParens, '=>') ||
                identical(afterParens, 'async') ||
                identical(afterParens, 'sync')) {
              return parseFunctionDeclaration(token);
            }
          }
        }
        // Fall through to expression statement.
      }
    }
    return parseExpressionStatement(token);
  }

  Token parseExpressionStatementOrConstDeclaration(Token token) {
    assert(identical(token.stringValue, 'const'));
    if (isModifier(token.next)) {
      return parseVariablesDeclaration(token);
    }
    Token identifier = peekIdentifierAfterOptionalType(token.next);
    if (identifier != null) {
      assert(identifier.isIdentifier());
      Token afterId = identifier.next;
      int afterIdKind = afterId.kind;
      if (identical(afterIdKind, EQ_TOKEN) ||
          identical(afterIdKind, SEMICOLON_TOKEN) ||
          identical(afterIdKind, COMMA_TOKEN)) {
        // We are looking at "const type identifier" followed by '=', ';', or
        // ','.
        return parseVariablesDeclaration(token);
      }
      // Fall-through to expression statement.
    }

    return parseExpressionStatement(token);
  }

  Token parseLabel(Token token) {
    token = parseIdentifier(token, IdentifierContext.labelDeclaration);
    Token colon = token;
    token = expect(':', token);
    listener.handleLabel(colon);
    return token;
  }

  Token parseLabeledStatement(Token token) {
    int labelCount = 0;
    do {
      token = parseLabel(token);
      labelCount++;
    } while (token.isIdentifier() && optional(':', token.next));
    listener.beginLabeledStatement(token, labelCount);
    token = parseStatement(token);
    listener.endLabeledStatement(labelCount);
    return token;
  }

  Token parseExpressionStatement(Token token) {
    listener.beginExpressionStatement(token);
    token = parseExpression(token);
    listener.endExpressionStatement(token);
    return expectSemicolon(token);
  }

  Token skipExpression(Token token) {
    while (true) {
      final kind = token.kind;
      final value = token.stringValue;
      if ((identical(kind, EOF_TOKEN)) ||
          (identical(value, ';')) ||
          (identical(value, ',')) ||
          (identical(value, '}')) ||
          (identical(value, ')')) ||
          (identical(value, ']'))) {
        break;
      }
      if (identical(value, '=') ||
          identical(value, '?') ||
          identical(value, ':') ||
          identical(value, '??')) {
        var nextValue = token.next.stringValue;
        if (identical(nextValue, 'const')) {
          token = token.next;
          nextValue = token.next.stringValue;
        }
        if (identical(nextValue, '{')) {
          // Handle cases like this:
          // class Foo {
          //   var map;
          //   Foo() : map = {};
          //   Foo.x() : map = true ? {} : {};
          // }
          BeginGroupToken begin = token.next;
          token = (begin.endGroup != null) ? begin.endGroup : token;
          token = token.next;
          continue;
        }
        if (identical(nextValue, '<')) {
          // Handle cases like this:
          // class Foo {
          //   var map;
          //   Foo() : map = <String, Foo>{};
          //   Foo.x() : map = true ? <String, Foo>{} : <String, Foo>{};
          // }
          BeginGroupToken begin = token.next;
          token = (begin.endGroup != null) ? begin.endGroup : token;
          token = token.next;
          if (identical(token.stringValue, '{')) {
            begin = token;
            token = (begin.endGroup != null) ? begin.endGroup : token;
            token = token.next;
          }
          continue;
        }
      }
      if (!mayParseFunctionExpressions && identical(value, '{')) {
        break;
      }
      if (token is BeginGroupToken) {
        BeginGroupToken begin = token;
        token = (begin.endGroup != null) ? begin.endGroup : token;
      } else if (token is ErrorToken) {
        reportErrorToken(token, false)?.next;
      }
      token = token.next;
    }
    return token;
  }

  Token parseRecoverExpression(Token token) => parseExpression(token);

  int expressionDepth = 0;
  Token parseExpression(Token token) {
    if (expressionDepth++ > 500) {
      // This happens in degenerate programs, for example, with a lot of nested
      // list literals. This is provoked by, for examaple, the language test
      // deep_nesting1_negative_test.
      return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next;
    }
    listener.beginExpression(token);
    Token result = optional('throw', token)
        ? parseThrowExpression(token, true)
        : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true);
    expressionDepth--;
    return result;
  }

  Token parseExpressionWithoutCascade(Token token) {
    listener.beginExpression(token);
    return optional('throw', token)
        ? parseThrowExpression(token, false)
        : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, false);
  }

  Token parseConditionalExpressionRest(Token token) {
    assert(optional('?', token));
    Token question = token;
    token = parseExpressionWithoutCascade(token.next);
    Token colon = token;
    token = expect(':', token);
    token = parseExpressionWithoutCascade(token);
    listener.handleConditionalExpression(question, colon);
    return token;
  }

  Token parsePrecedenceExpression(
      Token token, int precedence, bool allowCascades) {
    assert(precedence >= 1);
    assert(precedence <= POSTFIX_PRECEDENCE);
    token = parseUnaryExpression(token, allowCascades);
    PrecedenceInfo info = token.info;
    int tokenLevel = info.precedence;
    for (int level = tokenLevel; level >= precedence; --level) {
      while (identical(tokenLevel, level)) {
        Token operator = token;
        if (identical(tokenLevel, CASCADE_PRECEDENCE)) {
          if (!allowCascades) {
            return token;
          }
          token = parseCascadeExpression(token);
        } else if (identical(tokenLevel, ASSIGNMENT_PRECEDENCE)) {
          // Right associative, so we recurse at the same precedence
          // level.
          listener.beginExpression(token.next);
          token = parsePrecedenceExpression(token.next, level, allowCascades);
          listener.handleAssignmentExpression(operator);
        } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) {
          if (identical(info, PERIOD_INFO) ||
              identical(info, QUESTION_PERIOD_INFO)) {
            // Left associative, so we recurse at the next higher precedence
            // level. However, POSTFIX_PRECEDENCE is the highest level, so we
            // should just call [parseUnaryExpression] directly. However, a
            // unary expression isn't legal after a period, so we call
            // [parsePrimary] instead.
            token = parsePrimary(token.next);
            listener.handleBinaryExpression(operator);
          } else if ((identical(info, OPEN_PAREN_INFO)) ||
              (identical(info, OPEN_SQUARE_BRACKET_INFO))) {
            token = parseArgumentOrIndexStar(token);
          } else if ((identical(info, PLUS_PLUS_INFO)) ||
              (identical(info, MINUS_MINUS_INFO))) {
            listener.handleUnaryPostfixAssignmentExpression(token);
            token = token.next;
          } else {
            token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken)
                ?.next;
          }
        } else if (identical(info, IS_INFO)) {
          token = parseIsOperatorRest(token);
        } else if (identical(info, AS_INFO)) {
          token = parseAsOperatorRest(token);
        } else if (identical(info, QUESTION_INFO)) {
          token = parseConditionalExpressionRest(token);
        } else {
          // Left associative, so we recurse at the next higher
          // precedence level.
          listener.beginExpression(token.next);
          token =
              parsePrecedenceExpression(token.next, level + 1, allowCascades);
          listener.handleBinaryExpression(operator);
        }
        info = token.info;
        tokenLevel = info.precedence;
        if (level == EQUALITY_PRECEDENCE || level == RELATIONAL_PRECEDENCE) {
          // We don't allow (a == b == c) or (a < b < c).
          // Continue the outer loop if we have matched one equality or
          // relational operator.
          break;
        }
      }
    }
    return token;
  }

  Token parseCascadeExpression(Token token) {
    listener.beginCascade(token);
    assert(optional('..', token));
    Token cascadeOperator = token;
    token = token.next;
    if (optional('[', token)) {
      token = parseArgumentOrIndexStar(token);
    } else if (token.isIdentifier()) {
      token = parseSend(token, IdentifierContext.expressionContinuation);
      listener.handleBinaryExpression(cascadeOperator);
    } else {
      return reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
    }
    Token mark;
    do {
      mark = token;
      if (optional('.', token)) {
        Token period = token;
        token = parseSend(token.next, IdentifierContext.expressionContinuation);
        listener.handleBinaryExpression(period);
      }
      token = parseArgumentOrIndexStar(token);
    } while (!identical(mark, token));

    if (identical(token.info.precedence, ASSIGNMENT_PRECEDENCE)) {
      Token assignment = token;
      token = parseExpressionWithoutCascade(token.next);
      listener.handleAssignmentExpression(assignment);
    }
    listener.endCascade();
    return token;
  }

  Token parseUnaryExpression(Token token, bool allowCascades) {
    String value = token.stringValue;
    // Prefix:
    if (asyncAwaitKeywordsEnabled && optional('await', token)) {
      return parseAwaitExpression(token, allowCascades);
    } else if (identical(value, '+')) {
      // Dart no longer allows prefix-plus.
      reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus);
      return parseUnaryExpression(token.next, allowCascades);
    } else if ((identical(value, '!')) ||
        (identical(value, '-')) ||
        (identical(value, '~'))) {
      Token operator = token;
      // Right associative, so we recurse at the same precedence
      // level.
      token = parsePrecedenceExpression(
          token.next, POSTFIX_PRECEDENCE, allowCascades);
      listener.handleUnaryPrefixExpression(operator);
    } else if ((identical(value, '++')) || identical(value, '--')) {
      // TODO(ahe): Validate this is used correctly.
      Token operator = token;
      // Right associative, so we recurse at the same precedence
      // level.
      token = parsePrecedenceExpression(
          token.next, POSTFIX_PRECEDENCE, allowCascades);
      listener.handleUnaryPrefixAssignmentExpression(operator);
    } else {
      token = parsePrimary(token);
    }
    return token;
  }

  Token parseArgumentOrIndexStar(Token token) {
    Token beginToken = token;
    while (true) {
      if (optional('[', token)) {
        Token openSquareBracket = token;
        bool old = mayParseFunctionExpressions;
        mayParseFunctionExpressions = true;
        token = parseExpression(token.next);
        mayParseFunctionExpressions = old;
        listener.handleIndexedExpression(openSquareBracket, token);
        token = expect(']', token);
      } else if (optional('(', token)) {
        listener.handleNoTypeArguments(token);
        token = parseArguments(token);
        listener.endSend(beginToken, token);
      } else {
        break;
      }
    }
    return token;
  }

  Token parsePrimary(Token token) {
    final kind = token.kind;
    if (kind == IDENTIFIER_TOKEN) {
      return parseSendOrFunctionLiteral(token);
    } else if (kind == INT_TOKEN || kind == HEXADECIMAL_TOKEN) {
      return parseLiteralInt(token);
    } else if (kind == DOUBLE_TOKEN) {
      return parseLiteralDouble(token);
    } else if (kind == STRING_TOKEN) {
      return parseLiteralString(token);
    } else if (kind == HASH_TOKEN) {
      return parseLiteralSymbol(token);
    } else if (kind == KEYWORD_TOKEN) {
      final value = token.stringValue;
      if (value == 'true' || value == 'false') {
        return parseLiteralBool(token);
      } else if (value == 'null') {
        return parseLiteralNull(token);
      } else if (value == 'this') {
        return parseThisExpression(token);
      } else if (value == 'super') {
        return parseSuperExpression(token);
      } else if (value == 'new') {
        return parseNewExpression(token);
      } else if (value == 'const') {
        return parseConstExpression(token);
      } else if (value == 'void') {
        return parseFunctionExpression(token);
      } else if (asyncAwaitKeywordsEnabled &&
          (value == 'yield' || value == 'async')) {
        return expressionExpected(token);
      } else if (token.isIdentifier()) {
        return parseSendOrFunctionLiteral(token);
      } else {
        return expressionExpected(token);
      }
    } else if (kind == OPEN_PAREN_TOKEN) {
      return parseParenthesizedExpressionOrFunctionLiteral(token);
    } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || token.stringValue == '[]') {
      listener.handleNoTypeArguments(token);
      return parseLiteralListSuffix(token, null);
    } else if (kind == OPEN_CURLY_BRACKET_TOKEN) {
      listener.handleNoTypeArguments(token);
      return parseLiteralMapSuffix(token, null);
    } else if (kind == LT_TOKEN) {
      return parseLiteralListOrMapOrFunction(token, null);
    } else {
      return expressionExpected(token);
    }
  }

  Token expressionExpected(Token token) {
    token = reportUnrecoverableError(token, ErrorKind.ExpectedExpression)?.next;
    listener.handleInvalidExpression(token);
    return token;
  }

  Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
    BeginGroupToken beginGroup = token;
    // TODO(eernst): Check for NPE as described in issue 26252.
    Token nextToken = beginGroup.endGroup.next;
    int kind = nextToken.kind;
    if (mayParseFunctionExpressions &&
        (identical(kind, FUNCTION_TOKEN) ||
            identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
            (identical(kind, KEYWORD_TOKEN) &&
                (nextToken.lexeme == 'async' || nextToken.lexeme == 'sync')))) {
      listener.handleNoTypeVariables(token);
      return parseUnnamedFunction(token);
    } else {
      bool old = mayParseFunctionExpressions;
      mayParseFunctionExpressions = true;
      token = parseParenthesizedExpression(token);
      mayParseFunctionExpressions = old;
      return token;
    }
  }

  Token parseParenthesizedExpression(Token token) {
    // We expect [begin] to be of type [BeginGroupToken], but we don't know for
    // sure until after calling expect.
    dynamic begin = token;
    token = expect('(', token);
    // [begin] is now known to have type [BeginGroupToken].
    token = parseExpression(token);
    if (!identical(begin.endGroup, token)) {
      reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
      token = begin.endGroup;
    }
    listener.handleParenthesizedExpression(begin);
    return expect(')', token);
  }

  Token parseThisExpression(Token token) {
    Token beginToken = token;
    listener.handleThisExpression(token);
    token = token.next;
    if (optional('(', token)) {
      // Constructor forwarding.
      listener.handleNoTypeArguments(token);
      token = parseArguments(token);
      listener.endSend(beginToken, token);
    }
    return token;
  }

  Token parseSuperExpression(Token token) {
    Token beginToken = token;
    listener.handleSuperExpression(token);
    token = token.next;
    if (optional('(', token)) {
      // Super constructor.
      listener.handleNoTypeArguments(token);
      token = parseArguments(token);
      listener.endSend(beginToken, token);
    }
    return token;
  }

  /// '[' (expressionList ','?)? ']'.
  ///
  /// Provide [constKeyword] if preceded by 'const', null if not.
  /// This is a suffix parser because it is assumed that type arguments have
  /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
  Token parseLiteralListSuffix(Token token, Token constKeyword) {
    assert(optional('[', token) || optional('[]', token));
    Token beginToken = token;
    int count = 0;
    if (optional('[', token)) {
      bool old = mayParseFunctionExpressions;
      mayParseFunctionExpressions = true;
      do {
        if (optional(']', token.next)) {
          token = token.next;
          break;
        }
        token = parseExpression(token.next);
        ++count;
      } while (optional(',', token));
      mayParseFunctionExpressions = old;
      listener.handleLiteralList(count, beginToken, constKeyword, token);
      return expect(']', token);
    }
    // Looking at '[]'.
    listener.handleLiteralList(0, token, constKeyword, token);
    return token.next;
  }

  /// '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'.
  ///
  /// Provide token for [constKeyword] if preceded by 'const', null if not.
  /// This is a suffix parser because it is assumed that type arguments have
  /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
  Token parseLiteralMapSuffix(Token token, Token constKeyword) {
    assert(optional('{', token));
    Token beginToken = token;
    int count = 0;
    bool old = mayParseFunctionExpressions;
    mayParseFunctionExpressions = true;
    do {
      if (optional('}', token.next)) {
        token = token.next;
        break;
      }
      token = parseMapLiteralEntry(token.next);
      ++count;
    } while (optional(',', token));
    mayParseFunctionExpressions = old;
    listener.handleLiteralMap(count, beginToken, constKeyword, token);
    return expect('}', token);
  }

  /// formalParameterList functionBody.
  ///
  /// This is a suffix parser because it is assumed that type arguments have
  /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
  Token parseLiteralFunctionSuffix(Token token) {
    assert(optional('(', token));
    BeginGroupToken beginGroup = token;
    if (beginGroup.endGroup != null) {
      Token nextToken = beginGroup.endGroup.next;
      int kind = nextToken.kind;
      if (identical(kind, FUNCTION_TOKEN) ||
          identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
          (identical(kind, KEYWORD_TOKEN) &&
              (nextToken.lexeme == 'async' || nextToken.lexeme == 'sync'))) {
        return parseUnnamedFunction(token);
      }
      // Fall through.
    }
    reportUnrecoverableError(token, ErrorKind.UnexpectedToken);
    return null;
  }

  /// genericListLiteral | genericMapLiteral | genericFunctionLiteral.
  ///
  /// Where
  ///   genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']'
  ///   genericMapLiteral ::=
  ///       typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
  ///   genericFunctionLiteral ::=
  ///       typeParameters formalParameterList functionBody
  /// Provide token for [constKeyword] if preceded by 'const', null if not.
  Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
    assert(optional('<', token));
    BeginGroupToken begin = token;
    if (constKeyword == null &&
        begin.endGroup != null &&
        identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
      token = parseTypeVariablesOpt(token);
      return parseLiteralFunctionSuffix(token);
    } else {
      token = parseTypeArgumentsOpt(token);
      if (optional('{', token)) {
        return parseLiteralMapSuffix(token, constKeyword);
      } else if ((optional('[', token)) || (optional('[]', token))) {
        return parseLiteralListSuffix(token, constKeyword);
      }
      reportUnrecoverableError(token, ErrorKind.UnexpectedToken);
      return null;
    }
  }

  Token parseMapLiteralEntry(Token token) {
    listener.beginLiteralMapEntry(token);
    // Assume the listener rejects non-string keys.
    token = parseExpression(token);
    Token colon = token;
    token = expect(':', token);
    token = parseExpression(token);
    listener.endLiteralMapEntry(colon, token);
    return token;
  }

  Token parseSendOrFunctionLiteral(Token token) {
    if (!mayParseFunctionExpressions) {
      return parseSend(token, IdentifierContext.expression);
    }
    Token peek = peekAfterIfType(token);
    if (peek != null &&
        identical(peek.kind, IDENTIFIER_TOKEN) &&
        isFunctionDeclaration(peek.next)) {
      return parseFunctionExpression(token);
    } else if (isFunctionDeclaration(token.next)) {
      return parseFunctionExpression(token);
    } else {
      return parseSend(token, IdentifierContext.expression);
    }
  }

  bool isFunctionDeclaration(Token token) {
    if (optional('<', token)) {
      BeginGroupToken begin = token;
      if (begin.endGroup == null) return false;
      token = begin.endGroup.next;
    }
    if (optional('(', token)) {
      BeginGroupToken begin = token;
      // TODO(eernst): Check for NPE as described in issue 26252.
      String afterParens = begin.endGroup.next.stringValue;
      if (identical(afterParens, '{') ||
          identical(afterParens, '=>') ||
          identical(afterParens, 'async') ||
          identical(afterParens, 'sync')) {
        return true;
      }
    }
    return false;
  }

  Token parseRequiredArguments(Token token) {
    if (optional('(', token)) {
      token = parseArguments(token);
    } else {
      listener.handleNoArguments(token);
      token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
    }
    return token;
  }

  Token parseNewExpression(Token token) {
    Token newKeyword = token;
    token = expect('new', token);
    token = parseConstructorReference(token);
    token = parseRequiredArguments(token);
    listener.handleNewExpression(newKeyword);
    return token;
  }

  Token parseConstExpression(Token token) {
    Token constKeyword = token;
    token = expect('const', token);
    final String value = token.stringValue;
    if ((identical(value, '[')) || (identical(value, '[]'))) {
      listener.handleNoTypeArguments(token);
      return parseLiteralListSuffix(token, constKeyword);
    }
    if (identical(value, '{')) {
      listener.handleNoTypeArguments(token);
      return parseLiteralMapSuffix(token, constKeyword);
    }
    if (identical(value, '<')) {
      return parseLiteralListOrMapOrFunction(token, constKeyword);
    }
    token = parseConstructorReference(token);
    token = parseRequiredArguments(token);
    listener.handleConstExpression(constKeyword);
    return token;
  }

  Token parseLiteralInt(Token token) {
    listener.handleLiteralInt(token);
    return token.next;
  }

  Token parseLiteralDouble(Token token) {
    listener.handleLiteralDouble(token);
    return token.next;
  }

  Token parseLiteralString(Token token) {
    bool old = mayParseFunctionExpressions;
    mayParseFunctionExpressions = true;
    token = parseSingleLiteralString(token);
    int count = 1;
    while (identical(token.kind, STRING_TOKEN)) {
      token = parseSingleLiteralString(token);
      count++;
    }
    if (count > 1) {
      listener.handleStringJuxtaposition(count);
    }
    mayParseFunctionExpressions = old;
    return token;
  }

  Token parseLiteralSymbol(Token token) {
    Token hashToken = token;
    listener.beginLiteralSymbol(hashToken);
    token = token.next;
    if (isUserDefinableOperator(token.stringValue)) {
      listener.handleOperator(token);
      listener.endLiteralSymbol(hashToken, 1);
      return token.next;
    } else if (identical(token.stringValue, 'void')) {
      listener.handleSymbolVoid(token);
      listener.endLiteralSymbol(hashToken, 1);
      return token.next;
    } else {
      int count = 1;
      token = parseIdentifier(token, IdentifierContext.literalSymbol);
      while (identical(token.stringValue, '.')) {
        count++;
        token = parseIdentifier(
            token.next, IdentifierContext.literalSymbolContinuation);
      }
      listener.endLiteralSymbol(hashToken, count);
      return token;
    }
  }

  /**
   * Only called when [:token.kind === STRING_TOKEN:].
   */
  Token parseSingleLiteralString(Token token) {
    listener.beginLiteralString(token);
    // Parsing the prefix, for instance 'x of 'x${id}y${id}z'
    token = token.next;
    int interpolationCount = 0;
    var kind = token.kind;
    while (kind != EOF_TOKEN) {
      if (identical(kind, STRING_INTERPOLATION_TOKEN)) {
        // Parsing ${expression}.
        token = token.next;
        token = parseExpression(token);
        token = expect('}', token);
      } else if (identical(kind, STRING_INTERPOLATION_IDENTIFIER_TOKEN)) {
        // Parsing $identifier.
        token = token.next;
        token = parseExpression(token);
      } else {
        break;
      }
      ++interpolationCount;
      // Parsing the infix/suffix, for instance y and z' of 'x${id}y${id}z'
      token = parseStringPart(token);
      kind = token.kind;
    }
    listener.endLiteralString(interpolationCount, token);
    return token;
  }

  Token parseLiteralBool(Token token) {
    listener.handleLiteralBool(token);
    return token.next;
  }

  Token parseLiteralNull(Token token) {
    listener.handleLiteralNull(token);
    return token.next;
  }

  Token parseSend(Token token, IdentifierContext context) {
    Token beginToken = token;
    listener.beginSend(token);
    token = parseIdentifier(token, context);
    if (isValidMethodTypeArguments(token)) {
      token = parseTypeArgumentsOpt(token);
    } else {
      listener.handleNoTypeArguments(token);
    }
    token = parseArgumentsOpt(token);
    listener.endSend(beginToken, token);
    return token;
  }

  Token skipArgumentsOpt(Token token) {
    listener.handleNoArguments(token);
    if (optional('(', token)) {
      BeginGroupToken begin = token;
      return begin.endGroup.next;
    } else {
      return token;
    }
  }

  Token parseArgumentsOpt(Token token) {
    if (!optional('(', token)) {
      listener.handleNoArguments(token);
      return token;
    } else {
      return parseArguments(token);
    }
  }

  Token parseArguments(Token token) {
    Token begin = token;
    listener.beginArguments(begin);
    assert(identical('(', token.stringValue));
    int argumentCount = 0;
    if (optional(')', token.next)) {
      listener.endArguments(argumentCount, begin, token.next);
      return token.next.next;
    }
    bool old = mayParseFunctionExpressions;
    mayParseFunctionExpressions = true;
    do {
      if (optional(')', token.next)) {
        token = token.next;
        break;
      }
      Token colon = null;
      if (optional(':', token.next.next)) {
        token = parseIdentifier(
            token.next, IdentifierContext.namedArgumentReference);
        colon = token;
      }
      token = parseExpression(token.next);
      if (colon != null) listener.handleNamedArgument(colon);
      ++argumentCount;
    } while (optional(',', token));
    mayParseFunctionExpressions = old;
    listener.endArguments(argumentCount, begin, token);
    return expect(')', token);
  }

  Token parseIsOperatorRest(Token token) {
    assert(optional('is', token));
    Token operator = token;
    Token not = null;
    if (optional('!', token.next)) {
      token = token.next;
      not = token;
    }
    token = parseType(token.next);
    listener.handleIsOperator(operator, not, token);
    String value = token.stringValue;
    if (identical(value, 'is') || identical(value, 'as')) {
      // The is- and as-operators cannot be chained, but they can take part of
      // expressions like: foo is Foo || foo is Bar.
      reportUnrecoverableError(token, ErrorKind.UnexpectedToken);
    }
    return token;
  }

  Token parseAsOperatorRest(Token token) {
    assert(optional('as', token));
    Token operator = token;
    token = parseType(token.next);
    listener.handleAsOperator(operator, token);
    String value = token.stringValue;
    if (identical(value, 'is') || identical(value, 'as')) {
      // The is- and as-operators cannot be chained.
      reportUnrecoverableError(token, ErrorKind.UnexpectedToken);
    }
    return token;
  }

  Token parseVariablesDeclaration(Token token) {
    return parseVariablesDeclarationMaybeSemicolon(token, true);
  }

  Token parseVariablesDeclarationNoSemicolon(Token token) {
    // Only called when parsing a for loop, so this is for parsing locals.
    return parseVariablesDeclarationMaybeSemicolon(token, false);
  }

  Token parseVariablesDeclarationMaybeSemicolon(
      Token token, bool endWithSemicolon) {
    int count = 1;
    listener.beginVariablesDeclaration(token);
    token = parseModifiers(token);
    token = parseTypeOpt(token);
    token = parseOptionallyInitializedIdentifier(token);
    while (optional(',', token)) {
      token = parseOptionallyInitializedIdentifier(token.next);
      ++count;
    }
    if (endWithSemicolon) {
      Token semicolon = token;
      token = expectSemicolon(semicolon);
      listener.endVariablesDeclaration(count, semicolon);
      return token;
    } else {
      listener.endVariablesDeclaration(count, null);
      return token;
    }
  }

  Token parseOptionallyInitializedIdentifier(Token token) {
    Token nameToken = token;
    listener.beginInitializedIdentifier(token);
    token = parseIdentifier(token, IdentifierContext.localVariableDeclaration);
    token = parseVariableInitializerOpt(token);
    listener.endInitializedIdentifier(nameToken);
    return token;
  }

  Token parseIfStatement(Token token) {
    Token ifToken = token;
    listener.beginIfStatement(ifToken);
    token = expect('if', token);
    token = parseParenthesizedExpression(token);
    listener.beginThenStatement(token);
    token = parseStatement(token);
    listener.endThenStatement(token);
    Token elseToken = null;
    if (optional('else', token)) {
      elseToken = token;
      listener.beginElseStatement(token);
      token = parseStatement(token.next);
      listener.endElseStatement(token);
    }
    listener.endIfStatement(ifToken, elseToken);
    return token;
  }

  Token parseForStatement(Token awaitToken, Token token) {
    Token forKeyword = token;
    listener.beginForStatement(forKeyword);
    token = expect('for', token);
    Token leftParenthesis = token;
    token = expect('(', token);
    token = parseVariablesDeclarationOrExpressionOpt(token);
    if (optional('in', token)) {
      return parseForInRest(awaitToken, forKeyword, leftParenthesis, token);
    } else {
      if (awaitToken != null) {
        reportRecoverableError(awaitToken, ErrorKind.InvalidAwaitFor);
      }
      return parseForRest(forKeyword, leftParenthesis, token);
    }
  }

  Token parseVariablesDeclarationOrExpressionOpt(Token token) {
    final String value = token.stringValue;
    if (identical(value, ';')) {
      listener.handleNoExpression(token);
      return token;
    } else if (isOneOf3(token, 'var', 'final', 'const')) {
      return parseVariablesDeclarationNoSemicolon(token);
    }
    Token identifier = peekIdentifierAfterType(token);
    if (identifier != null) {
      assert(identifier.isIdentifier());
      if (isOneOf4(identifier.next, '=', ';', ',', 'in')) {
        return parseVariablesDeclarationNoSemicolon(token);
      }
    }
    return parseExpression(token);
  }

  Token parseForRest(Token forToken, Token leftParenthesis, Token token) {
    Token leftSeparator = token;
    token = expectSemicolon(token);
    if (optional(';', token)) {
      token = parseEmptyStatement(token);
    } else {
      token = parseExpressionStatement(token);
    }
    int expressionCount = 0;
    while (true) {
      if (optional(')', token)) break;
      token = parseExpression(token);
      ++expressionCount;
      if (optional(',', token)) {
        token = token.next;
      } else {
        break;
      }
    }
    token = expect(')', token);
    listener.beginForStatementBody(token);
    token = parseStatement(token);
    listener.endForStatementBody(token);
    listener.endForStatement(forToken, leftSeparator, expressionCount, token);
    return token;
  }

  Token parseForInRest(
      Token awaitToken, Token forKeyword, Token leftParenthesis, Token token) {
    assert(optional('in', token));
    Token inKeyword = token;
    token = token.next;
    listener.beginForInExpression(token);
    token = parseExpression(token);
    listener.endForInExpression(token);
    Token rightParenthesis = token;
    token = expect(')', token);
    listener.beginForInBody(token);
    token = parseStatement(token);
    listener.endForInBody(token);
    listener.endForIn(awaitToken, forKeyword, leftParenthesis, inKeyword,
        rightParenthesis, token);
    return token;
  }

  Token parseWhileStatement(Token token) {
    Token whileToken = token;
    listener.beginWhileStatement(whileToken);
    token = expect('while', token);
    token = parseParenthesizedExpression(token);
    listener.beginWhileStatementBody(token);
    token = parseStatement(token);
    listener.endWhileStatementBody(token);
    listener.endWhileStatement(whileToken, token);
    return token;
  }

  Token parseDoWhileStatement(Token token) {
    Token doToken = token;
    listener.beginDoWhileStatement(doToken);
    token = expect('do', token);
    listener.beginDoWhileStatementBody(token);
    token = parseStatement(token);
    listener.endDoWhileStatementBody(token);
    Token whileToken = token;
    token = expect('while', token);
    token = parseParenthesizedExpression(token);
    listener.endDoWhileStatement(doToken, whileToken, token);
    return expectSemicolon(token);
  }

  Token parseBlock(Token token) {
    Token begin = token;
    listener.beginBlock(begin);
    int statementCount = 0;
    token = expect('{', token);
    while (notEofOrValue('}', token)) {
      token = parseStatement(token);
      ++statementCount;
    }
    listener.endBlock(statementCount, begin, token);
    return expect('}', token);
  }

  Token parseAwaitExpression(Token token, bool allowCascades) {
    Token awaitToken = token;
    listener.beginAwaitExpression(awaitToken);
    token = expect('await', token);
    token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades);
    listener.endAwaitExpression(awaitToken, token);
    return token;
  }

  Token parseThrowExpression(Token token, bool allowCascades) {
    Token throwToken = token;
    listener.beginThrowExpression(throwToken);
    token = expect('throw', token);
    token = allowCascades
        ? parseExpression(token)
        : parseExpressionWithoutCascade(token);
    listener.endThrowExpression(throwToken, token);
    return token;
  }

  Token parseRethrowStatement(Token token) {
    Token throwToken = token;
    listener.beginRethrowStatement(throwToken);
    // TODO(kasperl): Disallow throw here.
    if (identical(throwToken.stringValue, 'throw')) {
      token = expect('throw', token);
    } else {
      token = expect('rethrow', token);
    }
    listener.endRethrowStatement(throwToken, token);
    return expectSemicolon(token);
  }

  Token parseTryStatement(Token token) {
    assert(optional('try', token));
    Token tryKeyword = token;
    listener.beginTryStatement(tryKeyword);
    token = parseBlock(token.next);
    int catchCount = 0;

    String value = token.stringValue;
    while (identical(value, 'catch') || identical(value, 'on')) {
      listener.beginCatchClause(token);
      var onKeyword = null;
      if (identical(value, 'on')) {
        // on qualified catchPart?
        onKeyword = token;
        token = parseType(token.next);
        value = token.stringValue;
      }
      Token catchKeyword = null;
      if (identical(value, 'catch')) {
        catchKeyword = token;
        // TODO(ahe): Validate the "parameters".
        token = parseFormalParameters(token.next);
      }
      listener.endCatchClause(token);
      token = parseBlock(token);
      ++catchCount;
      listener.handleCatchBlock(onKeyword, catchKeyword);
      value = token.stringValue; // while condition
    }

    Token finallyKeyword = null;
    if (optional('finally', token)) {
      finallyKeyword = token;
      token = parseBlock(token.next);
      listener.handleFinallyBlock(finallyKeyword);
    }
    listener.endTryStatement(catchCount, tryKeyword, finallyKeyword);
    return token;
  }

  Token parseSwitchStatement(Token token) {
    assert(optional('switch', token));
    Token switchKeyword = token;
    listener.beginSwitchStatement(switchKeyword);
    token = parseParenthesizedExpression(token.next);
    token = parseSwitchBlock(token);
    listener.endSwitchStatement(switchKeyword, token);
    return token.next;
  }

  Token parseSwitchBlock(Token token) {
    Token begin = token;
    listener.beginSwitchBlock(begin);
    token = expect('{', token);
    int caseCount = 0;
    while (!identical(token.kind, EOF_TOKEN)) {
      if (optional('}', token)) {
        break;
      }
      token = parseSwitchCase(token);
      ++caseCount;
    }
    listener.endSwitchBlock(caseCount, begin, token);
    expect('}', token);
    return token;
  }

  /**
   * Peek after the following labels (if any). The following token
   * is used to determine if the labels belong to a statement or a
   * switch case.
   */
  Token peekPastLabels(Token token) {
    while (token.isIdentifier() && optional(':', token.next)) {
      token = token.next.next;
    }
    return token;
  }

  /**
   * Parse a group of labels, cases and possibly a default keyword and
   * the statements that they select.
   */
  Token parseSwitchCase(Token token) {
    Token begin = token;
    Token defaultKeyword = null;
    int expressionCount = 0;
    int labelCount = 0;
    Token peek = peekPastLabels(token);
    while (true) {
      // Loop until we find something that can't be part of a switch case.
      String value = peek.stringValue;
      if (identical(value, 'default')) {
        while (!identical(token, peek)) {
          token = parseLabel(token);
          labelCount++;
        }
        defaultKeyword = token;
        token = expect(':', token.next);
        peek = token;
        break;
      } else if (identical(value, 'case')) {
        while (!identical(token, peek)) {
          token = parseLabel(token);
          labelCount++;
        }
        Token caseKeyword = token;
        token = parseExpression(token.next);
        Token colonToken = token;
        token = expect(':', token);
        listener.handleCaseMatch(caseKeyword, colonToken);
        expressionCount++;
        peek = peekPastLabels(token);
      } else {
        if (expressionCount == 0) {
          // TODO(ahe): This is probably easy to recover from.
          reportUnrecoverableError(
              token, ErrorKind.ExpectedButGot, {"expected": "case"});
        }
        break;
      }
    }
    listener.beginSwitchCase(labelCount, expressionCount, begin);
    // Finally zero or more statements.
    int statementCount = 0;
    while (!identical(token.kind, EOF_TOKEN)) {
      String value = peek.stringValue;
      if ((identical(value, 'case')) ||
          (identical(value, 'default')) ||
          ((identical(value, '}')) && (identical(token, peek)))) {
        // A label just before "}" will be handled as a statement error.
        break;
      } else {
        token = parseStatement(token);
      }
      statementCount++;
      peek = peekPastLabels(token);
    }
    listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
        statementCount, begin, token);
    return token;
  }

  Token parseBreakStatement(Token token) {
    assert(optional('break', token));
    Token breakKeyword = token;
    token = token.next;
    bool hasTarget = false;
    if (token.isIdentifier()) {
      token = parseIdentifier(token, IdentifierContext.labelReference);
      hasTarget = true;
    }
    listener.handleBreakStatement(hasTarget, breakKeyword, token);
    return expectSemicolon(token);
  }

  Token parseAssertStatement(Token token) {
    Token assertKeyword = token;
    Token commaToken = null;
    token = expect('assert', token);
    Token leftParenthesis = token;
    token = expect('(', token);
    bool old = mayParseFunctionExpressions;
    mayParseFunctionExpressions = true;
    token = parseExpression(token);
    if (optional(',', token)) {
      commaToken = token;
      token = token.next;
      token = parseExpression(token);
    }
    Token rightParenthesis = token;
    token = expect(')', token);
    mayParseFunctionExpressions = old;
    listener.handleAssertStatement(
        assertKeyword, leftParenthesis, commaToken, rightParenthesis, token);
    return expectSemicolon(token);
  }

  Token parseContinueStatement(Token token) {
    assert(optional('continue', token));
    Token continueKeyword = token;
    token = token.next;
    bool hasTarget = false;
    if (token.isIdentifier()) {
      token = parseIdentifier(token, IdentifierContext.labelReference);
      hasTarget = true;
    }
    listener.handleContinueStatement(hasTarget, continueKeyword, token);
    return expectSemicolon(token);
  }

  Token parseEmptyStatement(Token token) {
    listener.handleEmptyStatement(token);
    return expectSemicolon(token);
  }

  /// Don't call this method. Should only be used as a last resort when there
  /// is no feasible way to recover from a parser error.
  Token reportUnrecoverableError(Token token, ErrorKind kind, [Map arguments]) {
    Token next;
    if (token is ErrorToken) {
      next = reportErrorToken(token, false);
    } else {
      arguments ??= {};
      arguments.putIfAbsent("actual", () => token.lexeme);
      next = listener.handleUnrecoverableError(token, kind, arguments);
    }
    return next ?? skipToEof(token);
  }

  void reportRecoverableError(Token token, ErrorKind kind, [Map arguments]) {
    if (token is ErrorToken) {
      reportErrorToken(token, true);
    } else {
      arguments ??= {};
      listener.handleRecoverableError(token, kind, arguments);
    }
  }

  Token reportErrorToken(ErrorToken token, bool isRecoverable) {
    ErrorKind kind = token.errorCode;
    Map arguments = const {};
    switch (kind) {
      case ErrorKind.AsciiControlCharacter:
      case ErrorKind.NonAsciiIdentifier:
      case ErrorKind.NonAsciiWhitespace:
      case ErrorKind.Encoding:
        String hex = token.character.toRadixString(16);
        if (hex.length < 4) {
          String padding = "0000".substring(hex.length);
          hex = "$padding$hex";
        }
        arguments = {'characterHex': hex};
        break;

      case ErrorKind.UnterminatedString:
        arguments = {'quote': token.start};
        break;

      case ErrorKind.UnmatchedToken:
        String begin = token.begin.lexeme;
        String end = closeBraceFor(begin);
        arguments = {'begin': begin, 'end': end};
        break;

      case ErrorKind.Unspecified:
        arguments = {"text": token.assertionMessage};
        break;

      default:
        break;
    }
    if (isRecoverable) {
      listener.handleRecoverableError(token, kind, arguments);
      return null;
    } else {
      return listener.handleUnrecoverableError(token, kind, arguments);
    }
  }
}
