// 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/token.dart';
import 'package:analyzer/dart/ast/visitor.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/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linking_bundle_context.dart';
import 'package:analyzer/src/summary2/tokens_context.dart';

/// Serializer of fully resolved ASTs into flat buffers.
class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
  final LinkingBundleContext _linkingContext;
  final TokensContext _tokensContext;

  /// This field is set temporary while visiting [FieldDeclaration] or
  /// [TopLevelVariableDeclaration] to store data shared among all variables
  /// in these declarations.
  LinkedNodeVariablesDeclarationBuilder _variablesDeclaration;

  AstBinaryWriter(this._linkingContext, this._tokensContext);

  @override
  LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
    return LinkedNodeBuilder.adjacentStrings(
      adjacentStrings_strings: _writeNodeList(node.strings),
    );
  }

  @override
  LinkedNodeBuilder visitAnnotation(Annotation node) {
    var elementComponents = _componentsOfElement(node.element);
    return LinkedNodeBuilder.annotation(
      annotation_arguments: node.arguments?.accept(this),
      annotation_atSign: _getToken(node.atSign),
      annotation_constructorName: node.constructorName?.accept(this),
      annotation_element: elementComponents.rawElement,
      annotation_elementType: elementComponents.definingType,
      annotation_name: node.name?.accept(this),
      annotation_period: _getToken(node.period),
    );
  }

  @override
  LinkedNodeBuilder visitArgumentList(ArgumentList node) {
    return LinkedNodeBuilder.argumentList(
      argumentList_arguments: _writeNodeList(node.arguments),
      argumentList_leftParenthesis: _getToken(node.leftParenthesis),
      argumentList_rightParenthesis: _getToken(node.rightParenthesis),
    );
  }

  @override
  LinkedNodeBuilder visitAsExpression(AsExpression node) {
    return LinkedNodeBuilder.asExpression(
      asExpression_asOperator: _getToken(node.asOperator),
      asExpression_expression: node.expression.accept(this),
      asExpression_type: node.type.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) {
    return LinkedNodeBuilder.assertInitializer(
      assertInitializer_assertKeyword: _getToken(node.assertKeyword),
      assertInitializer_comma: _getToken(node.comma),
      assertInitializer_condition: node.condition.accept(this),
      assertInitializer_leftParenthesis: _getToken(node.leftParenthesis),
      assertInitializer_message: node.message?.accept(this),
      assertInitializer_rightParenthesis: _getToken(node.rightParenthesis),
    );
  }

  @override
  LinkedNodeBuilder visitAssertStatement(AssertStatement node) {
    var builder = LinkedNodeBuilder.assertStatement(
      assertStatement_assertKeyword: _getToken(node.assertKeyword),
      assertStatement_comma: _getToken(node.comma),
      assertStatement_condition: node.condition.accept(this),
      assertStatement_leftParenthesis: _getToken(node.leftParenthesis),
      assertStatement_message: node.message?.accept(this),
      assertStatement_rightParenthesis: _getToken(node.rightParenthesis),
      assertStatement_semicolon: _getToken(node.semicolon),
    );
    _storeStatement(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.assignmentExpression(
      assignmentExpression_element: elementComponents.rawElement,
      assignmentExpression_elementType: elementComponents.definingType,
      assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
      assignmentExpression_operator: _getToken(node.operator),
      assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) {
    return LinkedNodeBuilder.awaitExpression(
      awaitExpression_awaitKeyword: _getToken(node.awaitKeyword),
      awaitExpression_expression: node.expression.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.binaryExpression(
      binaryExpression_element: elementComponents.rawElement,
      binaryExpression_elementType: elementComponents.definingType,
      binaryExpression_leftOperand: node.leftOperand.accept(this),
      binaryExpression_operator: _getToken(node.operator),
      binaryExpression_rightOperand: node.rightOperand.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitBlock(Block node) {
    return LinkedNodeBuilder.block(
      block_leftBracket: _getToken(node.leftBracket),
      block_rightBracket: _getToken(node.rightBracket),
      block_statements: _writeNodeList(node.statements),
    );
  }

  @override
  LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) {
    return LinkedNodeBuilder.blockFunctionBody(
      blockFunctionBody_block: node.block.accept(this),
      blockFunctionBody_keyword: _getToken(node.keyword),
      blockFunctionBody_star: _getToken(node.star),
    );
  }

  @override
  LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) {
    return LinkedNodeBuilder.booleanLiteral(
      booleanLiteral_literal: _getToken(node.literal),
      booleanLiteral_value: node.value,
    );
  }

  @override
  LinkedNodeBuilder visitBreakStatement(BreakStatement node) {
    var builder = LinkedNodeBuilder.breakStatement(
      breakStatement_breakKeyword: _getToken(node.breakKeyword),
      breakStatement_label: node.label?.accept(this),
      breakStatement_semicolon: _getToken(node.semicolon),
    );
    _storeStatement(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitCascadeExpression(CascadeExpression node) {
    var builder = LinkedNodeBuilder.cascadeExpression(
      cascadeExpression_target: node.target.accept(this),
      cascadeExpression_sections: _writeNodeList(node.cascadeSections),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitCatchClause(CatchClause node) {
    return LinkedNodeBuilder.catchClause(
      catchClause_body: node.body.accept(this),
      catchClause_catchKeyword: _getToken(node.catchKeyword),
      catchClause_comma: _getToken(node.comma),
      catchClause_exceptionParameter: node.exceptionParameter?.accept(this),
      catchClause_exceptionType: node.exceptionType?.accept(this),
      catchClause_leftParenthesis: _getToken(node.leftParenthesis),
      catchClause_onKeyword: _getToken(node.onKeyword),
      catchClause_rightParenthesis: _getToken(node.rightParenthesis),
      catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) {
    var builder = LinkedNodeBuilder.classDeclaration(
      classDeclaration_abstractKeyword: _getToken(node.abstractKeyword),
      classDeclaration_classKeyword: _getToken(node.classKeyword),
      classDeclaration_extendsClause: node.extendsClause?.accept(this),
      classDeclaration_nativeClause: node.nativeClause?.accept(this),
      classDeclaration_withClause: node.withClause?.accept(this),
    );
    _storeClassOrMixinDeclaration(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) {
    var builder = LinkedNodeBuilder.classTypeAlias(
      classTypeAlias_abstractKeyword: _getToken(node.abstractKeyword),
      classTypeAlias_equals: _getToken(node.equals),
      classTypeAlias_implementsClause: node.implementsClause?.accept(this),
      classTypeAlias_superclass: node.superclass.accept(this),
      classTypeAlias_typeParameters: node.typeParameters?.accept(this),
      classTypeAlias_withClause: node.withClause.accept(this),
    );
    _storeTypeAlias(builder, node);
    _storeIsSimpleBounded(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitComment(Comment node) {
    LinkedNodeCommentType type;
    if (node.isBlock) {
      type = LinkedNodeCommentType.block;
    } else if (node.isDocumentation) {
      type = LinkedNodeCommentType.documentation;
    } else if (node.isEndOfLine) {
      type = LinkedNodeCommentType.endOfLine;
    }

    return LinkedNodeBuilder.comment(
      comment_tokens: _getTokens(node.tokens),
      comment_type: type,
    );
  }

  @override
  LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) {
    var builder = LinkedNodeBuilder.compilationUnit(
      compilationUnit_beginToken: _getToken(node.beginToken),
      compilationUnit_declarations: _writeNodeList(node.declarations),
      compilationUnit_directives: _writeNodeList(node.directives),
      compilationUnit_endToken: _getToken(node.endToken),
      compilationUnit_scriptTag: node.scriptTag?.accept(this),
    );
    _storeCodeOffsetLength(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) {
    var builder = LinkedNodeBuilder.conditionalExpression(
      conditionalExpression_colon: _getToken(node.colon),
      conditionalExpression_condition: node.condition.accept(this),
      conditionalExpression_elseExpression: node.elseExpression.accept(this),
      conditionalExpression_question: _getToken(node.question),
      conditionalExpression_thenExpression: node.thenExpression.accept(this),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitConfiguration(Configuration node) {
    return LinkedNodeBuilder.configuration(
      configuration_equalToken: _getToken(node.equalToken),
      configuration_ifKeyword: _getToken(node.ifKeyword),
      configuration_leftParenthesis: _getToken(node.leftParenthesis),
      configuration_name: node.name?.accept(this),
      configuration_rightParenthesis: _getToken(node.rightParenthesis),
      configuration_value: node.value?.accept(this),
      configuration_uri: node.uri?.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) {
    var builder = LinkedNodeBuilder.constructorDeclaration(
      constructorDeclaration_body: node.body?.accept(this),
      constructorDeclaration_constKeyword: _getToken(node.constKeyword),
      constructorDeclaration_externalKeyword: _getToken(node.externalKeyword),
      constructorDeclaration_factoryKeyword: _getToken(node.factoryKeyword),
      constructorDeclaration_initializers: _writeNodeList(node.initializers),
      constructorDeclaration_name: node.name?.accept(this),
      constructorDeclaration_parameters: node.parameters.accept(this),
      constructorDeclaration_period: _getToken(node.period),
      constructorDeclaration_redirectedConstructor:
          node.redirectedConstructor?.accept(this),
      constructorDeclaration_returnType: node.returnType.accept(this),
      constructorDeclaration_separator: _getToken(node.separator),
    );
    _storeClassMember(builder, node);
    _storeCodeOffsetLength(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitConstructorFieldInitializer(
      ConstructorFieldInitializer node) {
    var builder = LinkedNodeBuilder.constructorFieldInitializer(
      constructorFieldInitializer_equals: _getToken(node.equals),
      constructorFieldInitializer_expression: node.expression.accept(this),
      constructorFieldInitializer_fieldName: node.fieldName.accept(this),
      constructorFieldInitializer_period: _getToken(node.period),
      constructorFieldInitializer_thisKeyword: _getToken(node.thisKeyword),
    );
    _storeConstructorInitializer(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitConstructorName(ConstructorName node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.constructorName(
      constructorName_element: elementComponents.rawElement,
      constructorName_elementType: elementComponents.definingType,
      constructorName_name: node.name?.accept(this),
      constructorName_period: _getToken(node.period),
      constructorName_type: node.type.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitContinueStatement(ContinueStatement node) {
    var builder = LinkedNodeBuilder.continueStatement(
      continueStatement_continueKeyword: _getToken(node.continueKeyword),
      continueStatement_label: node.label?.accept(this),
      continueStatement_semicolon: _getToken(node.semicolon),
    );
    _storeStatement(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) {
    var builder = LinkedNodeBuilder.declaredIdentifier(
      declaredIdentifier_identifier: node.identifier.accept(this),
      declaredIdentifier_keyword: _getToken(node.keyword),
      declaredIdentifier_type: node.type?.accept(this),
    );
    _storeDeclaration(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitDefaultFormalParameter(DefaultFormalParameter node) {
    var builder = LinkedNodeBuilder.defaultFormalParameter(
      defaultFormalParameter_defaultValue: node.defaultValue?.accept(this),
      defaultFormalParameter_kind: _toParameterKind(node),
      defaultFormalParameter_parameter: node.parameter.accept(this),
      defaultFormalParameter_separator: _getToken(node.separator),
    );
    _storeCodeOffsetLength(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitDoStatement(DoStatement node) {
    return LinkedNodeBuilder.doStatement(
      doStatement_body: node.body.accept(this),
      doStatement_condition: node.condition.accept(this),
      doStatement_doKeyword: _getToken(node.doKeyword),
      doStatement_leftParenthesis: _getToken(node.leftParenthesis),
      doStatement_rightParenthesis: _getToken(node.rightParenthesis),
      doStatement_semicolon: _getToken(node.semicolon),
      doStatement_whileKeyword: _getToken(node.whileKeyword),
    );
  }

  @override
  LinkedNodeBuilder visitDottedName(DottedName node) {
    return LinkedNodeBuilder.dottedName(
      dottedName_components: _writeNodeList(node.components),
    );
  }

  @override
  LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) {
    return LinkedNodeBuilder.doubleLiteral(
      doubleLiteral_literal: _getToken(node.literal),
      doubleLiteral_value: node.value,
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) {
    var builder = LinkedNodeBuilder.emptyFunctionBody(
      emptyFunctionBody_semicolon: _getToken(node.semicolon),
    );
    _storeFunctionBody(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) {
    return LinkedNodeBuilder.emptyStatement(
      emptyStatement_semicolon: _getToken(node.semicolon),
    );
  }

  @override
  LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) {
    var builder = LinkedNodeBuilder.enumConstantDeclaration(
      enumConstantDeclaration_name: node.name.accept(this),
    );
    _storeDeclaration(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) {
    var builder = LinkedNodeBuilder.enumDeclaration(
      enumDeclaration_constants: _writeNodeList(node.constants),
      enumDeclaration_enumKeyword: _getToken(node.enumKeyword),
      enumDeclaration_leftBracket: _getToken(node.leftBracket),
      enumDeclaration_rightBracket: _getToken(node.rightBracket),
    );
    _storeNamedCompilationUnitMember(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitExportDirective(ExportDirective node) {
    var builder = LinkedNodeBuilder.exportDirective();
    _storeNamespaceDirective(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) {
    return LinkedNodeBuilder.expressionFunctionBody(
      expressionFunctionBody_arrow: _getToken(node.functionDefinition),
      expressionFunctionBody_expression: node.expression.accept(this),
      expressionFunctionBody_keyword: _getToken(node.keyword),
      expressionFunctionBody_semicolon: _getToken(node.semicolon),
    );
  }

  @override
  LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) {
    return LinkedNodeBuilder.expressionStatement(
      expressionStatement_expression: node.expression.accept(this),
      expressionStatement_semicolon: _getToken(node.semicolon),
    );
  }

  @override
  LinkedNodeBuilder visitExtendsClause(ExtendsClause node) {
    return LinkedNodeBuilder.extendsClause(
      extendsClause_extendsKeyword: _getToken(node.extendsKeyword),
      extendsClause_superclass: node.superclass.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) {
    _variablesDeclaration = LinkedNodeVariablesDeclarationBuilder(
      isCovariant: node.covariantKeyword != null,
      isStatic: node.isStatic,
    );

    var builder = LinkedNodeBuilder.fieldDeclaration(
      fieldDeclaration_covariantKeyword: _getToken(node.covariantKeyword),
      fieldDeclaration_fields: node.fields.accept(this),
      fieldDeclaration_semicolon: _getToken(node.semicolon),
      fieldDeclaration_staticKeyword: _getToken(node.staticKeyword),
    );
    _storeClassMember(builder, node);

    _variablesDeclaration.comment = builder.annotatedNode_comment;
    _variablesDeclaration = null;

    return builder;
  }

  @override
  LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) {
    var builder = LinkedNodeBuilder.fieldFormalParameter(
      fieldFormalParameter_formalParameters: node.parameters?.accept(this),
      fieldFormalParameter_keyword: _getToken(node.keyword),
      fieldFormalParameter_period: _getToken(node.period),
      fieldFormalParameter_thisKeyword: _getToken(node.thisKeyword),
      fieldFormalParameter_type: node.type?.accept(this),
      fieldFormalParameter_typeParameters: node.typeParameters?.accept(this),
    );
    _storeNormalFormalParameter(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitForEachPartsWithDeclaration(
      ForEachPartsWithDeclaration node) {
    var builder = LinkedNodeBuilder.forEachPartsWithDeclaration(
      forEachPartsWithDeclaration_loopVariable: node.loopVariable.accept(this),
    );
    _storeForEachParts(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitForEachPartsWithIdentifier(
      ForEachPartsWithIdentifier node) {
    var builder = LinkedNodeBuilder.forEachPartsWithIdentifier(
      forEachPartsWithIdentifier_identifier: node.identifier.accept(this),
    );
    _storeForEachParts(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitForElement(ForElement node) {
    var builder = LinkedNodeBuilder.forElement(
      forElement_body: node.body.accept(this),
    );
    _storeForMixin(builder, node as ForElementImpl);
    return builder;
  }

  @override
  LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) {
    return LinkedNodeBuilder.formalParameterList(
      formalParameterList_leftDelimiter: _getToken(node.leftDelimiter),
      formalParameterList_leftParenthesis: _getToken(node.leftParenthesis),
      formalParameterList_parameters: _writeNodeList(node.parameters),
      formalParameterList_rightDelimiter: _getToken(node.rightDelimiter),
      formalParameterList_rightParenthesis: _getToken(node.rightParenthesis),
    );
  }

  @override
  LinkedNodeBuilder visitForPartsWithDeclarations(
      ForPartsWithDeclarations node) {
    var builder = LinkedNodeBuilder.forPartsWithDeclarations(
      forPartsWithDeclarations_variables: node.variables.accept(this),
    );
    _storeForParts(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitForPartsWithExpression(ForPartsWithExpression node) {
    var builder = LinkedNodeBuilder.forPartsWithExpression(
      forPartsWithExpression_initialization: node.initialization?.accept(this),
    );
    _storeForParts(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitForStatement(ForStatement node) {
    var builder = LinkedNodeBuilder.forStatement(
      forStatement_body: node.body.accept(this),
    );
    _storeForMixin(builder, node as ForStatementImpl);
    return builder;
  }

  @override
  LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) {
    var builder = LinkedNodeBuilder.functionDeclaration(
      functionDeclaration_externalKeyword: _getToken(node.externalKeyword),
      functionDeclaration_functionExpression:
          node.functionExpression?.accept(this),
      functionDeclaration_propertyKeyword: _getToken(node.propertyKeyword),
      functionDeclaration_returnType: node.returnType?.accept(this),
    );
    _storeNamedCompilationUnitMember(builder, node);
    _writeActualReturnType(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitFunctionDeclarationStatement(
      FunctionDeclarationStatement node) {
    return LinkedNodeBuilder.functionDeclarationStatement(
      functionDeclarationStatement_functionDeclaration:
          node.functionDeclaration.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) {
    return LinkedNodeBuilder.functionExpression(
      functionExpression_body: node.body?.accept(this),
      functionExpression_formalParameters: node.parameters?.accept(this),
      functionExpression_typeParameters: node.typeParameters?.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitFunctionExpressionInvocation(
      FunctionExpressionInvocation node) {
    var builder = LinkedNodeBuilder.functionExpressionInvocation(
      functionExpressionInvocation_function: node.function?.accept(this),
    );
    _storeInvocationExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) {
    var builder = LinkedNodeBuilder.functionTypeAlias(
      functionTypeAlias_formalParameters: node.parameters.accept(this),
      functionTypeAlias_returnType: node.returnType?.accept(this),
      functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
      typeAlias_hasSelfReference:
          LazyFunctionTypeAlias.getHasSelfReference(node),
    );
    _storeTypeAlias(builder, node);
    _writeActualReturnType(builder, node);
    _storeIsSimpleBounded(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitFunctionTypedFormalParameter(
      FunctionTypedFormalParameter node) {
    var builder = LinkedNodeBuilder.functionTypedFormalParameter(
      functionTypedFormalParameter_formalParameters:
          node.parameters.accept(this),
      functionTypedFormalParameter_returnType: node.returnType?.accept(this),
      functionTypedFormalParameter_typeParameters:
          node.typeParameters?.accept(this),
    );
    _storeNormalFormalParameter(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
    var builder = LinkedNodeBuilder.genericFunctionType(
      genericFunctionType_formalParameters: node.parameters.accept(this),
      genericFunctionType_functionKeyword: _getToken(node.functionKeyword),
      genericFunctionType_question: _getToken(node.question),
      genericFunctionType_returnType: node.returnType?.accept(this),
      genericFunctionType_type: _writeType(node.type),
      genericFunctionType_typeParameters: node.typeParameters?.accept(this),
    );
    _writeActualReturnType(builder, node);

    var id = LazyAst.getGenericFunctionTypeId(node);
    builder.genericFunctionType_id = id;

    return builder;
  }

  @override
  LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) {
    var builder = LinkedNodeBuilder.genericTypeAlias(
      genericTypeAlias_equals: _getToken(node.equals),
      genericTypeAlias_functionType: node.functionType.accept(this),
      genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
      typeAlias_hasSelfReference:
          LazyGenericTypeAlias.getHasSelfReference(node),
    );
    _storeTypeAlias(builder, node);
    _storeIsSimpleBounded(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitHideCombinator(HideCombinator node) {
    var builder = LinkedNodeBuilder.hideCombinator(
      hideCombinator_hiddenNames: _writeNodeList(node.hiddenNames),
    );
    _storeCombinator(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitIfElement(IfElement node) {
    var builder = LinkedNodeBuilder.ifElement(
      ifElement_elseElement: node.elseElement?.accept(this),
      ifElement_thenElement: node.thenElement.accept(this),
    );
    _storeIfMixin(builder, node as IfElementImpl);
    return builder;
  }

  @override
  LinkedNodeBuilder visitIfStatement(IfStatement node) {
    var builder = LinkedNodeBuilder.ifStatement(
      ifMixin_condition: node.condition.accept(this),
      ifMixin_elseKeyword: _getToken(node.elseKeyword),
      ifStatement_elseStatement: node.elseStatement?.accept(this),
      ifMixin_ifKeyword: _getToken(node.ifKeyword),
      ifMixin_leftParenthesis: _getToken(node.leftParenthesis),
      ifMixin_rightParenthesis: _getToken(node.rightParenthesis),
      ifStatement_thenStatement: node.thenStatement.accept(this),
    );
    _storeIfMixin(builder, node as IfStatementImpl);
    return builder;
  }

  @override
  LinkedNodeBuilder visitImplementsClause(ImplementsClause node) {
    return LinkedNodeBuilder.implementsClause(
      implementsClause_implementsKeyword: _getToken(node.implementsKeyword),
      implementsClause_interfaces: _writeNodeList(node.interfaces),
    );
  }

  @override
  LinkedNodeBuilder visitImportDirective(ImportDirective node) {
    var builder = LinkedNodeBuilder.importDirective(
      importDirective_asKeyword: _getToken(node.asKeyword),
      importDirective_deferredKeyword: _getToken(node.deferredKeyword),
      importDirective_prefix: node.prefix?.accept(this),
    );
    _storeNamespaceDirective(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.indexExpression(
      indexExpression_element: elementComponents.rawElement,
      indexExpression_elementType: elementComponents.definingType,
      indexExpression_index: node.index.accept(this),
      indexExpression_leftBracket: _getToken(node.leftBracket),
      indexExpression_period: _getToken(node.period),
      indexExpression_rightBracket: _getToken(node.rightBracket),
      indexExpression_target: node.target?.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitInstanceCreationExpression(
      InstanceCreationExpression node) {
    InstanceCreationExpressionImpl nodeImpl = node;
    return LinkedNodeBuilder.instanceCreationExpression(
      instanceCreationExpression_arguments: node.argumentList.accept(this),
      instanceCreationExpression_constructorName:
          node.constructorName.accept(this),
      instanceCreationExpression_keyword: _getToken(node.keyword),
      instanceCreationExpression_typeArguments:
          nodeImpl.typeArguments?.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) {
    return LinkedNodeBuilder.integerLiteral(
      integerLiteral_literal: _getToken(node.literal),
      integerLiteral_value: node.value,
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) {
    return LinkedNodeBuilder.interpolationExpression(
      interpolationExpression_expression: node.expression.accept(this),
      interpolationExpression_leftBracket: _getToken(node.leftBracket),
      interpolationExpression_rightBracket: _getToken(node.rightBracket),
    );
  }

  @override
  LinkedNodeBuilder visitInterpolationString(InterpolationString node) {
    return LinkedNodeBuilder.interpolationString(
      interpolationString_token: _getToken(node.contents),
      interpolationString_value: node.value,
    );
  }

  @override
  LinkedNodeBuilder visitIsExpression(IsExpression node) {
    var builder = LinkedNodeBuilder.isExpression(
      isExpression_expression: node.expression.accept(this),
      isExpression_isOperator: _getToken(node.isOperator),
      isExpression_notOperator: _getToken(node.notOperator),
      isExpression_type: node.type.accept(this),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitLabel(Label node) {
    return LinkedNodeBuilder.label(
      label_label: node.label.accept(this),
      label_colon: _getToken(node.colon),
    );
  }

  @override
  LinkedNodeBuilder visitLabeledStatement(LabeledStatement node) {
    return LinkedNodeBuilder.labeledStatement(
      labeledStatement_labels: _writeNodeList(node.labels),
      labeledStatement_statement: node.statement.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) {
    var builder = LinkedNodeBuilder.libraryDirective(
      libraryDirective_name: node.name.accept(this),
      directive_semicolon: _getToken(node.semicolon),
    );
    _storeDirective(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitLibraryIdentifier(LibraryIdentifier node) {
    return LinkedNodeBuilder.libraryIdentifier(
      libraryIdentifier_components: _writeNodeList(node.components),
    );
  }

  @override
  LinkedNodeBuilder visitListLiteral(ListLiteral node) {
    var builder = LinkedNodeBuilder.listLiteral(
      listLiteral_elements: _writeNodeList(node.elements),
      listLiteral_leftBracket: _getToken(node.leftBracket),
      listLiteral_rightBracket: _getToken(node.rightBracket),
    );
    _storeTypedLiteral(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) {
    return LinkedNodeBuilder.mapLiteralEntry(
      mapLiteralEntry_key: node.key.accept(this),
      mapLiteralEntry_separator: _getToken(node.separator),
      mapLiteralEntry_value: node.value.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
    var builder = LinkedNodeBuilder.methodDeclaration(
      methodDeclaration_body: node.body?.accept(this),
      methodDeclaration_externalKeyword: _getToken(node.externalKeyword),
      methodDeclaration_formalParameters: node.parameters?.accept(this),
      methodDeclaration_modifierKeyword: _getToken(node.modifierKeyword),
      methodDeclaration_name: node.name.accept(this),
      methodDeclaration_operatorKeyword: _getToken(node.operatorKeyword),
      methodDeclaration_propertyKeyword: _getToken(node.propertyKeyword),
      methodDeclaration_returnType: node.returnType?.accept(this),
      methodDeclaration_typeParameters: node.typeParameters?.accept(this),
    );
    _storeClassMember(builder, node);
    _storeCodeOffsetLength(builder, node);
    _writeActualReturnType(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) {
    var builder = LinkedNodeBuilder.methodInvocation(
      methodInvocation_methodName: node.methodName?.accept(this),
      methodInvocation_operator: _getToken(node.operator),
      methodInvocation_target: node.target?.accept(this),
    );
    _storeInvocationExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) {
    var builder = LinkedNodeBuilder.mixinDeclaration(
      mixinDeclaration_mixinKeyword: _getToken(node.mixinKeyword),
      mixinDeclaration_onClause: node.onClause?.accept(this),
    );
    _storeClassOrMixinDeclaration(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitNamedExpression(NamedExpression node) {
    return LinkedNodeBuilder.namedExpression(
      namedExpression_expression: node.expression.accept(this),
      namedExpression_name: node.name.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitNativeClause(NativeClause node) {
    return LinkedNodeBuilder.nativeClause(
      nativeClause_nativeKeyword: _getToken(node.nativeKeyword),
      nativeClause_name: node.name.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) {
    return LinkedNodeBuilder.nativeFunctionBody(
      nativeFunctionBody_nativeKeyword: _getToken(node.nativeKeyword),
      nativeFunctionBody_semicolon: _getToken(node.semicolon),
      nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitNullLiteral(NullLiteral node) {
    var builder = LinkedNodeBuilder.nullLiteral(
      nullLiteral_literal: _getToken(node.literal),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitOnClause(OnClause node) {
    return LinkedNodeBuilder.onClause(
      onClause_onKeyword: _getToken(node.onKeyword),
      onClause_superclassConstraints:
          _writeNodeList(node.superclassConstraints),
    );
  }

  @override
  LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) {
    var builder = LinkedNodeBuilder.parenthesizedExpression(
      parenthesizedExpression_expression: node.expression.accept(this),
      parenthesizedExpression_leftParenthesis: _getToken(node.leftParenthesis),
      parenthesizedExpression_rightParenthesis:
          _getToken(node.rightParenthesis),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitPartDirective(PartDirective node) {
    var builder = LinkedNodeBuilder.partDirective(
      directive_semicolon: _getToken(node.semicolon),
    );
    _storeUriBasedDirective(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) {
    var builder = LinkedNodeBuilder.partOfDirective(
      partOfDirective_libraryName: node.libraryName?.accept(this),
      partOfDirective_ofKeyword: _getToken(node.ofKeyword),
      directive_semicolon: _getToken(node.semicolon),
      partOfDirective_uri: node.uri?.accept(this),
    );
    _storeDirective(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.postfixExpression(
      expression_type: _writeType(node.staticType),
      postfixExpression_element: elementComponents.rawElement,
      postfixExpression_elementType: elementComponents.definingType,
      postfixExpression_operand: node.operand.accept(this),
      postfixExpression_operator: _getToken(node.operator),
    );
  }

  @override
  LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
    return LinkedNodeBuilder.prefixedIdentifier(
      prefixedIdentifier_identifier: node.identifier.accept(this),
      prefixedIdentifier_period: _getToken(node.period),
      prefixedIdentifier_prefix: node.prefix.accept(this),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    return LinkedNodeBuilder.prefixExpression(
      expression_type: _writeType(node.staticType),
      prefixExpression_element: elementComponents.rawElement,
      prefixExpression_elementType: elementComponents.definingType,
      prefixExpression_operand: node.operand.accept(this),
      prefixExpression_operator: _getToken(node.operator),
    );
  }

  @override
  LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) {
    var builder = LinkedNodeBuilder.propertyAccess(
      propertyAccess_operator: _getToken(node.operator),
      propertyAccess_propertyName: node.propertyName.accept(this),
      propertyAccess_target: node.target?.accept(this),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitRedirectingConstructorInvocation(
      RedirectingConstructorInvocation node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    var builder = LinkedNodeBuilder.redirectingConstructorInvocation(
      redirectingConstructorInvocation_arguments:
          node.argumentList.accept(this),
      redirectingConstructorInvocation_constructorName:
          node.constructorName?.accept(this),
      redirectingConstructorInvocation_element: elementComponents.rawElement,
      redirectingConstructorInvocation_elementType:
          elementComponents.definingType,
      redirectingConstructorInvocation_period: _getToken(node.period),
      redirectingConstructorInvocation_thisKeyword: _getToken(node.thisKeyword),
    );
    _storeConstructorInitializer(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) {
    var builder = LinkedNodeBuilder.rethrowExpression(
      rethrowExpression_rethrowKeyword: _getToken(node.rethrowKeyword),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitReturnStatement(ReturnStatement node) {
    return LinkedNodeBuilder.returnStatement(
      returnStatement_expression: node.expression?.accept(this),
      returnStatement_returnKeyword: _getToken(node.returnKeyword),
      returnStatement_semicolon: _getToken(node.semicolon),
    );
  }

  @override
  LinkedNodeBuilder visitScriptTag(ScriptTag node) {
    return LinkedNodeBuilder.scriptTag(
      scriptTag_scriptTag: _getToken(node.scriptTag),
    );
  }

  @override
  LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) {
    var builder = LinkedNodeBuilder.setOrMapLiteral(
      setOrMapLiteral_elements: _writeNodeList(node.elements),
      setOrMapLiteral_isMap: node.isMap,
      setOrMapLiteral_isSet: node.isSet,
      setOrMapLiteral_leftBracket: _getToken(node.leftBracket),
      setOrMapLiteral_rightBracket: _getToken(node.rightBracket),
    );
    _storeTypedLiteral(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitShowCombinator(ShowCombinator node) {
    var builder = LinkedNodeBuilder.showCombinator(
      showCombinator_shownNames: _writeNodeList(node.shownNames),
    );
    _storeCombinator(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
    var builder = LinkedNodeBuilder.simpleFormalParameter(
      simpleFormalParameter_keyword: _getToken(node.keyword),
      simpleFormalParameter_type: node.type?.accept(this),
    );
    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
    _storeNormalFormalParameter(builder, node);
    _storeInheritsCovariant(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSimpleIdentifier(SimpleIdentifier node) {
    Element element;
    if (!node.inDeclarationContext()) {
      element = node.staticElement;
      if (element is MultiplyDefinedElement) {
        element = null;
      }
    }

    var elementComponents = _componentsOfElement(element);
    return LinkedNodeBuilder.simpleIdentifier(
      simpleIdentifier_element: elementComponents.rawElement,
      simpleIdentifier_elementType: elementComponents.definingType,
      simpleIdentifier_isDeclaration: node is DeclaredSimpleIdentifier,
      simpleIdentifier_token: _getToken(node.token),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) {
    var builder = LinkedNodeBuilder.simpleStringLiteral(
      simpleStringLiteral_token: _getToken(node.literal),
      simpleStringLiteral_value: node.value,
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSpreadElement(SpreadElement node) {
    return LinkedNodeBuilder.spreadElement(
      spreadElement_expression: node.expression.accept(this),
      spreadElement_spreadOperator: _getToken(node.spreadOperator),
    );
  }

  @override
  LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) {
    return LinkedNodeBuilder.stringInterpolation(
      stringInterpolation_elements: _writeNodeList(node.elements),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitSuperConstructorInvocation(
      SuperConstructorInvocation node) {
    var elementComponents = _componentsOfElement(node.staticElement);
    var builder = LinkedNodeBuilder.superConstructorInvocation(
      superConstructorInvocation_arguments: node.argumentList.accept(this),
      superConstructorInvocation_constructorName:
          node.constructorName?.accept(this),
      superConstructorInvocation_element: elementComponents.rawElement,
      superConstructorInvocation_elementType: elementComponents.definingType,
      superConstructorInvocation_period: _getToken(node.period),
      superConstructorInvocation_superKeyword: _getToken(node.superKeyword),
    );
    _storeConstructorInitializer(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSuperExpression(SuperExpression node) {
    var builder = LinkedNodeBuilder.superExpression(
      superExpression_superKeyword: _getToken(node.superKeyword),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSwitchCase(SwitchCase node) {
    var builder = LinkedNodeBuilder.switchCase(
      switchCase_expression: node.expression.accept(this),
    );
    _storeSwitchMember(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSwitchDefault(SwitchDefault node) {
    var builder = LinkedNodeBuilder.switchDefault();
    _storeSwitchMember(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) {
    return LinkedNodeBuilder.switchStatement(
      switchStatement_expression: node.expression.accept(this),
      switchStatement_leftBracket: _getToken(node.leftBracket),
      switchStatement_leftParenthesis: _getToken(node.leftParenthesis),
      switchStatement_members: _writeNodeList(node.members),
      switchStatement_rightBracket: _getToken(node.rightBracket),
      switchStatement_rightParenthesis: _getToken(node.rightParenthesis),
      switchStatement_switchKeyword: _getToken(node.switchKeyword),
    );
  }

  @override
  LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) {
    var builder = LinkedNodeBuilder.symbolLiteral(
      symbolLiteral_poundSign: _getToken(node.poundSign),
      symbolLiteral_components: _getTokens(node.components),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitThisExpression(ThisExpression node) {
    var builder = LinkedNodeBuilder.thisExpression(
      thisExpression_thisKeyword: _getToken(node.thisKeyword),
    );
    _storeExpression(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitThrowExpression(ThrowExpression node) {
    return LinkedNodeBuilder.throwExpression(
      throwExpression_expression: node.expression.accept(this),
      throwExpression_throwKeyword: _getToken(node.throwKeyword),
      expression_type: _writeType(node.staticType),
    );
  }

  @override
  LinkedNodeBuilder visitTopLevelVariableDeclaration(
      TopLevelVariableDeclaration node) {
    _variablesDeclaration = LinkedNodeVariablesDeclarationBuilder();

    var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
      topLevelVariableDeclaration_semicolon: _getToken(node.semicolon),
      topLevelVariableDeclaration_variableList: node.variables?.accept(this),
    );
    _storeCompilationUnitMember(builder, node);

    _variablesDeclaration.comment = builder.annotatedNode_comment;
    _variablesDeclaration = null;

    return builder;
  }

  @override
  LinkedNodeBuilder visitTryStatement(TryStatement node) {
    return LinkedNodeBuilder.tryStatement(
      tryStatement_body: node.body.accept(this),
      tryStatement_catchClauses: _writeNodeList(node.catchClauses),
      tryStatement_finallyBlock: node.finallyBlock?.accept(this),
      tryStatement_finallyKeyword: _getToken(node.finallyKeyword),
      tryStatement_tryKeyword: _getToken(node.tryKeyword),
    );
  }

  @override
  LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) {
    return LinkedNodeBuilder.typeArgumentList(
      typeArgumentList_arguments: _writeNodeList(node.arguments),
      typeArgumentList_leftBracket: _getToken(node.leftBracket),
      typeArgumentList_rightBracket: _getToken(node.rightBracket),
    );
  }

  @override
  LinkedNodeBuilder visitTypeName(TypeName node) {
    return LinkedNodeBuilder.typeName(
      typeName_name: node.name.accept(this),
      typeName_question: _getToken(node.question),
      typeName_type: _writeType(node.type),
      typeName_typeArguments: node.typeArguments?.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitTypeParameter(TypeParameter node) {
    var builder = LinkedNodeBuilder.typeParameter(
      typeParameter_bound: node.bound?.accept(this),
      typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)),
      typeParameter_extendsKeyword: _getToken(node.extendsKeyword),
      typeParameter_name: node.name.accept(this),
    );
    _storeDeclaration(builder, node);
    _storeCodeOffsetLength(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) {
    return LinkedNodeBuilder.typeParameterList(
      typeParameterList_leftBracket: _getToken(node.leftBracket),
      typeParameterList_rightBracket: _getToken(node.rightBracket),
      typeParameterList_typeParameters: _writeNodeList(node.typeParameters),
    );
  }

  @override
  LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
    var builder = LinkedNodeBuilder.variableDeclaration(
      variableDeclaration_equals: _getToken(node.equals),
      variableDeclaration_initializer: node.initializer?.accept(this),
      variableDeclaration_name: node.name.accept(this),
      variableDeclaration_declaration: _variablesDeclaration,
    );
    builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
    _writeActualType(builder, node);
    _storeInheritsCovariant(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitVariableDeclarationList(VariableDeclarationList node) {
    if (_variablesDeclaration != null) {
      _variablesDeclaration.isConst = node.isConst;
      _variablesDeclaration.isFinal = node.isFinal;
    }

    var builder = LinkedNodeBuilder.variableDeclarationList(
      variableDeclarationList_keyword: _getToken(node.keyword),
      variableDeclarationList_type: node.type?.accept(this),
      variableDeclarationList_variables: _writeNodeList(node.variables),
    );
    _storeAnnotatedNode(builder, node);
    _storeCodeOffsetLengthVariables(builder, node);
    return builder;
  }

  @override
  LinkedNodeBuilder visitVariableDeclarationStatement(
      VariableDeclarationStatement node) {
    return LinkedNodeBuilder.variableDeclarationStatement(
      variableDeclarationStatement_semicolon: _getToken(node.semicolon),
      variableDeclarationStatement_variables: node.variables.accept(this),
    );
  }

  @override
  LinkedNodeBuilder visitWhileStatement(WhileStatement node) {
    return LinkedNodeBuilder.whileStatement(
      whileStatement_body: node.body.accept(this),
      whileStatement_condition: node.condition.accept(this),
      whileStatement_leftParenthesis: _getToken(node.leftParenthesis),
      whileStatement_rightParenthesis: _getToken(node.rightParenthesis),
      whileStatement_whileKeyword: _getToken(node.whileKeyword),
    );
  }

  @override
  LinkedNodeBuilder visitWithClause(WithClause node) {
    return LinkedNodeBuilder.withClause(
      withClause_mixinTypes: _writeNodeList(node.mixinTypes),
      withClause_withKeyword: _getToken(node.withKeyword),
    );
  }

  @override
  LinkedNodeBuilder visitYieldStatement(YieldStatement node) {
    var builder = LinkedNodeBuilder.yieldStatement(
      yieldStatement_yieldKeyword: _getToken(node.yieldKeyword),
      yieldStatement_expression: node.expression.accept(this),
      yieldStatement_semicolon: _getToken(node.semicolon),
      yieldStatement_star: _getToken(node.star),
    );
    _storeStatement(builder, node);
    return builder;
  }

  LinkedNodeBuilder writeNode(AstNode node) {
    return node.accept(this);
  }

  _ElementComponents _componentsOfElement(Element element) {
    while (element is ParameterMember) {
      element = (element as ParameterMember).baseElement;
    }

    if (element is Member) {
      var elementIndex = _indexOfElement(element.baseElement);
      var definingTypeNode = _writeType(element.definingType);
      return _ElementComponents(elementIndex, definingTypeNode);
    }

    var elementIndex = _indexOfElement(element);
    return _ElementComponents(elementIndex, null);
  }

  int _getToken(Token token) {
    return _tokensContext.indexOfToken(token);
  }

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

  int _indexOfElement(Element element) {
    return _linkingContext.indexOfElement(element);
  }

  void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
    builder
      ..annotatedNode_comment = node.documentationComment?.accept(this)
      ..annotatedNode_metadata = _writeNodeList(node.metadata);
  }

  void _storeClassMember(LinkedNodeBuilder builder, ClassMember node) {
    _storeDeclaration(builder, node);
  }

  void _storeClassOrMixinDeclaration(
      LinkedNodeBuilder builder, ClassOrMixinDeclaration node) {
    builder
      ..classOrMixinDeclaration_implementsClause =
          node.implementsClause?.accept(this)
      ..classOrMixinDeclaration_leftBracket = _getToken(node.leftBracket)
      ..classOrMixinDeclaration_members = _writeNodeList(node.members)
      ..classOrMixinDeclaration_rightBracket = _getToken(node.rightBracket)
      ..classOrMixinDeclaration_typeParameters =
          node.typeParameters?.accept(this);
    _storeNamedCompilationUnitMember(builder, node);
    _storeIsSimpleBounded(builder, node);
  }

  void _storeCodeOffsetLength(LinkedNodeBuilder builder, AstNode node) {
    builder.codeOffset = node.offset;
    builder.codeLength = node.length;
  }

  void _storeCodeOffsetLengthVariables(
      LinkedNodeBuilder builder, VariableDeclarationList node) {
    var builders = builder.variableDeclarationList_variables;
    for (var i = 0; i < builders.length; ++i) {
      var variableBuilder = builders[i];
      var variableNode = node.variables[i];
      var offset = (i == 0 ? node.parent : variableNode).offset;
      variableBuilder.codeOffset = offset;
      variableBuilder.codeLength = variableNode.end - offset;
    }
  }

  void _storeCombinator(LinkedNodeBuilder builder, Combinator node) {
    builder.combinator_keyword = _getToken(node.keyword);
  }

  void _storeCompilationUnitMember(
      LinkedNodeBuilder builder, CompilationUnitMember node) {
    _storeDeclaration(builder, node);
  }

  void _storeConstructorInitializer(
      LinkedNodeBuilder builder, ConstructorInitializer node) {}

  void _storeDeclaration(LinkedNodeBuilder builder, Declaration node) {
    _storeAnnotatedNode(builder, node);
  }

  void _storeDirective(LinkedNodeBuilder builder, Directive node) {
    _storeAnnotatedNode(builder, node);
    builder..directive_keyword = _getToken(node.keyword);
  }

  void _storeExpression(LinkedNodeBuilder builder, Expression node) {
    builder.expression_type = _writeType(node.staticType);
  }

  void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) {
    _storeForLoopParts(builder, node);
    builder
      ..forEachParts_inKeyword = _getToken(node.inKeyword)
      ..forEachParts_iterable = node.iterable?.accept(this);
  }

  void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {}

  void _storeFormalParameter(LinkedNodeBuilder builder, FormalParameter node) {
    _storeCodeOffsetLength(builder, node);
    _writeActualType(builder, node);
  }

  void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
    builder
      ..forMixin_awaitKeyword = _getToken(node.awaitKeyword)
      ..forMixin_forKeyword = _getToken(node.forKeyword)
      ..forMixin_forLoopParts = node.forLoopParts.accept(this)
      ..forMixin_leftParenthesis = _getToken(node.leftParenthesis)
      ..forMixin_rightParenthesis = _getToken(node.rightParenthesis);
  }

  void _storeForParts(LinkedNodeBuilder builder, ForParts node) {
    _storeForLoopParts(builder, node);
    builder
      ..forParts_leftSeparator = _getToken(node.leftSeparator)
      ..forParts_condition = node.condition?.accept(this)
      ..forParts_rightSeparator = _getToken(node.rightSeparator)
      ..forParts_updaters = _writeNodeList(node.updaters);
  }

  void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {}

  void _storeIfMixin(LinkedNodeBuilder builder, IfMixin node) {
    builder
      ..ifMixin_condition = node.condition.accept(this)
      ..ifMixin_elseKeyword = _getToken(node.elseKeyword)
      ..ifMixin_ifKeyword = _getToken(node.ifKeyword)
      ..ifMixin_leftParenthesis = _getToken(node.leftParenthesis)
      ..ifMixin_rightParenthesis = _getToken(node.rightParenthesis);
  }

  void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) {
    var value = LazyAst.getInheritsCovariant(node);
    builder.inheritsCovariant = value;
  }

  void _storeInvocationExpression(
      LinkedNodeBuilder builder, InvocationExpression node) {
    _storeExpression(builder, node);
    builder
      ..invocationExpression_arguments = node.argumentList.accept(this)
      ..invocationExpression_invokeType = _writeType(node.staticInvokeType)
      ..invocationExpression_typeArguments = node.typeArguments?.accept(this);
  }

  void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) {
    var flag = LazyAst.isSimplyBounded(node);
    // TODO(scheglov) Check for `null` when writing resolved AST.
    builder.simplyBoundable_isSimplyBounded = flag;
  }

  void _storeNamedCompilationUnitMember(
      LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
    _storeCompilationUnitMember(builder, node);
    _storeCodeOffsetLength(builder, node);
    builder..namedCompilationUnitMember_name = node.name.accept(this);
  }

  void _storeNamespaceDirective(
      LinkedNodeBuilder builder, NamespaceDirective node) {
    _storeUriBasedDirective(builder, node);
    builder
      ..namespaceDirective_combinators = _writeNodeList(node.combinators)
      ..namespaceDirective_configurations = _writeNodeList(node.configurations)
      ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node)
      ..directive_semicolon = _getToken(node.semicolon);
  }

  void _storeNormalFormalParameter(
      LinkedNodeBuilder builder, NormalFormalParameter node) {
    _storeFormalParameter(builder, node);
    builder
      ..normalFormalParameter_comment = node.documentationComment?.accept(this)
      ..normalFormalParameter_covariantKeyword =
          _getToken(node.covariantKeyword)
      ..normalFormalParameter_identifier = node.identifier?.accept(this)
      ..normalFormalParameter_metadata = _writeNodeList(node.metadata)
      ..normalFormalParameter_requiredKeyword = _getToken(node.requiredKeyword);
  }

  void _storeStatement(LinkedNodeBuilder builder, Statement node) {}

  void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) {
    builder.switchMember_colon = _getToken(node.colon);
    builder.switchMember_keyword = _getToken(node.keyword);
    builder.switchMember_labels = _writeNodeList(node.labels);
    builder.switchMember_statements = _writeNodeList(node.statements);
  }

  void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) {
    _storeNamedCompilationUnitMember(builder, node);
    builder
      ..typeAlias_semicolon = _getToken(node.semicolon)
      ..typeAlias_typedefKeyword = _getToken(node.typedefKeyword);
  }

  void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node) {
    _storeExpression(builder, node);
    builder
      ..typedLiteral_constKeyword = _getToken(node.constKeyword)
      ..typedLiteral_typeArguments = node.typeArguments?.accept(this);
  }

  void _storeUriBasedDirective(
      LinkedNodeBuilder builder, UriBasedDirective node) {
    _storeDirective(builder, node);
    builder
      ..uriBasedDirective_uri = node.uri.accept(this)
      ..uriBasedDirective_uriContent = node.uriContent
      ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
  }

  void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
    var type = LazyAst.getReturnType(node);
    // TODO(scheglov) Check for `null` when writing resolved AST.
    builder.actualReturnType = _writeType(type);
  }

  void _writeActualType(LinkedNodeBuilder builder, AstNode node) {
    var type = LazyAst.getType(node);
    // TODO(scheglov) Check for `null` when writing resolved AST.
    builder.actualType = _writeType(type);
  }

  List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
    var result = List<LinkedNodeBuilder>.filled(
      nodeList.length,
      null,
      growable: true,
    );
    for (var i = 0; i < nodeList.length; ++i) {
      result[i] = nodeList[i].accept(this);
    }
    return result;
  }

  LinkedNodeTypeBuilder _writeType(DartType type) {
    return _linkingContext.writeType(type);
  }

  static LinkedNodeFormalParameterKind _toParameterKind(FormalParameter node) {
    if (node.isRequiredPositional) {
      return LinkedNodeFormalParameterKind.requiredPositional;
    } else if (node.isRequiredNamed) {
      return LinkedNodeFormalParameterKind.requiredNamed;
    } else if (node.isOptionalPositional) {
      return LinkedNodeFormalParameterKind.optionalPositional;
    } else if (node.isOptionalNamed) {
      return LinkedNodeFormalParameterKind.optionalNamed;
    } else {
      throw new StateError('Unknown kind of parameter');
    }
  }
}

/// Components of a [Member] - the raw element, and the defining type.
class _ElementComponents {
  final int rawElement;
  final LinkedNodeType definingType;

  _ElementComponents(this.rawElement, this.definingType);
}
