// 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/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';

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

  AstBinaryReader(this._unitContext);

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

    _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken);
    return node;
  }

  ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
    if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
      return ParameterKind.NAMED;
    }
    if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
      return ParameterKind.POSITIONAL;
    }
    return ParameterKind.REQUIRED;
  }

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

  List<T> _getElements<T extends Element>(List<int> indexList) {
    var bundleContext = _unitContext.bundleContext;
    return bundleContext.elementsOfIndexes(indexList);
  }

  Token _getToken(int index) {
    return _unitContext.tokensContext.tokenOfIndex(index);
  }

  List<Token> _getTokens(List<int> indexList) {
    var result = List<Token>(indexList.length);
    for (var i = 0; i < indexList.length; ++i) {
      var index = indexList[i];
      result[i] = _getToken(index);
    }
    return result;
  }

  AdjacentStrings _read_adjacentStrings(LinkedNode data) {
    return astFactory.adjacentStrings(
      _readNodeList(data.adjacentStrings_strings),
    )..staticType = _readType(data.expression_type);
  }

  Annotation _read_annotation(LinkedNode data) {
    return astFactory.annotation(
      _getToken(data.annotation_atSign),
      _readNode(data.annotation_name),
      _getToken(data.annotation_period),
      _readNode(data.annotation_constructorName),
      _readNode(data.annotation_arguments),
    );
  }

  ArgumentList _read_argumentList(LinkedNode data) {
    return astFactory.argumentList(
      _getToken(data.argumentList_leftParenthesis),
      _readNodeList(data.argumentList_arguments),
      _getToken(data.argumentList_rightParenthesis),
    );
  }

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

  AssertInitializer _read_assertInitializer(LinkedNode data) {
    return astFactory.assertInitializer(
      _getToken(data.assertInitializer_assertKeyword),
      _getToken(data.assertInitializer_leftParenthesis),
      _readNode(data.assertInitializer_condition),
      _getToken(data.assertInitializer_comma),
      _readNode(data.assertInitializer_message),
      _getToken(data.assertInitializer_rightParenthesis),
    );
  }

  AssertStatement _read_assertStatement(LinkedNode data) {
    return astFactory.assertStatement(
      _getToken(data.assertStatement_assertKeyword),
      _getToken(data.assertStatement_leftParenthesis),
      _readNode(data.assertStatement_condition),
      _getToken(data.assertStatement_comma),
      _readNode(data.assertStatement_message),
      _getToken(data.assertStatement_rightParenthesis),
      _getToken(data.assertStatement_semicolon),
    );
  }

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

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

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

  Block _read_block(LinkedNode data) {
    return astFactory.block(
      _getToken(data.block_leftBracket),
      _readNodeList(data.block_statements),
      _getToken(data.block_rightBracket),
    );
  }

  BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
    return astFactory.blockFunctionBody(
      _getToken(data.blockFunctionBody_keyword),
      _getToken(data.blockFunctionBody_star),
      _readNode(data.blockFunctionBody_block),
    );
  }

  BooleanLiteral _read_booleanLiteral(LinkedNode data) {
    return astFactory.booleanLiteral(
      _getToken(data.booleanLiteral_literal),
      data.booleanLiteral_value,
    )..staticType = _readType(data.expression_type);
  }

  BreakStatement _read_breakStatement(LinkedNode data) {
    return astFactory.breakStatement(
      _getToken(data.breakStatement_breakKeyword),
      _readNode(data.breakStatement_label),
      _getToken(data.breakStatement_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) {
    return astFactory.catchClause(
      _getToken(data.catchClause_onKeyword),
      _readNode(data.catchClause_exceptionType),
      _getToken(data.catchClause_catchKeyword),
      _getToken(data.catchClause_leftParenthesis),
      _readNode(data.catchClause_exceptionParameter),
      _getToken(data.catchClause_comma),
      _readNode(data.catchClause_stackTraceParameter),
      _getToken(data.catchClause_rightParenthesis),
      _readNode(data.catchClause_body),
    );
  }

  ClassDeclaration _read_classDeclaration(LinkedNode data) {
    return astFactory.classDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.classDeclaration_abstractKeyword),
      _getToken(data.classDeclaration_classKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.classOrMixinDeclaration_typeParameters),
      _readNode(data.classDeclaration_extendsClause),
      _readNode(data.classDeclaration_withClause),
      _readNode(data.classOrMixinDeclaration_implementsClause),
      _getToken(data.classOrMixinDeclaration_leftBracket),
      _readNodeList(data.classOrMixinDeclaration_members),
      _getToken(data.classOrMixinDeclaration_rightBracket),
    )..nativeClause = _readNode(data.classDeclaration_nativeClause);
  }

  ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
    return astFactory.classTypeAlias(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.typeAlias_typedefKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.classTypeAlias_typeParameters),
      _getToken(data.classTypeAlias_equals),
      _getToken(data.classTypeAlias_abstractKeyword),
      _readNode(data.classTypeAlias_superclass),
      _readNode(data.classTypeAlias_withClause),
      _readNode(data.classTypeAlias_implementsClause),
      _getToken(data.typeAlias_semicolon),
    );
  }

  Comment _read_comment(LinkedNode data) {
    var tokens = _getTokens(data.comment_tokens);
    switch (data.comment_type) {
      case LinkedNodeCommentType.block:
        return astFactory.endOfLineComment(
          tokens,
        );
      case LinkedNodeCommentType.documentation:
        return astFactory.documentationComment(
          tokens,
          // TODO(scheglov) references
        );
      case LinkedNodeCommentType.endOfLine:
        return astFactory.endOfLineComment(
          tokens,
        );
      default:
        throw StateError('${data.comment_type}');
    }
  }

  CompilationUnit _read_compilationUnit(LinkedNode data) {
    return astFactory.compilationUnit(
      _getToken(data.compilationUnit_beginToken),
      _readNode(data.compilationUnit_scriptTag),
      _readNodeList(data.compilationUnit_directives),
      _readNodeList(data.compilationUnit_declarations),
      _getToken(data.compilationUnit_endToken),
    );
  }

  ConditionalExpression _read_conditionalExpression(LinkedNode data) {
    return astFactory.conditionalExpression(
      _readNode(data.conditionalExpression_condition),
      _getToken(data.conditionalExpression_question),
      _readNode(data.conditionalExpression_thenExpression),
      _getToken(data.conditionalExpression_colon),
      _readNode(data.conditionalExpression_elseExpression),
    )..staticType = _readType(data.expression_type);
  }

  Configuration _read_configuration(LinkedNode data) {
    return astFactory.configuration(
      _getToken(data.configuration_ifKeyword),
      _getToken(data.configuration_leftParenthesis),
      _readNode(data.configuration_name),
      _getToken(data.configuration_equalToken),
      _readNode(data.configuration_value),
      _getToken(data.configuration_rightParenthesis),
      _readNode(data.configuration_uri),
    );
  }

  ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
    return astFactory.constructorDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.constructorDeclaration_externalKeyword),
      _getToken(data.constructorDeclaration_constKeyword),
      _getToken(data.constructorDeclaration_factoryKeyword),
      _readNode(data.constructorDeclaration_returnType),
      _getToken(data.constructorDeclaration_period),
      _readNode(data.constructorDeclaration_name),
      _readNode(data.constructorDeclaration_parameters),
      _getToken(data.constructorDeclaration_separator),
      _readNodeList(data.constructorDeclaration_initializers),
      _readNode(data.constructorDeclaration_redirectedConstructor),
      _readNode(data.constructorDeclaration_body),
    );
  }

  ConstructorFieldInitializer _read_constructorFieldInitializer(
      LinkedNode data) {
    return astFactory.constructorFieldInitializer(
      _getToken(data.constructorFieldInitializer_thisKeyword),
      _getToken(data.constructorFieldInitializer_period),
      _readNode(data.constructorFieldInitializer_fieldName),
      _getToken(data.constructorFieldInitializer_equals),
      _readNode(data.constructorFieldInitializer_expression),
    );
  }

  ConstructorName _read_constructorName(LinkedNode data) {
    return astFactory.constructorName(
      _readNode(data.constructorName_type),
      _getToken(data.constructorName_period),
      _readNode(data.constructorName_name),
    )..staticElement = _getElement(data.constructorName_element);
  }

  ContinueStatement _read_continueStatement(LinkedNode data) {
    return astFactory.continueStatement(
      _getToken(data.continueStatement_continueKeyword),
      _readNode(data.continueStatement_label),
      _getToken(data.continueStatement_semicolon),
    );
  }

  DeclaredIdentifier _read_declaredIdentifier(LinkedNode data) {
    return astFactory.declaredIdentifier(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.declaredIdentifier_keyword),
      _readNode(data.declaredIdentifier_type),
      _readNode(data.declaredIdentifier_identifier),
    );
  }

  DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
    return astFactory.defaultFormalParameter(
      _readNode(data.defaultFormalParameter_parameter),
      data.defaultFormalParameter_isNamed
          ? ParameterKind.NAMED
          : ParameterKind.POSITIONAL,
      _getToken(data.defaultFormalParameter_separator),
      _readNode(data.defaultFormalParameter_defaultValue),
    );
  }

  DoStatement _read_doStatement(LinkedNode data) {
    return astFactory.doStatement(
      _getToken(data.doStatement_doKeyword),
      _readNode(data.doStatement_body),
      _getToken(data.doStatement_whileKeyword),
      _getToken(data.doStatement_leftParenthesis),
      _readNode(data.doStatement_condition),
      _getToken(data.doStatement_rightParenthesis),
      _getToken(data.doStatement_semicolon),
    );
  }

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

  DoubleLiteral _read_doubleLiteral(LinkedNode data) {
    return astFactory.doubleLiteral(
      _getToken(data.doubleLiteral_literal),
      data.doubleLiteral_value,
    )..staticType = _readType(data.expression_type);
  }

  EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
    return astFactory.emptyFunctionBody(
      _getToken(data.emptyFunctionBody_semicolon),
    );
  }

  EmptyStatement _read_emptyStatement(LinkedNode data) {
    return astFactory.emptyStatement(
      _getToken(data.emptyStatement_semicolon),
    );
  }

  EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
    return astFactory.enumConstantDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _readNode(data.enumConstantDeclaration_name),
    );
  }

  EnumDeclaration _read_enumDeclaration(LinkedNode data) {
    return astFactory.enumDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.enumDeclaration_enumKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _getToken(data.enumDeclaration_leftBracket),
      _readNodeList(data.enumDeclaration_constants),
      _getToken(data.enumDeclaration_rightBracket),
    );
  }

  ExportDirective _read_exportDirective(LinkedNode data) {
    return astFactory.exportDirective(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.directive_keyword),
      _readNode(data.uriBasedDirective_uri),
      _readNodeList(data.namespaceDirective_configurations),
      _readNodeList(data.namespaceDirective_combinators),
      _getToken(data.directive_semicolon),
    );
  }

  ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
    return astFactory.expressionFunctionBody(
      _getToken(data.expressionFunctionBody_keyword),
      _getToken(data.expressionFunctionBody_arrow),
      _readNode(data.expressionFunctionBody_expression),
      _getToken(data.expressionFunctionBody_semicolon),
    );
  }

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

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

  FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
    return astFactory.fieldDeclaration2(
      comment: _readNode(data.annotatedNode_comment),
      covariantKeyword: _getToken(data.fieldDeclaration_covariantKeyword),
      fieldList: _readNode(data.fieldDeclaration_fields),
      metadata: _readNodeList(data.annotatedNode_metadata),
      semicolon: _getToken(data.fieldDeclaration_semicolon),
      staticKeyword: _getToken(data.fieldDeclaration_staticKeyword),
    );
  }

  FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
    return astFactory.fieldFormalParameter2(
      identifier: _readNode(data.normalFormalParameter_identifier),
      period: _getToken(data.fieldFormalParameter_period),
      thisKeyword: _getToken(data.fieldFormalParameter_thisKeyword),
      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
      typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
      keyword: _getToken(data.fieldFormalParameter_keyword),
      metadata: _readNodeList(data.normalFormalParameter_metadata),
      comment: _readNode(data.normalFormalParameter_comment),
      type: _readNode(data.fieldFormalParameter_type),
      parameters: _readNode(data.fieldFormalParameter_formalParameters),
    );
  }

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

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

  ForElement _read_forElement(LinkedNode data) {
    return astFactory.forElement(
      awaitKeyword: _getToken(data.forMixin_awaitKeyword),
      body: _readNode(data.forElement_body),
      forKeyword: _getToken(data.forMixin_forKeyword),
      forLoopParts: _readNode(data.forMixin_forLoopParts),
      leftParenthesis: _getToken(data.forMixin_leftParenthesis),
      rightParenthesis: _getToken(data.forMixin_rightParenthesis),
    );
  }

  FormalParameterList _read_formalParameterList(LinkedNode data) {
    return astFactory.formalParameterList(
      _getToken(data.formalParameterList_leftParenthesis),
      _readNodeList(data.formalParameterList_parameters),
      _getToken(data.formalParameterList_leftDelimiter),
      _getToken(data.formalParameterList_rightDelimiter),
      _getToken(data.formalParameterList_rightParenthesis),
    );
  }

  ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
    return astFactory.forPartsWithDeclarations(
      condition: _readNode(data.forParts_condition),
      leftSeparator: _getToken(data.forParts_leftSeparator),
      rightSeparator: _getToken(data.forParts_rightSeparator),
      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: _getToken(data.forParts_leftSeparator),
      rightSeparator: _getToken(data.forParts_rightSeparator),
      updaters: _readNodeList(data.forParts_updaters),
    );
  }

  ForStatement _read_forStatement(LinkedNode data) {
    return astFactory.forStatement(
      awaitKeyword: _getToken(data.forMixin_awaitKeyword),
      forKeyword: _getToken(data.forMixin_forKeyword),
      leftParenthesis: _getToken(data.forMixin_leftParenthesis),
      forLoopParts: _readNode(data.forMixin_forLoopParts),
      rightParenthesis: _getToken(data.forMixin_rightParenthesis),
      body: _readNode(data.forStatement_body),
    );
  }

  FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
    return astFactory.functionDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.functionDeclaration_externalKeyword),
      _readNode(data.functionDeclaration_returnType),
      _getToken(data.functionDeclaration_propertyKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.functionDeclaration_functionExpression),
    );
  }

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

  FunctionExpression _read_functionExpression(LinkedNode data) {
    return astFactory.functionExpression(
      _readNode(data.functionExpression_typeParameters),
      _readNode(data.functionExpression_formalParameters),
      _readNode(data.functionExpression_body),
    );
  }

  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) {
    return astFactory.functionTypeAlias(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.typeAlias_typedefKeyword),
      _readNode(data.functionTypeAlias_returnType),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.functionTypeAlias_typeParameters),
      _readNode(data.functionTypeAlias_formalParameters),
      _getToken(data.typeAlias_semicolon),
    );
  }

  FunctionTypedFormalParameter _read_functionTypedFormalParameter(
      LinkedNode data) {
    return astFactory.functionTypedFormalParameter2(
      identifier: _readNode(data.normalFormalParameter_identifier),
      parameters: _readNode(data.functionTypedFormalParameter_formalParameters),
      returnType: _readNode(data.functionTypedFormalParameter_returnType),
      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
      comment: _readNode(data.normalFormalParameter_comment),
      metadata: _readNodeList(data.normalFormalParameter_metadata),
      typeParameters:
          _readNode(data.functionTypedFormalParameter_typeParameters),
    );
  }

  GenericFunctionType _read_genericFunctionType(LinkedNode data) {
    return astFactory.genericFunctionType(
      _readNode(data.genericFunctionType_returnType),
      _getToken(data.genericFunctionType_functionKeyword),
      _readNode(data.genericFunctionType_typeParameters),
      _readNode(data.genericFunctionType_formalParameters),
      question: _getToken(data.genericFunctionType_question),
    );
  }

  GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
    return astFactory.genericTypeAlias(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.typeAlias_typedefKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.genericTypeAlias_typeParameters),
      _getToken(data.genericTypeAlias_equals),
      _readNode(data.genericTypeAlias_functionType),
      _getToken(data.typeAlias_semicolon),
    );
  }

  HideCombinator _read_hideCombinator(LinkedNode data) {
    return astFactory.hideCombinator(
      _getToken(data.combinator_keyword),
      _readNodeList(data.hideCombinator_hiddenNames),
    );
  }

  IfElement _read_ifElement(LinkedNode data) {
    return astFactory.ifElement(
      condition: _readNode(data.ifMixin_condition),
      elseElement: _readNode(data.ifElement_elseElement),
      elseKeyword: _getToken(data.ifMixin_elseKeyword),
      ifKeyword: _getToken(data.ifMixin_ifKeyword),
      leftParenthesis: _getToken(data.ifMixin_leftParenthesis),
      rightParenthesis: _getToken(data.ifMixin_rightParenthesis),
      thenElement: _readNode(data.ifElement_thenElement),
    );
  }

  IfStatement _read_ifStatement(LinkedNode data) {
    return astFactory.ifStatement(
      _getToken(data.ifMixin_ifKeyword),
      _getToken(data.ifMixin_leftParenthesis),
      _readNode(data.ifMixin_condition),
      _getToken(data.ifMixin_rightParenthesis),
      _readNode(data.ifStatement_thenStatement),
      _getToken(data.ifMixin_elseKeyword),
      _readNode(data.ifStatement_elseStatement),
    );
  }

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

  ImportDirective _read_importDirective(LinkedNode data) {
    return astFactory.importDirective(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.directive_keyword),
      _readNode(data.uriBasedDirective_uri),
      _readNodeList(data.namespaceDirective_configurations),
      _getToken(data.importDirective_deferredKeyword),
      _getToken(data.importDirective_asKeyword),
      _readNode(data.importDirective_prefix),
      _readNodeList(data.namespaceDirective_combinators),
      _getToken(data.directive_semicolon),
    );
  }

  IndexExpression _read_indexExpression(LinkedNode data) {
    return astFactory.indexExpressionForTarget(
      _readNode(data.indexExpression_target),
      _getToken(data.indexExpression_leftBracket),
      _readNode(data.indexExpression_index),
      _getToken(data.indexExpression_rightBracket),
    )
      ..period = _getToken(data.indexExpression_period)
      ..staticElement = _getElement(data.indexExpression_element)
      ..staticType = _readType(data.expression_type);
  }

  InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
    return astFactory.instanceCreationExpression(
      _getToken(data.instanceCreationExpression_keyword),
      _readNode(data.instanceCreationExpression_constructorName),
      _readNode(data.instanceCreationExpression_arguments),
      typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
    )..staticType = _readType(data.expression_type);
  }

  IntegerLiteral _read_integerLiteral(LinkedNode data) {
    return astFactory.integerLiteral(
      _getToken(data.integerLiteral_literal),
      data.integerLiteral_value,
    )..staticType = _readType(data.expression_type);
  }

  InterpolationExpression _read_interpolationExpression(LinkedNode data) {
    return astFactory.interpolationExpression(
      _getToken(data.interpolationExpression_leftBracket),
      _readNode(data.interpolationExpression_expression),
      _getToken(data.interpolationExpression_rightBracket),
    );
  }

  InterpolationString _read_interpolationString(LinkedNode data) {
    return astFactory.interpolationString(
      _getToken(data.interpolationString_token),
      data.interpolationString_value,
    );
  }

  IsExpression _read_isExpression(LinkedNode data) {
    return astFactory.isExpression(
      _readNode(data.isExpression_expression),
      _getToken(data.isExpression_isOperator),
      _getToken(data.isExpression_notOperator),
      _readNode(data.isExpression_type),
    )..staticType = _readType(data.expression_type);
  }

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

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

  LibraryDirective _read_libraryDirective(LinkedNode data) {
    return astFactory.libraryDirective(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.directive_keyword),
      _readNode(data.libraryDirective_name),
      _getToken(data.directive_semicolon),
    );
  }

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

  ListLiteral _read_listLiteral(LinkedNode data) {
    return astFactory.listLiteral(
      _getToken(data.typedLiteral_constKeyword),
      _readNode(data.typedLiteral_typeArguments),
      _getToken(data.listLiteral_leftBracket),
      _readNodeList(data.listLiteral_elements),
      _getToken(data.listLiteral_rightBracket),
    )..staticType = _readType(data.expression_type);
  }

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

  MethodDeclaration _read_methodDeclaration(LinkedNode data) {
    return astFactory.methodDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.methodDeclaration_externalKeyword),
      _getToken(data.methodDeclaration_modifierKeyword),
      _readNode(data.methodDeclaration_returnType),
      _getToken(data.methodDeclaration_propertyKeyword),
      _getToken(data.methodDeclaration_operatorKeyword),
      _readNode(data.methodDeclaration_name),
      _readNode(data.methodDeclaration_typeParameters),
      _readNode(data.methodDeclaration_formalParameters),
      _readNode(data.methodDeclaration_body),
    );
  }

  MethodInvocation _read_methodInvocation(LinkedNode data) {
    return astFactory.methodInvocation(
      _readNode(data.methodInvocation_target),
      _getToken(data.methodInvocation_operator),
      _readNode(data.methodInvocation_methodName),
      _readNode(data.invocationExpression_typeArguments),
      _readNode(data.invocationExpression_arguments),
    )..staticInvokeType = _readType(data.invocationExpression_invokeType);
  }

  MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
    return astFactory.mixinDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.mixinDeclaration_mixinKeyword),
      _readNode(data.namedCompilationUnitMember_name),
      _readNode(data.classOrMixinDeclaration_typeParameters),
      _readNode(data.mixinDeclaration_onClause),
      _readNode(data.classOrMixinDeclaration_implementsClause),
      _getToken(data.classOrMixinDeclaration_leftBracket),
      _readNodeList(data.classOrMixinDeclaration_members),
      _getToken(data.classOrMixinDeclaration_rightBracket),
    );
  }

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

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

  NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
    return astFactory.nativeFunctionBody(
      _getToken(data.nativeFunctionBody_nativeKeyword),
      _readNode(data.nativeFunctionBody_stringLiteral),
      _getToken(data.nativeFunctionBody_semicolon),
    );
  }

  NullLiteral _read_nullLiteral(LinkedNode data) {
    return astFactory.nullLiteral(
      _getToken(data.nullLiteral_literal),
    )..staticType = _readType(data.expression_type);
  }

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

  ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
    return astFactory.parenthesizedExpression(
      _getToken(data.parenthesizedExpression_leftParenthesis),
      _readNode(data.parenthesizedExpression_expression),
      _getToken(data.parenthesizedExpression_rightParenthesis),
    )..staticType = _readType(data.expression_type);
  }

  PartDirective _read_partDirective(LinkedNode data) {
    return astFactory.partDirective(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.directive_keyword),
      _readNode(data.uriBasedDirective_uri),
      _getToken(data.directive_semicolon),
    );
  }

  PartOfDirective _read_partOfDirective(LinkedNode data) {
    return astFactory.partOfDirective(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.directive_keyword),
      _getToken(data.partOfDirective_ofKeyword),
      _readNode(data.partOfDirective_uri),
      _readNode(data.partOfDirective_libraryName),
      _getToken(data.directive_semicolon),
    );
  }

  PostfixExpression _read_postfixExpression(LinkedNode data) {
    return astFactory.postfixExpression(
      _readNode(data.postfixExpression_operand),
      _getToken(data.postfixExpression_operator),
    )
      ..staticElement = _getElement(data.postfixExpression_element)
      ..staticType = _readType(data.expression_type);
  }

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

  PrefixExpression _read_prefixExpression(LinkedNode data) {
    return astFactory.prefixExpression(
      _getToken(data.prefixExpression_operator),
      _readNode(data.prefixExpression_operand),
    )
      ..staticElement = _getElement(data.prefixExpression_element)
      ..staticType = _readType(data.expression_type);
  }

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

  RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
      LinkedNode data) {
    return astFactory.redirectingConstructorInvocation(
      _getToken(data.redirectingConstructorInvocation_thisKeyword),
      _getToken(data.redirectingConstructorInvocation_period),
      _readNode(data.redirectingConstructorInvocation_constructorName),
      _readNode(data.redirectingConstructorInvocation_arguments),
    )..staticElement =
        _getElement(data.redirectingConstructorInvocation_element);
  }

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

  ReturnStatement _read_returnStatement(LinkedNode data) {
    return astFactory.returnStatement(
      _getToken(data.returnStatement_returnKeyword),
      _readNode(data.returnStatement_expression),
      _getToken(data.returnStatement_semicolon),
    );
  }

  ScriptTag _read_scriptTag(LinkedNode data) {
    return astFactory.scriptTag(
      _getToken(data.scriptTag_scriptTag),
    );
  }

  SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
    SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
      constKeyword: _getToken(data.typedLiteral_constKeyword),
      elements: _readNodeList(data.setOrMapLiteral_elements),
      leftBracket: _getToken(data.setOrMapLiteral_leftBracket),
      typeArguments: _readNode(data.typedLiteral_typeArguments),
      rightBracket: _getToken(data.setOrMapLiteral_rightBracket),
    )..staticType = _readType(data.expression_type);
    if (data.setOrMapLiteral_isMap) {
      node.becomeMap();
    } else if (data.setOrMapLiteral_isSet) {
      node.becomeSet();
    }
    return node;
  }

  ShowCombinator _read_showCombinator(LinkedNode data) {
    return astFactory.showCombinator(
      _getToken(data.combinator_keyword),
      _readNodeList(data.showCombinator_shownNames),
    );
  }

  SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
    return astFactory.simpleFormalParameter2(
      identifier: _readNode(data.normalFormalParameter_identifier),
      type: _readNode(data.simpleFormalParameter_type),
      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
      comment: _readNode(data.normalFormalParameter_comment),
      metadata: _readNodeList(data.normalFormalParameter_metadata),
      keyword: _getToken(data.simpleFormalParameter_keyword),
    );
  }

  SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
    return astFactory.simpleIdentifier(
      _getToken(data.simpleIdentifier_token),
    )
      ..staticElement = _getElement(data.simpleIdentifier_element)
      ..staticType = _readType(data.expression_type);
  }

  SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
    return astFactory.simpleStringLiteral(
      _getToken(data.simpleStringLiteral_token),
      data.simpleStringLiteral_value,
    )..staticType = _readType(data.expression_type);
  }

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

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

  SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
    return astFactory.superConstructorInvocation(
      _getToken(data.superConstructorInvocation_superKeyword),
      _getToken(data.superConstructorInvocation_period),
      _readNode(data.superConstructorInvocation_constructorName),
      _readNode(data.superConstructorInvocation_arguments),
    )..staticElement = _getElement(data.superConstructorInvocation_element);
  }

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

  SwitchCase _read_switchCase(LinkedNode data) {
    return astFactory.switchCase(
      _readNodeList(data.switchMember_labels),
      _getToken(data.switchMember_keyword),
      _readNode(data.switchCase_expression),
      _getToken(data.switchMember_colon),
      _readNodeList(data.switchMember_statements),
    );
  }

  SwitchDefault _read_switchDefault(LinkedNode data) {
    return astFactory.switchDefault(
      _readNodeList(data.switchMember_labels),
      _getToken(data.switchMember_keyword),
      _getToken(data.switchMember_colon),
      _readNodeList(data.switchMember_statements),
    );
  }

  SwitchStatement _read_switchStatement(LinkedNode data) {
    return astFactory.switchStatement(
      _getToken(data.switchStatement_switchKeyword),
      _getToken(data.switchStatement_leftParenthesis),
      _readNode(data.switchStatement_expression),
      _getToken(data.switchStatement_rightParenthesis),
      _getToken(data.switchStatement_leftBracket),
      _readNodeList(data.switchStatement_members),
      _getToken(data.switchStatement_rightBracket),
    );
  }

  SymbolLiteral _read_symbolLiteral(LinkedNode data) {
    return astFactory.symbolLiteral(
      _getToken(data.symbolLiteral_poundSign),
      _getTokens(data.symbolLiteral_components),
    )..staticType = _readType(data.expression_type);
  }

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

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

  TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
      LinkedNode data) {
    return astFactory.topLevelVariableDeclaration(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _readNode(data.topLevelVariableDeclaration_variableList),
      _getToken(data.topLevelVariableDeclaration_semicolon),
    );
  }

  TryStatement _read_tryStatement(LinkedNode data) {
    return astFactory.tryStatement(
      _getToken(data.tryStatement_tryKeyword),
      _readNode(data.tryStatement_body),
      _readNodeList(data.tryStatement_catchClauses),
      _getToken(data.tryStatement_finallyKeyword),
      _readNode(data.tryStatement_finallyBlock),
    );
  }

  TypeArgumentList _read_typeArgumentList(LinkedNode data) {
    return astFactory.typeArgumentList(
      _getToken(data.typeArgumentList_leftBracket),
      _readNodeList(data.typeArgumentList_arguments),
      _getToken(data.typeArgumentList_rightBracket),
    );
  }

  TypeName _read_typeName(LinkedNode data) {
    return astFactory.typeName(
      _readNode(data.typeName_name),
      _readNode(data.typeName_typeArguments),
      question: _getToken(data.typeName_question),
    )..type = _readType(data.typeName_type);
  }

  TypeParameter _read_typeParameter(LinkedNode data) {
    return astFactory.typeParameter(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _readNode(data.typeParameter_name),
      _getToken(data.typeParameter_extendsKeyword),
      _readNode(data.typeParameter_bound),
    );
  }

  TypeParameterList _read_typeParameterList(LinkedNode data) {
    return astFactory.typeParameterList(
      _getToken(data.typeParameterList_leftBracket),
      _readNodeList(data.typeParameterList_typeParameters),
      _getToken(data.typeParameterList_rightBracket),
    );
  }

  VariableDeclaration _read_variableDeclaration(LinkedNode data) {
    return astFactory.variableDeclaration(
      _readNode(data.variableDeclaration_name),
      _getToken(data.variableDeclaration_equals),
      _readNode(data.variableDeclaration_initializer),
    );
  }

  VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
    return astFactory.variableDeclarationList(
      _readNode(data.annotatedNode_comment),
      _readNodeList(data.annotatedNode_metadata),
      _getToken(data.variableDeclarationList_keyword),
      _readNode(data.variableDeclarationList_type),
      _readNodeList(data.variableDeclarationList_variables),
    );
  }

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

  WhileStatement _read_whileStatement(LinkedNode data) {
    return astFactory.whileStatement(
      _getToken(data.whileStatement_whileKeyword),
      _getToken(data.whileStatement_leftParenthesis),
      _readNode(data.whileStatement_condition),
      _getToken(data.whileStatement_rightParenthesis),
      _readNode(data.whileStatement_body),
    );
  }

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

  YieldStatement _read_yieldStatement(LinkedNode data) {
    return astFactory.yieldStatement(
      _getToken(data.yieldStatement_yieldKeyword),
      _getToken(data.yieldStatement_star),
      _readNode(data.yieldStatement_expression),
      _getToken(data.yieldStatement_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.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.scriptTag:
        return _read_scriptTag(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}');
    }
  }

  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;
  }

  DartType _readType(LinkedNodeType data) {
    if (data == null) return null;

    switch (data.kind) {
      case LinkedNodeTypeKind.bottom:
        return BottomTypeImpl.instance;
      case LinkedNodeTypeKind.dynamic_:
        return DynamicTypeImpl.instance;
      case LinkedNodeTypeKind.function:
        return FunctionTypeImpl.synthetic(
          _readType(data.functionReturnType),
          _getElements(data.functionTypeParameters),
          data.functionFormalParameters
              .map((p) => ParameterElementImpl.synthetic(
                  p.name, _readType(p.type), _formalParameterKind(p.kind)))
              .toList(),
        );
      case LinkedNodeTypeKind.interface:
        var element = _getElement(data.interfaceClass);
        if (element != null) {
          return InterfaceTypeImpl.explicit(
            element,
            _readTypes(
              data.interfaceTypeArguments,
              const <InterfaceType>[],
            ),
          );
        }
        return DynamicTypeImpl.instance;
      case LinkedNodeTypeKind.typeParameter:
        var element = _getElement(data.typeParameterParameter);
        // TODO(scheglov) Remove when references include all type parameters.
        element ??= TypeParameterElementImpl('', -1);
        return TypeParameterTypeImpl(element);
      case LinkedNodeTypeKind.void_:
        return VoidTypeImpl.instance;
      default:
        throw UnimplementedError('Type kind: ${data.kind}');
    }
  }

  List<T> _readTypes<T extends DartType>(
    List<LinkedNodeType> dataList,
    List<T> ifEmpty,
  ) {
    if (dataList.isEmpty) return ifEmpty;

    var result = List<T>(dataList.length);
    for (var i = 0; i < dataList.length; ++i) {
      var data = dataList[i];
      result[i] = _readType(data);
    }
    return result;
  }
}
