// Copyright (c) 2019, 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.

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/tokens_context.dart';

var timerAstBinaryReader = Stopwatch();
var timerAstBinaryReaderClass = Stopwatch();
var timerAstBinaryReaderDirective = Stopwatch();
var timerAstBinaryReaderFunctionBody = Stopwatch();
var timerAstBinaryReaderFunctionDeclaration = Stopwatch();
var timerAstBinaryReaderMixin = Stopwatch();
var timerAstBinaryReaderTopLevelVar = Stopwatch();

/// Deserializer of fully resolved ASTs from flat buffers.
class AstBinaryReader {
  final LinkedUnitContext _unitContext;

  /// Set to `true` when this reader is used to lazily read its unit.
  bool isLazy = false;

  /// Whether we are reading a directive.
  ///
  /// [StringLiteral]s in directives are not actual expressions, and don't need
  /// a type. Moreover, when we are reading `dart:core` imports, the type
  /// provider is not ready yet, so we cannot access type `String`.
  bool _isReadingDirective = false;

  AstBinaryReader(this._unitContext);

  InterfaceType get _boolType => _unitContext.typeProvider.boolType;

  InterfaceType get _doubleType => _unitContext.typeProvider.doubleType;

  InterfaceType get _intType => _unitContext.typeProvider.intType;

  DartType get _nullType => _unitContext.typeProvider.nullType;

  InterfaceType get _stringType => _unitContext.typeProvider.stringType;

  /// This method is invoked by [LinkedUnitContext] to finish reading.
  void readGenericFunctionTypeFinish(
    LinkedNode data,
    GenericFunctionType node,
  ) {
    var typeParameterListData = data.genericFunctionType_typeParameters;
    if (typeParameterListData != null) {
      var dataList = typeParameterListData.typeParameterList_typeParameters;
      var typeParameters = node.typeParameters.typeParameters;
      for (var i = 0; i < dataList.length; ++i) {
        var data = dataList[i];
        var node = typeParameters[i];
        node.bound = _readNode(data.typeParameter_bound);
      }
    }
    node.returnType = readNode(data.genericFunctionType_returnType);
    node.parameters = _readNode(data.genericFunctionType_formalParameters);
  }

  /// This method is invoked by [LinkedUnitContext] to perform shallow reading.
  ///
  /// It reads [TypeParameter] names, and creates [GenericFunctionType] node,
  /// so that [LinkedUnitContext] can create elements for these nodes.
  ///
  /// But we cannot read the return type and formal parameters yet, until the
  /// corresponding elements are created.
  GenericFunctionType readGenericFunctionTypeShallow(LinkedNode data) {
    TypeParameterList typeParameterList;
    var typeParameterListData = data.genericFunctionType_typeParameters;
    if (typeParameterListData != null) {
      var dataList = typeParameterListData.typeParameterList_typeParameters;
      var typeParameters = List<TypeParameter>(dataList.length);
      for (var i = 0; i < dataList.length; ++i) {
        var data = dataList[i];
        typeParameters[i] = astFactory.typeParameter(
          _readNode(data.annotatedNode_comment),
          _readNodeList(data.annotatedNode_metadata),
          _readNode(data.typeParameter_name),
          data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
          null,
        );
      }
      typeParameterList = astFactory.typeParameterList(
        _Tokens.LT,
        typeParameters,
        _Tokens.GT,
      );
    }

    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
      null,
      _Tokens.FUNCTION,
      typeParameterList,
      null,
      question:
          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
    );
    node.type = _readType(data.genericFunctionType_type);
    return node;
  }

  AstNode readNode(LinkedNode data) {
    timerAstBinaryReader.start();
    try {
      return _readNode(data);
    } finally {
      timerAstBinaryReader.stop();
    }
  }

  DartType readType(LinkedNodeType data) {
    return _readType(data);
  }

  Element _elementOfComponents(
    int rawElementIndex,
    LinkedNodeType definingTypeNode,
  ) {
    var element = _getElement(rawElementIndex);
    if (definingTypeNode == null) return element;

    var definingType = _readType(definingTypeNode);
    if (element is ConstructorElement) {
      return ConstructorMember.from(element, definingType);
    } else if (element is MethodElement) {
      return MethodMember.from(element, definingType);
    } else if (element is PropertyAccessorElement) {
      return PropertyAccessorMember.from(element, definingType);
    } else {
      throw UnimplementedError('(${element.runtimeType}) $element');
    }
  }

  T _getElement<T extends Element>(int index) {
    var bundleContext = _unitContext.bundleContext;
    return bundleContext.elementOfIndex(index);
  }

  AdjacentStrings _read_adjacentStrings(LinkedNode data) {
    var node = astFactory.adjacentStrings(
      _readNodeList(data.adjacentStrings_strings),
    );
    if (!_isReadingDirective) {
      node.staticType = _stringType;
    }
    return node;
  }

  Annotation _read_annotation(LinkedNode data) {
    return astFactory.annotation(
      _Tokens.AT,
      _readNode(data.annotation_name),
      _Tokens.PERIOD,
      _readNode(data.annotation_constructorName),
      _readNode(data.annotation_arguments),
    )..element = _elementOfComponents(
        data.annotation_element,
        data.annotation_elementType,
      );
  }

  ArgumentList _read_argumentList(LinkedNode data) {
    return astFactory.argumentList(
      _Tokens.OPEN_PAREN,
      _readNodeList(data.argumentList_arguments),
      _Tokens.CLOSE_PAREN,
    );
  }

  AsExpression _read_asExpression(LinkedNode data) {
    return astFactory.asExpression(
      _readNode(data.asExpression_expression),
      _Tokens.AS,
      _readNode(data.asExpression_type),
    )..staticType = _readType(data.expression_type);
  }

  AssertInitializer _read_assertInitializer(LinkedNode data) {
    return astFactory.assertInitializer(
      _Tokens.ASSERT,
      _Tokens.OPEN_PAREN,
      _readNode(data.assertInitializer_condition),
      _Tokens.COMMA,
      _readNode(data.assertInitializer_message),
      _Tokens.CLOSE_PAREN,
    );
  }

  AssertStatement _read_assertStatement(LinkedNode data) {
    return astFactory.assertStatement(
      _Tokens.AS,
      _Tokens.OPEN_PAREN,
      _readNode(data.assertStatement_condition),
      _Tokens.COMMA,
      _readNode(data.assertStatement_message),
      _Tokens.CLOSE_PAREN,
      _Tokens.SEMICOLON,
    );
  }

  AssignmentExpression _read_assignmentExpression(LinkedNode data) {
    return astFactory.assignmentExpression(
      _readNode(data.assignmentExpression_leftHandSide),
      _Tokens.fromType(data.assignmentExpression_operator),
      _readNode(data.assignmentExpression_rightHandSide),
    )
      ..staticElement = _elementOfComponents(
        data.assignmentExpression_element,
        data.assignmentExpression_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  AwaitExpression _read_awaitExpression(LinkedNode data) {
    return astFactory.awaitExpression(
      _Tokens.AWAIT,
      _readNode(data.awaitExpression_expression),
    )..staticType = _readType(data.expression_type);
  }

  BinaryExpression _read_binaryExpression(LinkedNode data) {
    return astFactory.binaryExpression(
      _readNode(data.binaryExpression_leftOperand),
      _Tokens.fromType(data.binaryExpression_operator),
      _readNode(data.binaryExpression_rightOperand),
    )
      ..staticElement = _elementOfComponents(
        data.binaryExpression_element,
        data.binaryExpression_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  Block _read_block(LinkedNode data) {
    return astFactory.block(
      _Tokens.OPEN_CURLY_BRACKET,
      _readNodeList(data.block_statements),
      _Tokens.CLOSE_CURLY_BRACKET,
    );
  }

  BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
    timerAstBinaryReaderFunctionBody.start();
    try {
      return astFactory.blockFunctionBody(
        _Tokens.choose(
          AstBinaryFlags.isAsync(data.flags),
          _Tokens.ASYNC,
          AstBinaryFlags.isSync(data.flags),
          _Tokens.SYNC,
        ),
        AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
        _readNode(data.blockFunctionBody_block),
      );
    } finally {
      timerAstBinaryReaderFunctionBody.stop();
    }
  }

  BooleanLiteral _read_booleanLiteral(LinkedNode data) {
    return AstTestFactory.booleanLiteral(data.booleanLiteral_value)
      ..staticType = _boolType;
  }

  BreakStatement _read_breakStatement(LinkedNode data) {
    return astFactory.breakStatement(
      _Tokens.BREAK,
      _readNode(data.breakStatement_label),
      _Tokens.SEMICOLON,
    );
  }

  CascadeExpression _read_cascadeExpression(LinkedNode data) {
    return astFactory.cascadeExpression(
      _readNode(data.cascadeExpression_target),
      _readNodeList(data.cascadeExpression_sections),
    )..staticType = _readType(data.expression_type);
  }

  CatchClause _read_catchClause(LinkedNode data) {
    var exceptionType = _readNode(data.catchClause_exceptionType);
    var exceptionParameter = _readNode(data.catchClause_exceptionParameter);
    var stackTraceParameter = _readNode(data.catchClause_stackTraceParameter);
    return astFactory.catchClause(
      exceptionType != null ? _Tokens.ON : null,
      exceptionType,
      exceptionParameter != null ? _Tokens.CATCH : null,
      exceptionParameter != null ? _Tokens.OPEN_PAREN : null,
      exceptionParameter,
      stackTraceParameter != null ? _Tokens.COMMA : null,
      stackTraceParameter,
      exceptionParameter != null ? _Tokens.CLOSE_PAREN : null,
      _readNode(data.catchClause_body),
    );
  }

  ClassDeclaration _read_classDeclaration(LinkedNode data) {
    timerAstBinaryReaderClass.start();
    try {
      var node = astFactory.classDeclaration(
        _readNodeLazy(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
        _Tokens.CLASS,
        _readNode(data.namedCompilationUnitMember_name),
        _readNode(data.classOrMixinDeclaration_typeParameters),
        _readNodeLazy(data.classDeclaration_extendsClause),
        _readNodeLazy(data.classDeclaration_withClause),
        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
        _Tokens.OPEN_CURLY_BRACKET,
        _readNodeListLazy(data.classOrMixinDeclaration_members),
        _Tokens.CLOSE_CURLY_BRACKET,
      );
      node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
      LazyClassDeclaration.setData(node, data);
      return node;
    } finally {
      timerAstBinaryReaderClass.stop();
    }
  }

  ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
    timerAstBinaryReaderClass.start();
    try {
      var node = astFactory.classTypeAlias(
        _readNodeLazy(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.CLASS,
        _readNode(data.namedCompilationUnitMember_name),
        _readNode(data.classTypeAlias_typeParameters),
        _Tokens.EQ,
        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
        _readNodeLazy(data.classTypeAlias_superclass),
        _readNodeLazy(data.classTypeAlias_withClause),
        _readNodeLazy(data.classTypeAlias_implementsClause),
        _Tokens.SEMICOLON,
      );
      LazyClassTypeAlias.setData(node, data);
      return node;
    } finally {
      timerAstBinaryReaderClass.stop();
    }
  }

  Comment _read_comment(LinkedNode data) {
    var tokens = data.comment_tokens
        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
        .toList();
    switch (data.comment_type) {
      case LinkedNodeCommentType.block:
        return astFactory.endOfLineComment(
          tokens,
        );
      case LinkedNodeCommentType.documentation:
        return astFactory.documentationComment(
          tokens,
          _readNodeList(data.comment_references),
        );
      case LinkedNodeCommentType.endOfLine:
        return astFactory.endOfLineComment(
          tokens,
        );
      default:
        throw StateError('${data.comment_type}');
    }
  }

  CommentReference _read_commentReference(LinkedNode data) {
    return astFactory.commentReference(
      AstBinaryFlags.isNew(data.flags) ? _Tokens.NEW : null,
      _readNode(data.commentReference_identifier),
    );
  }

  CompilationUnit _read_compilationUnit(LinkedNode data) {
    return astFactory.compilationUnit2(
        beginToken: null,
        scriptTag: _readNode(data.compilationUnit_scriptTag),
        directives: _readNodeList(data.compilationUnit_directives),
        declarations: _readNodeList(data.compilationUnit_declarations),
        endToken: null,
        featureSet: null);
  }

  ConditionalExpression _read_conditionalExpression(LinkedNode data) {
    return astFactory.conditionalExpression(
      _readNode(data.conditionalExpression_condition),
      _Tokens.QUESTION,
      _readNode(data.conditionalExpression_thenExpression),
      _Tokens.COLON,
      _readNode(data.conditionalExpression_elseExpression),
    )..staticType = _readType(data.expression_type);
  }

  Configuration _read_configuration(LinkedNode data) {
    return astFactory.configuration(
      _Tokens.IF,
      _Tokens.OPEN_PAREN,
      _readNode(data.configuration_name),
      AstBinaryFlags.hasEqual(data.flags) ? _Tokens.EQ : null,
      _readNode(data.configuration_value),
      _Tokens.CLOSE_PAREN,
      _readNode(data.configuration_uri),
    );
  }

  ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
    var name = _readNode(data.constructorDeclaration_name);
    var node = astFactory.constructorDeclaration(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
      AstBinaryFlags.isFactory(data.flags) ? _Tokens.FACTORY : null,
      _readNode(data.constructorDeclaration_returnType),
      name != null
          ? Token(TokenType.PERIOD, data.constructorDeclaration_periodOffset)
          : null,
      name,
      _readNodeLazy(data.constructorDeclaration_parameters),
      _Tokens.choose(
        AstBinaryFlags.hasSeparatorColon(data.flags),
        _Tokens.COLON,
        AstBinaryFlags.hasSeparatorEquals(data.flags),
        _Tokens.EQ,
      ),
      _readNodeListLazy(data.constructorDeclaration_initializers),
      _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
      _readNodeLazy(data.constructorDeclaration_body),
    );
    LazyConstructorDeclaration.setData(node, data);
    return node;
  }

  ConstructorFieldInitializer _read_constructorFieldInitializer(
      LinkedNode data) {
    var hasThis = AstBinaryFlags.hasThis(data.flags);
    return astFactory.constructorFieldInitializer(
      hasThis ? _Tokens.THIS : null,
      hasThis ? _Tokens.PERIOD : null,
      _readNode(data.constructorFieldInitializer_fieldName),
      _Tokens.EQ,
      _readNode(data.constructorFieldInitializer_expression),
    );
  }

  ConstructorName _read_constructorName(LinkedNode data) {
    return astFactory.constructorName(
      _readNode(data.constructorName_type),
      data.constructorName_name != null ? _Tokens.PERIOD : null,
      _readNode(data.constructorName_name),
    )..staticElement = _elementOfComponents(
        data.constructorName_element,
        data.constructorName_elementType,
      );
  }

  ContinueStatement _read_continueStatement(LinkedNode data) {
    return astFactory.continueStatement(
      _Tokens.CONTINUE,
      _readNode(data.continueStatement_label),
      _Tokens.SEMICOLON,
    );
  }

  DeclaredIdentifier _read_declaredIdentifier(LinkedNode data) {
    return astFactory.declaredIdentifier(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _Tokens.choose(
        AstBinaryFlags.isConst(data.flags),
        _Tokens.CONST,
        AstBinaryFlags.isFinal(data.flags),
        _Tokens.FINAL,
        AstBinaryFlags.isVar(data.flags),
        _Tokens.VAR,
      ),
      _readNode(data.declaredIdentifier_type),
      _readNode(data.declaredIdentifier_identifier),
    );
  }

  DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
    var node = astFactory.defaultFormalParameter(
      _readNode(data.defaultFormalParameter_parameter),
      _toParameterKind(data.defaultFormalParameter_kind),
      data.defaultFormalParameter_defaultValue != null ? _Tokens.COLON : null,
      _readNodeLazy(data.defaultFormalParameter_defaultValue),
    );
    LazyFormalParameter.setData(node, data);
    return node;
  }

  DoStatement _read_doStatement(LinkedNode data) {
    return astFactory.doStatement(
      _Tokens.DO,
      _readNode(data.doStatement_body),
      _Tokens.WHILE,
      _Tokens.OPEN_PAREN,
      _readNode(data.doStatement_condition),
      _Tokens.CLOSE_PAREN,
      _Tokens.SEMICOLON,
    );
  }

  DottedName _read_dottedName(LinkedNode data) {
    return astFactory.dottedName(
      _readNodeList(data.dottedName_components),
    );
  }

  DoubleLiteral _read_doubleLiteral(LinkedNode data) {
    return AstTestFactory.doubleLiteral(data.doubleLiteral_value)
      ..staticType = _doubleType;
  }

  EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
    return astFactory.emptyFunctionBody(
      _Tokens.SEMICOLON,
    );
  }

  EmptyStatement _read_emptyStatement(LinkedNode data) {
    return astFactory.emptyStatement(
      _Tokens.SEMICOLON,
    );
  }

  EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
    var node = astFactory.enumConstantDeclaration(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      _readNode(data.enumConstantDeclaration_name),
    );
    LazyEnumConstantDeclaration.setData(node, data);
    return node;
  }

  EnumDeclaration _read_enumDeclaration(LinkedNode data) {
    var node = astFactory.enumDeclaration(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      _Tokens.ENUM,
      _readNode(data.namedCompilationUnitMember_name),
      _Tokens.OPEN_CURLY_BRACKET,
      _readNodeListLazy(data.enumDeclaration_constants),
      _Tokens.CLOSE_CURLY_BRACKET,
    );
    LazyEnumDeclaration.setData(node, data);
    return node;
  }

  ExportDirective _read_exportDirective(LinkedNode data) {
    timerAstBinaryReaderDirective.start();
    _isReadingDirective = true;
    try {
      var node = astFactory.exportDirective(
        _readNode(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.EXPORT,
        _readNode(data.uriBasedDirective_uri),
        _readNodeList(data.namespaceDirective_configurations),
        _readNodeList(data.namespaceDirective_combinators),
        _Tokens.SEMICOLON,
      );
      LazyDirective.setData(node, data);
      return node;
    } finally {
      _isReadingDirective = false;
      timerAstBinaryReaderDirective.stop();
    }
  }

  ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
    timerAstBinaryReaderFunctionBody.start();
    try {
      return astFactory.expressionFunctionBody(
        _Tokens.choose(
          AstBinaryFlags.isAsync(data.flags),
          _Tokens.ASYNC,
          AstBinaryFlags.isSync(data.flags),
          _Tokens.SYNC,
        ),
        _Tokens.ARROW,
        _readNode(data.expressionFunctionBody_expression),
        _Tokens.SEMICOLON,
      );
    } finally {
      timerAstBinaryReaderFunctionBody.stop();
    }
  }

  ExpressionStatement _read_expressionStatement(LinkedNode data) {
    return astFactory.expressionStatement(
      _readNode(data.expressionStatement_expression),
      _Tokens.SEMICOLON,
    );
  }

  ExtendsClause _read_extendsClause(LinkedNode data) {
    return astFactory.extendsClause(
      _Tokens.EXTENDS,
      _readNode(data.extendsClause_superclass),
    );
  }

  FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
    var node = astFactory.fieldDeclaration2(
      comment: _readNodeLazy(data.annotatedNode_comment),
      covariantKeyword:
          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
      fieldList: _readNode(data.fieldDeclaration_fields),
      metadata: _readNodeListLazy(data.annotatedNode_metadata),
      semicolon: _Tokens.SEMICOLON,
      staticKeyword:
          AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
    );
    LazyFieldDeclaration.setData(node, data);
    return node;
  }

  FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
    var node = astFactory.fieldFormalParameter2(
      identifier: _readNode(data.normalFormalParameter_identifier),
      period: _Tokens.PERIOD,
      thisKeyword: _Tokens.THIS,
      covariantKeyword:
          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
      typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
      keyword: _Tokens.choose(
        AstBinaryFlags.isConst(data.flags),
        _Tokens.CONST,
        AstBinaryFlags.isFinal(data.flags),
        _Tokens.FINAL,
        AstBinaryFlags.isVar(data.flags),
        _Tokens.VAR,
      ),
      metadata: _readNodeList(data.normalFormalParameter_metadata),
      comment: _readNode(data.normalFormalParameter_comment),
      type: _readNode(data.fieldFormalParameter_type),
      parameters: _readNode(data.fieldFormalParameter_formalParameters),
      requiredKeyword:
          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
    );
    LazyFormalParameter.setData(node, data);
    return node;
  }

  ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
      LinkedNode data) {
    return astFactory.forEachPartsWithDeclaration(
      inKeyword: _Tokens.IN,
      iterable: _readNode(data.forEachParts_iterable),
      loopVariable: _readNode(data.forEachPartsWithDeclaration_loopVariable),
    );
  }

  ForEachPartsWithIdentifier _read_forEachPartsWithIdentifier(LinkedNode data) {
    return astFactory.forEachPartsWithIdentifier(
      inKeyword: _Tokens.IN,
      iterable: _readNode(data.forEachParts_iterable),
      identifier: _readNode(data.forEachPartsWithIdentifier_identifier),
    );
  }

  ForElement _read_forElement(LinkedNode data) {
    return astFactory.forElement(
      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
      body: _readNode(data.forElement_body),
      forKeyword: _Tokens.FOR,
      forLoopParts: _readNode(data.forMixin_forLoopParts),
      leftParenthesis: _Tokens.OPEN_PAREN,
      rightParenthesis: _Tokens.CLOSE_PAREN,
    );
  }

  FormalParameterList _read_formalParameterList(LinkedNode data) {
    return astFactory.formalParameterList(
      _Tokens.OPEN_PAREN,
      _readNodeList(data.formalParameterList_parameters),
      _Tokens.choose(
        AstBinaryFlags.isDelimiterCurly(data.flags),
        _Tokens.OPEN_CURLY_BRACKET,
        AstBinaryFlags.isDelimiterSquare(data.flags),
        _Tokens.OPEN_SQUARE_BRACKET,
      ),
      _Tokens.choose(
        AstBinaryFlags.isDelimiterCurly(data.flags),
        _Tokens.CLOSE_CURLY_BRACKET,
        AstBinaryFlags.isDelimiterSquare(data.flags),
        _Tokens.CLOSE_SQUARE_BRACKET,
      ),
      _Tokens.CLOSE_PAREN,
    );
  }

  ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
    return astFactory.forPartsWithDeclarations(
      condition: _readNode(data.forParts_condition),
      leftSeparator: _Tokens.SEMICOLON,
      rightSeparator: _Tokens.SEMICOLON,
      updaters: _readNodeList(data.forParts_updaters),
      variables: _readNode(data.forPartsWithDeclarations_variables),
    );
  }

  ForPartsWithExpression _read_forPartsWithExpression(LinkedNode data) {
    return astFactory.forPartsWithExpression(
      condition: _readNode(data.forParts_condition),
      initialization: _readNode(data.forPartsWithExpression_initialization),
      leftSeparator: _Tokens.SEMICOLON,
      rightSeparator: _Tokens.SEMICOLON,
      updaters: _readNodeList(data.forParts_updaters),
    );
  }

  ForStatement _read_forStatement(LinkedNode data) {
    return astFactory.forStatement(
      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
      forKeyword: _Tokens.FOR,
      leftParenthesis: _Tokens.OPEN_PAREN,
      forLoopParts: _readNode(data.forMixin_forLoopParts),
      rightParenthesis: _Tokens.CLOSE_PAREN,
      body: _readNode(data.forStatement_body),
    );
  }

  FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
    timerAstBinaryReaderFunctionDeclaration.start();
    try {
      var node = astFactory.functionDeclaration(
        _readNodeLazy(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
        _readNodeLazy(data.functionDeclaration_returnType),
        _Tokens.choose(
          AstBinaryFlags.isGet(data.flags),
          _Tokens.GET,
          AstBinaryFlags.isSet(data.flags),
          _Tokens.SET,
        ),
        _readNode(data.namedCompilationUnitMember_name),
        _readNodeLazy(data.functionDeclaration_functionExpression),
      );
      LazyFunctionDeclaration.setData(node, data);
      return node;
    } finally {
      timerAstBinaryReaderFunctionDeclaration.stop();
    }
  }

  FunctionDeclarationStatement _read_functionDeclarationStatement(
      LinkedNode data) {
    return astFactory.functionDeclarationStatement(
      _readNode(data.functionDeclarationStatement_functionDeclaration),
    );
  }

  FunctionExpression _read_functionExpression(LinkedNode data) {
    var node = astFactory.functionExpression(
      _readNode(data.functionExpression_typeParameters),
      _readNodeLazy(data.functionExpression_formalParameters),
      _readNodeLazy(data.functionExpression_body),
    );
    LazyFunctionExpression.setData(node, data);
    return node;
  }

  FunctionExpressionInvocation _read_functionExpressionInvocation(
      LinkedNode data) {
    return astFactory.functionExpressionInvocation(
      _readNode(data.functionExpressionInvocation_function),
      _readNode(data.invocationExpression_typeArguments),
      _readNode(data.invocationExpression_arguments),
    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
  }

  FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) {
    var node = astFactory.functionTypeAlias(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      _Tokens.TYPEDEF,
      _readNodeLazy(data.functionTypeAlias_returnType),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.functionTypeAlias_typeParameters),
      _readNodeLazy(data.functionTypeAlias_formalParameters),
      _Tokens.SEMICOLON,
    );
    LazyFunctionTypeAlias.setData(node, data);
    LazyFunctionTypeAlias.setHasSelfReference(
      node,
      data.typeAlias_hasSelfReference,
    );
    return node;
  }

  FunctionTypedFormalParameter _read_functionTypedFormalParameter(
      LinkedNode data) {
    var node = astFactory.functionTypedFormalParameter2(
      comment: _readNodeLazy(data.normalFormalParameter_comment),
      covariantKeyword:
          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
      identifier: _readNode(data.normalFormalParameter_identifier),
      metadata: _readNodeListLazy(data.normalFormalParameter_metadata),
      parameters: _readNodeLazy(
        data.functionTypedFormalParameter_formalParameters,
      ),
      requiredKeyword:
          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
      returnType: _readNodeLazy(data.functionTypedFormalParameter_returnType),
      typeParameters: _readNode(
        data.functionTypedFormalParameter_typeParameters,
      ),
    );
    LazyFormalParameter.setData(node, data);
    return node;
  }

  GenericFunctionType _read_genericFunctionType(LinkedNode data) {
    var id = data.genericFunctionType_id;
    return _unitContext.getGenericFunctionType(id);
  }

  GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
    var node = astFactory.genericTypeAlias(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      _Tokens.TYPEDEF,
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.genericTypeAlias_typeParameters),
      _Tokens.EQ,
      _readNodeLazy(data.genericTypeAlias_functionType),
      _Tokens.SEMICOLON,
    );
    LazyGenericTypeAlias.setData(node, data);
    LazyGenericTypeAlias.setHasSelfReference(
      node,
      data.typeAlias_hasSelfReference,
    );
    return node;
  }

  HideCombinator _read_hideCombinator(LinkedNode data) {
    return astFactory.hideCombinator(
      _Tokens.HIDE,
      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
    );
  }

  IfElement _read_ifElement(LinkedNode data) {
    var elseElement = _readNode(data.ifElement_elseElement);
    return astFactory.ifElement(
      condition: _readNode(data.ifMixin_condition),
      elseElement: elseElement,
      elseKeyword: elseElement != null ? _Tokens.ELSE : null,
      ifKeyword: _Tokens.IF,
      leftParenthesis: _Tokens.OPEN_PAREN,
      rightParenthesis: _Tokens.CLOSE_PAREN,
      thenElement: _readNode(data.ifElement_thenElement),
    );
  }

  IfStatement _read_ifStatement(LinkedNode data) {
    var elseStatement = _readNode(data.ifStatement_elseStatement);
    return astFactory.ifStatement(
      _Tokens.IF,
      _Tokens.OPEN_PAREN,
      _readNode(data.ifMixin_condition),
      _Tokens.CLOSE_PAREN,
      _readNode(data.ifStatement_thenStatement),
      elseStatement != null ? _Tokens.ELSE : null,
      elseStatement,
    );
  }

  ImplementsClause _read_implementsClause(LinkedNode data) {
    return astFactory.implementsClause(
      _Tokens.IMPLEMENTS,
      _readNodeList(data.implementsClause_interfaces),
    );
  }

  ImportDirective _read_importDirective(LinkedNode data) {
    timerAstBinaryReaderDirective.start();
    _isReadingDirective = true;
    try {
      SimpleIdentifier prefix;
      if (data.importDirective_prefix.isNotEmpty) {
        prefix = astFactory.simpleIdentifier(
          TokenFactory.tokenFromString(data.importDirective_prefix)
            ..offset = data.importDirective_prefixOffset,
        );
      }

      var node = astFactory.importDirective(
        _readNode(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.IMPORT,
        _readNode(data.uriBasedDirective_uri),
        _readNodeList(data.namespaceDirective_configurations),
        AstBinaryFlags.isDeferred(data.flags) ? _Tokens.DEFERRED : null,
        _Tokens.AS,
        prefix,
        _readNodeList(data.namespaceDirective_combinators),
        _Tokens.SEMICOLON,
      );
      LazyDirective.setData(node, data);
      return node;
    } finally {
      _isReadingDirective = false;
      timerAstBinaryReaderDirective.stop();
    }
  }

  IndexExpression _read_indexExpression(LinkedNode data) {
    return astFactory.indexExpressionForTarget(
      _readNode(data.indexExpression_target),
      _Tokens.OPEN_SQUARE_BRACKET,
      _readNode(data.indexExpression_index),
      _Tokens.CLOSE_SQUARE_BRACKET,
    )
      ..period =
          AstBinaryFlags.hasPeriod(data.flags) ? _Tokens.PERIOD_PERIOD : null
      ..staticElement = _elementOfComponents(
        data.indexExpression_element,
        data.indexExpression_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
    var node = astFactory.instanceCreationExpression(
      _Tokens.choose(
        AstBinaryFlags.isConst(data.flags),
        _Tokens.CONST,
        AstBinaryFlags.isNew(data.flags),
        _Tokens.NEW,
      ),
      _readNode(data.instanceCreationExpression_constructorName),
      astFactory.argumentList(
        _Tokens.OPEN_PAREN,
        _readNodeList(
          data.instanceCreationExpression_arguments,
        ),
        _Tokens.CLOSE_PAREN,
      ),
      typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
    );
    node.staticElement = node.constructorName.staticElement;
    node.staticType = _readType(data.expression_type);
    return node;
  }

  IntegerLiteral _read_integerLiteral(LinkedNode data) {
    return AstTestFactory.integer(data.integerLiteral_value)
      ..staticType = _intType;
  }

  InterpolationExpression _read_interpolationExpression(LinkedNode data) {
    var isIdentifier =
        AstBinaryFlags.isStringInterpolationIdentifier(data.flags);
    return astFactory.interpolationExpression(
      isIdentifier
          ? _Tokens.OPEN_CURLY_BRACKET
          : _Tokens.STRING_INTERPOLATION_EXPRESSION,
      _readNode(data.interpolationExpression_expression),
      isIdentifier ? null : _Tokens.CLOSE_CURLY_BRACKET,
    );
  }

  InterpolationString _read_interpolationString(LinkedNode data) {
    return astFactory.interpolationString(
      TokenFactory.tokenFromString(data.interpolationString_value),
      data.interpolationString_value,
    );
  }

  IsExpression _read_isExpression(LinkedNode data) {
    return astFactory.isExpression(
      _readNode(data.isExpression_expression),
      _Tokens.IS,
      AstBinaryFlags.hasNot(data.flags) ? _Tokens.BANG : null,
      _readNode(data.isExpression_type),
    )..staticType = _boolType;
  }

  Label _read_label(LinkedNode data) {
    return astFactory.label(
      _readNode(data.label_label),
      _Tokens.COLON,
    );
  }

  LabeledStatement _read_labeledStatement(LinkedNode data) {
    return astFactory.labeledStatement(
      _readNodeList(data.labeledStatement_labels),
      _readNode(data.labeledStatement_statement),
    );
  }

  LibraryDirective _read_libraryDirective(LinkedNode data) {
    timerAstBinaryReaderDirective.start();
    _isReadingDirective = true;
    try {
      var node = astFactory.libraryDirective(
        _readNode(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.LIBRARY,
        _readNode(data.libraryDirective_name),
        _Tokens.SEMICOLON,
      );
      LazyDirective.setData(node, data);
      return node;
    } finally {
      _isReadingDirective = false;
      timerAstBinaryReaderDirective.stop();
    }
  }

  LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
    return astFactory.libraryIdentifier(
      _readNodeList(data.libraryIdentifier_components),
    );
  }

  ListLiteral _read_listLiteral(LinkedNode data) {
    return astFactory.listLiteral(
      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
      AstBinaryFlags.hasTypeArguments(data.flags)
          ? astFactory.typeArgumentList(
              _Tokens.LT,
              _readNodeList(data.typedLiteral_typeArguments),
              _Tokens.GT,
            )
          : null,
      _Tokens.OPEN_SQUARE_BRACKET,
      _readNodeList(data.listLiteral_elements),
      _Tokens.CLOSE_SQUARE_BRACKET,
    )..staticType = _readType(data.expression_type);
  }

  MapLiteralEntry _read_mapLiteralEntry(LinkedNode data) {
    return astFactory.mapLiteralEntry(
      _readNode(data.mapLiteralEntry_key),
      _Tokens.COLON,
      _readNode(data.mapLiteralEntry_value),
    );
  }

  MethodDeclaration _read_methodDeclaration(LinkedNode data) {
    var node = astFactory.methodDeclaration(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
      AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
      _readNodeLazy(data.methodDeclaration_returnType),
      _Tokens.choose(
        AstBinaryFlags.isGet(data.flags),
        _Tokens.GET,
        AstBinaryFlags.isSet(data.flags),
        _Tokens.SET,
      ),
      AstBinaryFlags.isOperator(data.flags) ? _Tokens.OPERATOR : null,
      _readNode(data.methodDeclaration_name),
      _readNode(data.methodDeclaration_typeParameters),
      _readNodeLazy(data.methodDeclaration_formalParameters),
      AstBinaryFlags.isAbstract(data.flags)
          ? AstTestFactory.emptyFunctionBody()
          : AstTestFactory.blockFunctionBody(AstTestFactory.block()),
    );
    LazyMethodDeclaration.setData(node, data);
    return node;
  }

  MethodInvocation _read_methodInvocation(LinkedNode data) {
    return astFactory.methodInvocation(
      _readNode(data.methodInvocation_target),
      _Tokens.choose(
        AstBinaryFlags.hasPeriod(data.flags),
        _Tokens.PERIOD,
        AstBinaryFlags.hasPeriod2(data.flags),
        _Tokens.PERIOD_PERIOD,
      ),
      _readNode(data.methodInvocation_methodName),
      _readNode(data.invocationExpression_typeArguments),
      _readNode(data.invocationExpression_arguments),
    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
  }

  MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
    timerAstBinaryReaderMixin.start();
    try {
      var node = astFactory.mixinDeclaration(
        _readNodeLazy(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.MIXIN,
        _readNode(data.namedCompilationUnitMember_name),
        _readNode(data.classOrMixinDeclaration_typeParameters),
        _readNodeLazy(data.mixinDeclaration_onClause),
        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
        _Tokens.OPEN_CURLY_BRACKET,
        _readNodeListLazy(data.classOrMixinDeclaration_members),
        _Tokens.CLOSE_CURLY_BRACKET,
      );
      LazyMixinDeclaration(node, data);
      return node;
    } finally {
      timerAstBinaryReaderMixin.stop();
    }
  }

  NamedExpression _read_namedExpression(LinkedNode data) {
    Expression expression = _readNode(data.namedExpression_expression);
    return astFactory.namedExpression(
      _readNode(data.namedExpression_name),
      expression,
    )..staticType = expression.staticType;
  }

  NativeClause _read_nativeClause(LinkedNode data) {
    return astFactory.nativeClause(
      _Tokens.NATIVE,
      _readNode(data.nativeClause_name),
    );
  }

  NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
    return astFactory.nativeFunctionBody(
      _Tokens.NATIVE,
      _readNode(data.nativeFunctionBody_stringLiteral),
      _Tokens.SEMICOLON,
    );
  }

  NullLiteral _read_nullLiteral(LinkedNode data) {
    return astFactory.nullLiteral(
      _Tokens.NULL,
    )..staticType = _nullType;
  }

  OnClause _read_onClause(LinkedNode data) {
    return astFactory.onClause(
      _Tokens.ON,
      _readNodeList(data.onClause_superclassConstraints),
    );
  }

  ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
    return astFactory.parenthesizedExpression(
      _Tokens.OPEN_PAREN,
      _readNode(data.parenthesizedExpression_expression),
      _Tokens.CLOSE_PAREN,
    )..staticType = _readType(data.expression_type);
  }

  PartDirective _read_partDirective(LinkedNode data) {
    timerAstBinaryReaderDirective.start();
    _isReadingDirective = true;
    try {
      var node = astFactory.partDirective(
        _readNode(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.PART,
        _readNode(data.uriBasedDirective_uri),
        _Tokens.SEMICOLON,
      );
      LazyDirective.setData(node, data);
      return node;
    } finally {
      _isReadingDirective = false;
      timerAstBinaryReaderDirective.stop();
    }
  }

  PartOfDirective _read_partOfDirective(LinkedNode data) {
    timerAstBinaryReaderDirective.start();
    _isReadingDirective = true;
    try {
      var node = astFactory.partOfDirective(
        _readNode(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _Tokens.PART,
        _Tokens.OF,
        _readNode(data.partOfDirective_uri),
        _readNode(data.partOfDirective_libraryName),
        _Tokens.SEMICOLON,
      );
      LazyDirective.setData(node, data);
      return node;
    } finally {
      _isReadingDirective = false;
      timerAstBinaryReaderDirective.stop();
    }
  }

  PostfixExpression _read_postfixExpression(LinkedNode data) {
    return astFactory.postfixExpression(
      _readNode(data.postfixExpression_operand),
      _Tokens.fromType(data.postfixExpression_operator),
    )
      ..staticElement = _elementOfComponents(
        data.postfixExpression_element,
        data.postfixExpression_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  PrefixedIdentifier _read_prefixedIdentifier(LinkedNode data) {
    return astFactory.prefixedIdentifier(
      _readNode(data.prefixedIdentifier_prefix),
      _Tokens.PERIOD,
      _readNode(data.prefixedIdentifier_identifier),
    )..staticType = _readType(data.expression_type);
  }

  PrefixExpression _read_prefixExpression(LinkedNode data) {
    return astFactory.prefixExpression(
      _Tokens.fromType(data.prefixExpression_operator),
      _readNode(data.prefixExpression_operand),
    )
      ..staticElement = _elementOfComponents(
        data.prefixExpression_element,
        data.prefixExpression_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  PropertyAccess _read_propertyAccess(LinkedNode data) {
    return astFactory.propertyAccess(
      _readNode(data.propertyAccess_target),
      _Tokens.fromType(data.propertyAccess_operator),
      _readNode(data.propertyAccess_propertyName),
    )..staticType = _readType(data.expression_type);
  }

  RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
      LinkedNode data) {
    var hasThis = AstBinaryFlags.hasThis(data.flags);
    return astFactory.redirectingConstructorInvocation(
      hasThis ? _Tokens.THIS : null,
      hasThis ? _Tokens.PERIOD : null,
      _readNode(data.redirectingConstructorInvocation_constructorName),
      _readNode(data.redirectingConstructorInvocation_arguments),
    )..staticElement = _elementOfComponents(
        data.redirectingConstructorInvocation_element,
        data.redirectingConstructorInvocation_elementType,
      );
  }

  RethrowExpression _read_rethrowExpression(LinkedNode data) {
    return astFactory.rethrowExpression(
      _Tokens.RETHROW,
    )..staticType = _readType(data.expression_type);
  }

  ReturnStatement _read_returnStatement(LinkedNode data) {
    return astFactory.returnStatement(
      _Tokens.RETURN,
      _readNode(data.returnStatement_expression),
      _Tokens.SEMICOLON,
    );
  }

  SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
    SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
      constKeyword: AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
      elements: _readNodeList(data.setOrMapLiteral_elements),
      leftBracket: _Tokens.OPEN_CURLY_BRACKET,
      typeArguments: AstBinaryFlags.hasTypeArguments(data.flags)
          ? astFactory.typeArgumentList(
              _Tokens.LT,
              _readNodeList(data.typedLiteral_typeArguments),
              _Tokens.GT,
            )
          : null,
      rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
    )..staticType = _readType(data.expression_type);
    if (AstBinaryFlags.isMap(data.flags)) {
      node.becomeMap();
    } else if (AstBinaryFlags.isSet(data.flags)) {
      node.becomeSet();
    }
    return node;
  }

  ShowCombinator _read_showCombinator(LinkedNode data) {
    return astFactory.showCombinator(
      _Tokens.SHOW,
      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
    );
  }

  SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
    SimpleFormalParameterImpl node = astFactory.simpleFormalParameter2(
      identifier: _readNode(data.normalFormalParameter_identifier),
      type: _readNode(data.simpleFormalParameter_type),
      covariantKeyword:
          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
      comment: _readNode(data.normalFormalParameter_comment),
      metadata: _readNodeList(data.normalFormalParameter_metadata),
      keyword: _Tokens.choose(
        AstBinaryFlags.isConst(data.flags),
        _Tokens.CONST,
        AstBinaryFlags.isFinal(data.flags),
        _Tokens.FINAL,
        AstBinaryFlags.isVar(data.flags),
        _Tokens.VAR,
      ),
      requiredKeyword:
          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
    );
    LazyFormalParameter.setData(node, data);
    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
    return node;
  }

  SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
    return astFactory.simpleIdentifier(
      TokenFactory.tokenFromString(data.simpleIdentifier_name)
        ..offset = data.simpleIdentifier_offset,
      isDeclaration: AstBinaryFlags.isDeclaration(data.flags),
    )
      ..staticElement = _elementOfComponents(
        data.simpleIdentifier_element,
        data.simpleIdentifier_elementType,
      )
      ..staticType = _readType(data.expression_type);
  }

  SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
    var node = AstTestFactory.string2(data.simpleStringLiteral_value);
    if (!_isReadingDirective) {
      node.staticType = _stringType;
    }
    return node;
  }

  SpreadElement _read_spreadElement(LinkedNode data) {
    return astFactory.spreadElement(
      spreadOperator: _Tokens.fromType(data.spreadElement_spreadOperator),
      expression: _readNode(data.spreadElement_expression),
    );
  }

  StringInterpolation _read_stringInterpolation(LinkedNode data) {
    return astFactory.stringInterpolation(
      _readNodeList(data.stringInterpolation_elements),
    )..staticType = _stringType;
  }

  SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
    return astFactory.superConstructorInvocation(
      _Tokens.SUPER,
      _Tokens.PERIOD,
      _readNode(data.superConstructorInvocation_constructorName),
      _readNode(data.superConstructorInvocation_arguments),
    )..staticElement = _elementOfComponents(
        data.superConstructorInvocation_element,
        data.superConstructorInvocation_elementType,
      );
  }

  SuperExpression _read_superExpression(LinkedNode data) {
    return astFactory.superExpression(
      _Tokens.SUPER,
    )..staticType = _readType(data.expression_type);
  }

  SwitchCase _read_switchCase(LinkedNode data) {
    return astFactory.switchCase(
      _readNodeList(data.switchMember_labels),
      _Tokens.CASE,
      _readNode(data.switchCase_expression),
      _Tokens.COLON,
      _readNodeList(data.switchMember_statements),
    );
  }

  SwitchDefault _read_switchDefault(LinkedNode data) {
    return astFactory.switchDefault(
      _readNodeList(data.switchMember_labels),
      _Tokens.DEFAULT,
      _Tokens.COLON,
      _readNodeList(data.switchMember_statements),
    );
  }

  SwitchStatement _read_switchStatement(LinkedNode data) {
    return astFactory.switchStatement(
      _Tokens.SWITCH,
      _Tokens.OPEN_PAREN,
      _readNode(data.switchStatement_expression),
      _Tokens.CLOSE_PAREN,
      _Tokens.OPEN_CURLY_BRACKET,
      _readNodeList(data.switchStatement_members),
      _Tokens.CLOSE_CURLY_BRACKET,
    );
  }

  SymbolLiteral _read_symbolLiteral(LinkedNode data) {
    return astFactory.symbolLiteral(
      _Tokens.HASH,
      data.names.map((lexeme) => TokenFactory.tokenFromString(lexeme)).toList(),
    )..staticType = _readType(data.expression_type);
  }

  ThisExpression _read_thisExpression(LinkedNode data) {
    return astFactory.thisExpression(
      _Tokens.THIS,
    )..staticType = _readType(data.expression_type);
  }

  ThrowExpression _read_throwExpression(LinkedNode data) {
    return astFactory.throwExpression(
      _Tokens.THROW,
      _readNode(data.throwExpression_expression),
    )..staticType = _readType(data.expression_type);
  }

  TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
      LinkedNode data) {
    timerAstBinaryReaderTopLevelVar.start();
    try {
      var node = astFactory.topLevelVariableDeclaration(
        _readNodeLazy(data.annotatedNode_comment),
        _readNodeListLazy(data.annotatedNode_metadata),
        _readNode(data.topLevelVariableDeclaration_variableList),
        _Tokens.SEMICOLON,
      );
      LazyTopLevelVariableDeclaration.setData(node, data);
      return node;
    } finally {
      timerAstBinaryReaderTopLevelVar.stop();
    }
  }

  TryStatement _read_tryStatement(LinkedNode data) {
    return astFactory.tryStatement(
      _Tokens.TRY,
      _readNode(data.tryStatement_body),
      _readNodeList(data.tryStatement_catchClauses),
      _Tokens.FINALLY,
      _readNode(data.tryStatement_finallyBlock),
    );
  }

  TypeArgumentList _read_typeArgumentList(LinkedNode data) {
    return astFactory.typeArgumentList(
      _Tokens.LT,
      _readNodeList(data.typeArgumentList_arguments),
      _Tokens.GT,
    );
  }

  TypeName _read_typeName(LinkedNode data) {
    return astFactory.typeName(
      _readNode(data.typeName_name),
      AstBinaryFlags.hasTypeArguments(data.flags)
          ? astFactory.typeArgumentList(
              _Tokens.LT,
              _readNodeList(data.typeName_typeArguments),
              _Tokens.GT,
            )
          : null,
      question:
          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
    )..type = _readType(data.typeName_type);
  }

  TypeParameter _read_typeParameter(LinkedNode data) {
    var node = astFactory.typeParameter(
      _readNodeLazy(data.annotatedNode_comment),
      _readNodeListLazy(data.annotatedNode_metadata),
      _readNode(data.typeParameter_name),
      _Tokens.EXTENDS,
      _readNodeLazy(data.typeParameter_bound),
    );
    LazyTypeParameter.setData(node, data);
    return node;
  }

  TypeParameterList _read_typeParameterList(LinkedNode data) {
    return astFactory.typeParameterList(
      _Tokens.LT,
      _readNodeList(data.typeParameterList_typeParameters),
      _Tokens.GT,
    );
  }

  VariableDeclaration _read_variableDeclaration(LinkedNode data) {
    var node = astFactory.variableDeclaration(
      _readNode(data.variableDeclaration_name),
      _Tokens.EQ,
      _readNodeLazy(data.variableDeclaration_initializer),
    );
    LazyVariableDeclaration.setData(node, data);
    LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
    return node;
  }

  VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
    var node = astFactory.variableDeclarationList2(
      comment: _readNodeLazy(data.annotatedNode_comment),
      keyword: _Tokens.choose(
        AstBinaryFlags.isConst(data.flags),
        _Tokens.CONST,
        AstBinaryFlags.isFinal(data.flags),
        _Tokens.FINAL,
        AstBinaryFlags.isVar(data.flags),
        _Tokens.VAR,
      ),
      lateKeyword: AstBinaryFlags.isLate(data.flags) ? _Tokens.LATE : null,
      metadata: _readNodeListLazy(data.annotatedNode_metadata),
      type: _readNodeLazy(data.variableDeclarationList_type),
      variables: _readNodeList(data.variableDeclarationList_variables),
    );
    LazyVariableDeclarationList.setData(node, data);
    return node;
  }

  VariableDeclarationStatement _read_variableDeclarationStatement(
      LinkedNode data) {
    return astFactory.variableDeclarationStatement(
      _readNode(data.variableDeclarationStatement_variables),
      _Tokens.SEMICOLON,
    );
  }

  WhileStatement _read_whileStatement(LinkedNode data) {
    return astFactory.whileStatement(
      _Tokens.WHILE,
      _Tokens.OPEN_PAREN,
      _readNode(data.whileStatement_condition),
      _Tokens.CLOSE_PAREN,
      _readNode(data.whileStatement_body),
    );
  }

  WithClause _read_withClause(LinkedNode data) {
    return astFactory.withClause(
      _Tokens.WITH,
      _readNodeList(data.withClause_mixinTypes),
    );
  }

  YieldStatement _read_yieldStatement(LinkedNode data) {
    return astFactory.yieldStatement(
      _Tokens.YIELD,
      AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
      _readNode(data.yieldStatement_expression),
      _Tokens.SEMICOLON,
    );
  }

  AstNode _readNode(LinkedNode data) {
    if (data == null) return null;

    switch (data.kind) {
      case LinkedNodeKind.adjacentStrings:
        return _read_adjacentStrings(data);
      case LinkedNodeKind.annotation:
        return _read_annotation(data);
      case LinkedNodeKind.argumentList:
        return _read_argumentList(data);
      case LinkedNodeKind.asExpression:
        return _read_asExpression(data);
      case LinkedNodeKind.assertInitializer:
        return _read_assertInitializer(data);
      case LinkedNodeKind.assertStatement:
        return _read_assertStatement(data);
      case LinkedNodeKind.assignmentExpression:
        return _read_assignmentExpression(data);
      case LinkedNodeKind.awaitExpression:
        return _read_awaitExpression(data);
      case LinkedNodeKind.binaryExpression:
        return _read_binaryExpression(data);
      case LinkedNodeKind.block:
        return _read_block(data);
      case LinkedNodeKind.blockFunctionBody:
        return _read_blockFunctionBody(data);
      case LinkedNodeKind.booleanLiteral:
        return _read_booleanLiteral(data);
      case LinkedNodeKind.breakStatement:
        return _read_breakStatement(data);
      case LinkedNodeKind.cascadeExpression:
        return _read_cascadeExpression(data);
      case LinkedNodeKind.catchClause:
        return _read_catchClause(data);
      case LinkedNodeKind.classDeclaration:
        return _read_classDeclaration(data);
      case LinkedNodeKind.classTypeAlias:
        return _read_classTypeAlias(data);
      case LinkedNodeKind.comment:
        return _read_comment(data);
      case LinkedNodeKind.commentReference:
        return _read_commentReference(data);
      case LinkedNodeKind.compilationUnit:
        return _read_compilationUnit(data);
      case LinkedNodeKind.conditionalExpression:
        return _read_conditionalExpression(data);
      case LinkedNodeKind.configuration:
        return _read_configuration(data);
      case LinkedNodeKind.constructorDeclaration:
        return _read_constructorDeclaration(data);
      case LinkedNodeKind.constructorFieldInitializer:
        return _read_constructorFieldInitializer(data);
      case LinkedNodeKind.constructorName:
        return _read_constructorName(data);
      case LinkedNodeKind.continueStatement:
        return _read_continueStatement(data);
      case LinkedNodeKind.declaredIdentifier:
        return _read_declaredIdentifier(data);
      case LinkedNodeKind.defaultFormalParameter:
        return _read_defaultFormalParameter(data);
      case LinkedNodeKind.doStatement:
        return _read_doStatement(data);
      case LinkedNodeKind.dottedName:
        return _read_dottedName(data);
      case LinkedNodeKind.doubleLiteral:
        return _read_doubleLiteral(data);
      case LinkedNodeKind.emptyFunctionBody:
        return _read_emptyFunctionBody(data);
      case LinkedNodeKind.emptyStatement:
        return _read_emptyStatement(data);
      case LinkedNodeKind.enumConstantDeclaration:
        return _read_enumConstantDeclaration(data);
      case LinkedNodeKind.enumDeclaration:
        return _read_enumDeclaration(data);
      case LinkedNodeKind.exportDirective:
        return _read_exportDirective(data);
      case LinkedNodeKind.expressionFunctionBody:
        return _read_expressionFunctionBody(data);
      case LinkedNodeKind.expressionStatement:
        return _read_expressionStatement(data);
      case LinkedNodeKind.extendsClause:
        return _read_extendsClause(data);
      case LinkedNodeKind.fieldDeclaration:
        return _read_fieldDeclaration(data);
      case LinkedNodeKind.fieldFormalParameter:
        return _read_fieldFormalParameter(data);
      case LinkedNodeKind.forEachPartsWithDeclaration:
        return _read_forEachPartsWithDeclaration(data);
      case LinkedNodeKind.forEachPartsWithIdentifier:
        return _read_forEachPartsWithIdentifier(data);
      case LinkedNodeKind.forElement:
        return _read_forElement(data);
      case LinkedNodeKind.forPartsWithExpression:
        return _read_forPartsWithExpression(data);
      case LinkedNodeKind.forPartsWithDeclarations:
        return _read_forPartsWithDeclarations(data);
      case LinkedNodeKind.forStatement:
        return _read_forStatement(data);
      case LinkedNodeKind.formalParameterList:
        return _read_formalParameterList(data);
      case LinkedNodeKind.functionDeclaration:
        return _read_functionDeclaration(data);
      case LinkedNodeKind.functionDeclarationStatement:
        return _read_functionDeclarationStatement(data);
      case LinkedNodeKind.functionExpression:
        return _read_functionExpression(data);
      case LinkedNodeKind.functionExpressionInvocation:
        return _read_functionExpressionInvocation(data);
      case LinkedNodeKind.functionTypeAlias:
        return _read_functionTypeAlias(data);
      case LinkedNodeKind.functionTypedFormalParameter:
        return _read_functionTypedFormalParameter(data);
      case LinkedNodeKind.genericFunctionType:
        return _read_genericFunctionType(data);
      case LinkedNodeKind.genericTypeAlias:
        return _read_genericTypeAlias(data);
      case LinkedNodeKind.hideCombinator:
        return _read_hideCombinator(data);
      case LinkedNodeKind.ifElement:
        return _read_ifElement(data);
      case LinkedNodeKind.ifStatement:
        return _read_ifStatement(data);
      case LinkedNodeKind.implementsClause:
        return _read_implementsClause(data);
      case LinkedNodeKind.importDirective:
        return _read_importDirective(data);
      case LinkedNodeKind.indexExpression:
        return _read_indexExpression(data);
      case LinkedNodeKind.instanceCreationExpression:
        return _read_instanceCreationExpression(data);
      case LinkedNodeKind.integerLiteral:
        return _read_integerLiteral(data);
      case LinkedNodeKind.interpolationString:
        return _read_interpolationString(data);
      case LinkedNodeKind.interpolationExpression:
        return _read_interpolationExpression(data);
      case LinkedNodeKind.isExpression:
        return _read_isExpression(data);
      case LinkedNodeKind.label:
        return _read_label(data);
      case LinkedNodeKind.labeledStatement:
        return _read_labeledStatement(data);
      case LinkedNodeKind.libraryDirective:
        return _read_libraryDirective(data);
      case LinkedNodeKind.libraryIdentifier:
        return _read_libraryIdentifier(data);
      case LinkedNodeKind.listLiteral:
        return _read_listLiteral(data);
      case LinkedNodeKind.mapLiteralEntry:
        return _read_mapLiteralEntry(data);
      case LinkedNodeKind.methodDeclaration:
        return _read_methodDeclaration(data);
      case LinkedNodeKind.methodInvocation:
        return _read_methodInvocation(data);
      case LinkedNodeKind.mixinDeclaration:
        return _read_mixinDeclaration(data);
      case LinkedNodeKind.namedExpression:
        return _read_namedExpression(data);
      case LinkedNodeKind.nativeClause:
        return _read_nativeClause(data);
      case LinkedNodeKind.nativeFunctionBody:
        return _read_nativeFunctionBody(data);
      case LinkedNodeKind.nullLiteral:
        return _read_nullLiteral(data);
      case LinkedNodeKind.onClause:
        return _read_onClause(data);
      case LinkedNodeKind.parenthesizedExpression:
        return _read_parenthesizedExpression(data);
      case LinkedNodeKind.partDirective:
        return _read_partDirective(data);
      case LinkedNodeKind.partOfDirective:
        return _read_partOfDirective(data);
      case LinkedNodeKind.postfixExpression:
        return _read_postfixExpression(data);
      case LinkedNodeKind.prefixExpression:
        return _read_prefixExpression(data);
      case LinkedNodeKind.propertyAccess:
        return _read_propertyAccess(data);
      case LinkedNodeKind.prefixedIdentifier:
        return _read_prefixedIdentifier(data);
      case LinkedNodeKind.redirectingConstructorInvocation:
        return _read_redirectingConstructorInvocation(data);
      case LinkedNodeKind.rethrowExpression:
        return _read_rethrowExpression(data);
      case LinkedNodeKind.returnStatement:
        return _read_returnStatement(data);
      case LinkedNodeKind.setOrMapLiteral:
        return _read_setOrMapLiteral(data);
      case LinkedNodeKind.showCombinator:
        return _read_showCombinator(data);
      case LinkedNodeKind.simpleFormalParameter:
        return _read_simpleFormalParameter(data);
      case LinkedNodeKind.simpleIdentifier:
        return _read_simpleIdentifier(data);
      case LinkedNodeKind.simpleStringLiteral:
        return _read_simpleStringLiteral(data);
      case LinkedNodeKind.spreadElement:
        return _read_spreadElement(data);
      case LinkedNodeKind.stringInterpolation:
        return _read_stringInterpolation(data);
      case LinkedNodeKind.superConstructorInvocation:
        return _read_superConstructorInvocation(data);
      case LinkedNodeKind.superExpression:
        return _read_superExpression(data);
      case LinkedNodeKind.switchCase:
        return _read_switchCase(data);
      case LinkedNodeKind.switchDefault:
        return _read_switchDefault(data);
      case LinkedNodeKind.switchStatement:
        return _read_switchStatement(data);
      case LinkedNodeKind.symbolLiteral:
        return _read_symbolLiteral(data);
      case LinkedNodeKind.thisExpression:
        return _read_thisExpression(data);
      case LinkedNodeKind.throwExpression:
        return _read_throwExpression(data);
      case LinkedNodeKind.topLevelVariableDeclaration:
        return _read_topLevelVariableDeclaration(data);
      case LinkedNodeKind.tryStatement:
        return _read_tryStatement(data);
      case LinkedNodeKind.typeArgumentList:
        return _read_typeArgumentList(data);
      case LinkedNodeKind.typeName:
        return _read_typeName(data);
      case LinkedNodeKind.typeParameter:
        return _read_typeParameter(data);
      case LinkedNodeKind.typeParameterList:
        return _read_typeParameterList(data);
      case LinkedNodeKind.variableDeclaration:
        return _read_variableDeclaration(data);
      case LinkedNodeKind.variableDeclarationList:
        return _read_variableDeclarationList(data);
      case LinkedNodeKind.variableDeclarationStatement:
        return _read_variableDeclarationStatement(data);
      case LinkedNodeKind.whileStatement:
        return _read_whileStatement(data);
      case LinkedNodeKind.withClause:
        return _read_withClause(data);
      case LinkedNodeKind.yieldStatement:
        return _read_yieldStatement(data);
      default:
        throw UnimplementedError('Expression kind: ${data.kind}');
    }
  }

  AstNode _readNodeLazy(LinkedNode data) {
    if (isLazy) return null;
    return _readNode(data);
  }

  List<T> _readNodeList<T>(List<LinkedNode> nodeList) {
    var result = List<T>.filled(nodeList.length, null);
    for (var i = 0; i < nodeList.length; ++i) {
      var linkedNode = nodeList[i];
      result[i] = _readNode(linkedNode) as T;
    }
    return result;
  }

  List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) {
    if (isLazy) {
      return List<T>.filled(nodeList.length, null);
    }
    return _readNodeList(nodeList);
  }

  DartType _readType(LinkedNodeType data) {
    return _unitContext.readType(data);
  }

  static ParameterKind _toParameterKind(LinkedNodeFormalParameterKind kind) {
    switch (kind) {
      case LinkedNodeFormalParameterKind.requiredPositional:
        return ParameterKind.REQUIRED;
      case LinkedNodeFormalParameterKind.requiredNamed:
        return ParameterKind.NAMED_REQUIRED;
        break;
      case LinkedNodeFormalParameterKind.optionalPositional:
        return ParameterKind.POSITIONAL;
        break;
      case LinkedNodeFormalParameterKind.optionalNamed:
        return ParameterKind.NAMED;
      default:
        throw StateError('Unexpected: $kind');
    }
  }
}

class _Tokens {
  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
  static final AT = TokenFactory.tokenFromType(TokenType.AT);
  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
  static final CLOSE_CURLY_BRACKET =
      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
  static final CLOSE_SQUARE_BRACKET =
      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
  static final GT = TokenFactory.tokenFromType(TokenType.GT);
  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
  static final LT = TokenFactory.tokenFromType(TokenType.LT);
  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
  static final OPEN_CURLY_BRACKET =
      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
  static final OPEN_SQUARE_BRACKET =
      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
  static final PERIOD_PERIOD =
      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
  static final STRING_INTERPOLATION_EXPRESSION =
      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);

  static Token choose(bool if1, Token then1, bool if2, Token then2,
      [bool if3, Token then3]) {
    if (if1) return then1;
    if (if2) return then2;
    if (if2 == true) return then3;
    return null;
  }

  static Token fromType(UnlinkedTokenType type) {
    return TokenFactory.tokenFromType(
      TokensContext.binaryToAstTokenType(type),
    );
  }
}
