// 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/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/source/line_info.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/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/ast_binary_reader.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/type_builder.dart';

/// The context of a unit - the context of the bundle, and the unit tokens.
class LinkedUnitContext {
  final LinkedBundleContext bundleContext;
  final LinkedLibraryContext libraryContext;
  final int indexInLibrary;
  final String partUriStr;
  final String uriStr;
  final Reference reference;
  final bool isSynthetic;
  final LinkedNodeUnit data;

  /// Optional informative data for the unit.
  List<UnlinkedInformativeData> informativeData;

  AstBinaryReader _astReader;

  CompilationUnit _unit;
  bool _hasDirectivesRead = false;

  /// Mapping from identifiers to synthetic type parameters.
  ///
  /// Synthetic type parameters are added when [readType] begins reading a
  /// [FunctionType], and removed when reading is done.
  final Map<int, TypeParameterElementImpl> _typeParameters = {};

  int _nextSyntheticTypeParameterId = 0x10000;

  LinkedUnitContext(
      this.bundleContext,
      this.libraryContext,
      this.indexInLibrary,
      this.partUriStr,
      this.uriStr,
      this.reference,
      this.isSynthetic,
      this.data,
      {CompilationUnit unit}) {
    _astReader = AstBinaryReader(this);
    _astReader.isLazy = unit == null;

    _unit = unit;
    _hasDirectivesRead = _unit != null;
  }

  bool get hasPartOfDirective {
    for (var directive in unit_withDirectives.directives) {
      if (directive is PartOfDirective) {
        return true;
      }
    }
    return false;
  }

  /// Return `true` if this unit is a part of a bundle that is being linked.
  bool get isLinking => bundleContext.isLinking;

  TypeProvider get typeProvider {
    var libraryReference = libraryContext.reference;
    var libraryElement = libraryReference.element as LibraryElementImpl;
    return libraryElement.typeProvider;
  }

  CompilationUnit get unit => _unit;

  CompilationUnit get unit_withDeclarations {
    _ensureUnitWithDeclarations();
    return _unit;
  }

  CompilationUnit get unit_withDirectives {
    _ensureUnitWithDeclarations();
    if (!_hasDirectivesRead) {
      var directiveDataList = data.node.compilationUnit_directives;
      for (var i = 0; i < directiveDataList.length; ++i) {
        var directiveData = directiveDataList[i];
        _unit.directives[i] = _astReader.readNode(directiveData);
      }
      _hasDirectivesRead = true;
    }
    return _unit;
  }

  Comment createComment(LinkedNode data) {
    var informativeData = getInformativeData(data);
    var tokenStringList = informativeData?.documentationComment_tokens;
    if (tokenStringList == null || tokenStringList.isEmpty) {
      return null;
    }

    var tokens = tokenStringList
        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
        .toList();
    return astFactory.documentationComment(tokens);
  }

  void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
    var containerRef = this.reference.getChild('@genericFunctionType');
    var reference = containerRef.getChild('$id');
    var element = GenericFunctionTypeElementImpl.forLinkedNode(
      this.reference.element,
      reference,
      node,
    );
    node.declaredElement = element;
  }

  /// Return the [LibraryElement] referenced in the [node].
  LibraryElement directiveLibrary(UriBasedDirective node) {
    var uriStr = LazyDirective.getSelectedUri(node);
    if (uriStr == null) return null;
    return bundleContext.elementFactory.libraryOfUri(uriStr);
  }

  int getCodeLength(AstNode node) {
    if (node is ClassDeclaration) {
      return LazyClassDeclaration.getCodeLength(this, node);
    } else if (node is ClassTypeAlias) {
      return LazyClassTypeAlias.getCodeLength(this, node);
    } else if (node is CompilationUnit) {
      if (data != null) {
        return getInformativeData(data.node)?.codeLength ?? 0;
      } else {
        return node.length;
      }
    } else if (node is ConstructorDeclaration) {
      return LazyConstructorDeclaration.getCodeLength(this, node);
    } else if (node is EnumConstantDeclaration) {
      return LazyEnumConstantDeclaration.getCodeLength(this, node);
    } else if (node is EnumDeclaration) {
      return LazyEnumDeclaration.getCodeLength(this, node);
    } else if (node is ExtensionDeclaration) {
      return LazyExtensionDeclaration.getCodeLength(this, node);
    } else if (node is FormalParameter) {
      return LazyFormalParameter.getCodeLength(this, node);
    } else if (node is FunctionDeclaration) {
      return LazyFunctionDeclaration.getCodeLength(this, node);
    } else if (node is FunctionTypeAliasImpl) {
      return LazyFunctionTypeAlias.getCodeLength(this, node);
    } else if (node is GenericTypeAlias) {
      return LazyGenericTypeAlias.getCodeLength(this, node);
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.getCodeLength(this, node);
    } else if (node is MixinDeclaration) {
      return LazyMixinDeclaration.getCodeLength(this, node);
    } else if (node is TypeParameter) {
      return LazyTypeParameter.getCodeLength(this, node);
    } else if (node is VariableDeclaration) {
      return LazyVariableDeclaration.getCodeLength(this, node);
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  int getCodeOffset(AstNode node) {
    if (node is ClassDeclaration) {
      return LazyClassDeclaration.getCodeOffset(this, node);
    } else if (node is ClassTypeAlias) {
      return LazyClassTypeAlias.getCodeOffset(this, node);
    } else if (node is CompilationUnit) {
      return 0;
    } else if (node is ConstructorDeclaration) {
      return LazyConstructorDeclaration.getCodeOffset(this, node);
    } else if (node is EnumConstantDeclaration) {
      return LazyEnumConstantDeclaration.getCodeOffset(this, node);
    } else if (node is EnumDeclaration) {
      return LazyEnumDeclaration.getCodeOffset(this, node);
    } else if (node is ExtensionDeclaration) {
      return LazyExtensionDeclaration.getCodeOffset(this, node);
    } else if (node is FormalParameter) {
      return LazyFormalParameter.getCodeOffset(this, node);
    } else if (node is FunctionDeclaration) {
      return LazyFunctionDeclaration.getCodeOffset(this, node);
    } else if (node is FunctionTypeAliasImpl) {
      return LazyFunctionTypeAlias.getCodeOffset(this, node);
    } else if (node is GenericTypeAlias) {
      return LazyGenericTypeAlias.getCodeOffset(this, node);
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.getCodeOffset(this, node);
    } else if (node is MixinDeclaration) {
      return LazyMixinDeclaration.getCodeOffset(this, node);
    } else if (node is TypeParameter) {
      return LazyTypeParameter.getCodeOffset(this, node);
    } else if (node is VariableDeclaration) {
      return LazyVariableDeclaration.getCodeOffset(this, node);
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  int getCombinatorEnd(ShowCombinator node) {
    return LazyCombinator.getEnd(this, node);
  }

  List<ConstructorInitializer> getConstructorInitializers(
    ConstructorDeclaration node,
  ) {
    LazyConstructorDeclaration.readInitializers(_astReader, node);
    return node.initializers;
  }

  ConstructorName getConstructorRedirected(ConstructorDeclaration node) {
    LazyConstructorDeclaration.readRedirectedConstructor(_astReader, node);
    return node.redirectedConstructor;
  }

  Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
    if (node is ClassOrMixinDeclaration) {
      var members = _getClassOrExtensionOrMixinMembers(node);
      for (var member in members) {
        if (member is ConstructorDeclaration) {
          yield member;
        }
      }
    }
  }

  DartType getDefaultType(TypeParameter node) {
    var type = LazyTypeParameter.getDefaultType(_astReader, node);
    if (type is TypeBuilder) {
      type = (type as TypeBuilder).build();
      LazyAst.setDefaultType(node, type);
    }
    return type;
  }

  String getDefaultValueCode(AstNode node) {
    if (node is DefaultFormalParameter) {
      return LazyFormalParameter.getDefaultValueCode(this, node);
    }
    return null;
  }

  String getDefaultValueCodeData(LinkedNode data) {
    var informativeData = getInformativeData(data);
    return informativeData?.defaultFormalParameter_defaultValueCode;
  }

  int getDirectiveOffset(Directive node) {
    return node.keyword.offset;
  }

  Comment getDocumentationComment(AstNode node) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is ClassTypeAlias) {
      LazyClassTypeAlias.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is ConstructorDeclaration) {
      LazyConstructorDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is EnumConstantDeclaration) {
      LazyEnumConstantDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is EnumDeclaration) {
      LazyEnumDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is ExtensionDeclaration) {
      LazyExtensionDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is FunctionTypeAlias) {
      LazyFunctionTypeAlias.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is GenericTypeAlias) {
      LazyGenericTypeAlias.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is MethodDeclaration) {
      LazyMethodDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is MixinDeclaration) {
      LazyMixinDeclaration.readDocumentationComment(this, node);
      return node.documentationComment;
    } else if (node is VariableDeclaration) {
      var parent2 = node.parent.parent;
      if (parent2 is FieldDeclaration) {
        LazyFieldDeclaration.readDocumentationComment(this, parent2);
        return parent2.documentationComment;
      } else if (parent2 is TopLevelVariableDeclaration) {
        LazyTopLevelVariableDeclaration.readDocumentationComment(
          this,
          parent2,
        );
        return parent2.documentationComment;
      } else {
        throw UnimplementedError('${parent2.runtimeType}');
      }
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
    LazyEnumDeclaration.readConstants(_astReader, node);
    return node.constants;
  }

  TypeAnnotation getExtendedType(ExtensionDeclaration node) {
    LazyExtensionDeclaration.readExtendedType(_astReader, node);
    return node.extendedType;
  }

  String getExtensionRefName(ExtensionDeclaration node) {
    return LazyExtensionDeclaration.get(node).refName;
  }

  String getFieldFormalParameterName(AstNode node) {
    if (node is DefaultFormalParameter) {
      return getFieldFormalParameterName(node.parameter);
    } else if (node is FieldFormalParameter) {
      return node.identifier.name;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  Iterable<VariableDeclaration> getFields(CompilationUnitMember node) sync* {
    var members = _getClassOrExtensionOrMixinMembers(node);
    for (var member in members) {
      if (member is FieldDeclaration) {
        for (var field in member.fields.variables) {
          yield field;
        }
      }
    }
  }

  List<FormalParameter> getFormalParameters(AstNode node) {
    if (node is ConstructorDeclaration) {
      LazyConstructorDeclaration.readFormalParameters(_astReader, node);
      return node.parameters.parameters;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
      return getFormalParameters(node.functionExpression);
    } else if (node is FunctionExpression) {
      LazyFunctionExpression.readFormalParameters(_astReader, node);
      return node.parameters?.parameters;
    } else if (node is FormalParameter) {
      if (node is DefaultFormalParameter) {
        return getFormalParameters(node.parameter);
      } else if (node is FieldFormalParameter) {
        LazyFormalParameter.readFormalParameters(_astReader, node);
        return node.parameters?.parameters;
      } else if (node is FunctionTypedFormalParameter) {
        LazyFormalParameter.readFormalParameters(_astReader, node);
        return node.parameters.parameters;
      } else {
        return null;
      }
    } else if (node is FunctionTypeAlias) {
      LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
      return node.parameters.parameters;
    } else if (node is GenericFunctionType) {
      return node.parameters.parameters;
    } else if (node is MethodDeclaration) {
      LazyMethodDeclaration.readFormalParameters(_astReader, node);
      return node.parameters?.parameters;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  Reference getGenericFunctionTypeReference(GenericFunctionType node) {
    var containerRef = reference.getChild('@genericFunctionType');
    var id = LazyAst.getGenericFunctionTypeId(node);
    return containerRef.getChild('$id');
  }

  GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
    LazyGenericTypeAlias.readFunctionType(_astReader, node);
    return node.functionType;
  }

  bool getHasTypedefSelfReference(AstNode node) {
    if (node is FunctionTypeAlias) {
      return LazyFunctionTypeAlias.getHasSelfReference(node);
    } else if (node is GenericTypeAlias) {
      return LazyGenericTypeAlias.getHasSelfReference(node);
    }
    return false;
  }

  ImplementsClause getImplementsClause(AstNode node) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readImplementsClause(_astReader, node);
      return node.implementsClause;
    } else if (node is ClassTypeAlias) {
      LazyClassTypeAlias.readImplementsClause(_astReader, node);
      return node.implementsClause;
    } else if (node is MixinDeclaration) {
      LazyMixinDeclaration.readImplementsClause(_astReader, node);
      return node.implementsClause;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  UnlinkedInformativeData getInformativeData(LinkedNode data) {
    if (informativeData == null) return null;

    var id = data.informativeId;
    if (id == 0) return null;

    return informativeData[id - 1];
  }

  bool getInheritsCovariant(AstNode node) {
    if (node is DefaultFormalParameter) {
      return getInheritsCovariant(node.parameter);
    } else if (node is FormalParameter) {
      return LazyAst.getInheritsCovariant(node);
    } else if (node is VariableDeclaration) {
      return LazyAst.getInheritsCovariant(node);
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
    return LazyCompilationUnit.getLanguageVersion(node);
  }

  Comment getLibraryDocumentationComment(CompilationUnit unit) {
    for (var directive in unit.directives) {
      if (directive is LibraryDirective) {
        return directive.documentationComment;
      }
    }
    return null;
  }

  List<Annotation> getLibraryMetadata(CompilationUnit unit) {
    for (var directive in unit.directives) {
      if (directive is LibraryDirective) {
        return getMetadata(directive);
      }
    }
    return const <Annotation>[];
  }

  List<Annotation> getMetadata(AstNode node) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is ClassTypeAlias) {
      LazyClassTypeAlias.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is CompilationUnit) {
      assert(node == _unit);
      if (indexInLibrary != 0) {
        return _getPartDirectiveAnnotation();
      } else {
        return const <Annotation>[];
      }
    } else if (node is ConstructorDeclaration) {
      LazyConstructorDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is DefaultFormalParameter) {
      return getMetadata(node.parameter);
    } else if (node is Directive) {
      LazyDirective.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is EnumConstantDeclaration) {
      LazyEnumConstantDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is EnumDeclaration) {
      LazyEnumDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is ExtensionDeclaration) {
      LazyExtensionDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is FormalParameter) {
      LazyFormalParameter.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is FunctionTypeAlias) {
      LazyFunctionTypeAlias.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is GenericTypeAlias) {
      LazyGenericTypeAlias.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is MethodDeclaration) {
      LazyMethodDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is MixinDeclaration) {
      LazyMixinDeclaration.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is TypeParameter) {
      LazyTypeParameter.readMetadata(_astReader, node);
      return node.metadata;
    } else if (node is VariableDeclaration) {
      var parent2 = node.parent.parent;
      if (parent2 is FieldDeclaration) {
        LazyFieldDeclaration.readMetadata(_astReader, parent2);
        return parent2.metadata;
      } else if (parent2 is TopLevelVariableDeclaration) {
        LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2);
        return parent2.metadata;
      }
    }
    return const <Annotation>[];
  }

  Iterable<MethodDeclaration> getMethods(CompilationUnitMember node) sync* {
    var members = _getClassOrExtensionOrMixinMembers(node);
    for (var member in members) {
      if (member is MethodDeclaration) {
        yield member;
      }
    }
  }

  List<String> getMixinSuperInvokedNames(MixinDeclaration node) {
    return LazyMixinDeclaration.get(node).getSuperInvokedNames();
  }

  int getNameOffset(AstNode node) {
    if (node is ConstructorDeclaration) {
      if (node.name != null) {
        return node.name.offset;
      } else {
        return node.returnType.offset;
      }
    } else if (node is EnumConstantDeclaration) {
      return node.name.offset;
    } else if (node is ExtensionDeclaration) {
      return node.name?.offset ?? -1;
    } else if (node is FormalParameter) {
      return node.identifier?.offset ?? -1;
    } else if (node is MethodDeclaration) {
      return node.name.offset;
    } else if (node is NamedCompilationUnitMember) {
      return node.name.offset;
    } else if (node is TypeParameter) {
      return node.name.offset;
    } else if (node is VariableDeclaration) {
      return node.name.offset;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  OnClause getOnClause(MixinDeclaration node) {
    LazyMixinDeclaration.readOnClause(_astReader, node);
    return node.onClause;
  }

  /// Return the actual return type for the [node] - explicit or inferred.
  DartType getReturnType(AstNode node) {
    if (node is FunctionDeclaration) {
      return LazyFunctionDeclaration.getReturnType(_astReader, node);
    } else if (node is FunctionTypeAlias) {
      return LazyFunctionTypeAlias.getReturnType(_astReader, node);
    } else if (node is GenericFunctionType) {
      return node.returnType?.type ?? DynamicTypeImpl.instance;
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.getReturnType(_astReader, node);
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  TypeAnnotation getReturnTypeNode(AstNode node) {
    if (node is FunctionTypeAlias) {
      LazyFunctionTypeAlias.readReturnTypeNode(_astReader, node);
      return node.returnType;
    } else if (node is GenericFunctionType) {
      return node.returnType;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
      return node.returnType;
    } else if (node is MethodDeclaration) {
      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
      return node.returnType;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  String getSelectedUri(UriBasedDirective node) {
    return LazyDirective.getSelectedUri(node);
  }

  TypeName getSuperclass(AstNode node) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readExtendsClause(_astReader, node);
      return node.extendsClause?.superclass;
    } else if (node is ClassTypeAlias) {
      LazyClassTypeAlias.readSuperclass(_astReader, node);
      return node.superclass;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  /// Return the actual type for the [node] - explicit or inferred.
  DartType getType(AstNode node) {
    if (node is DefaultFormalParameter) {
      return getType(node.parameter);
    } else if (node is FormalParameter) {
      return LazyFormalParameter.getType(_astReader, node);
    } else if (node is VariableDeclaration) {
      return LazyVariableDeclaration.getType(_astReader, node);
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  TopLevelInferenceError getTypeInferenceError(AstNode node) {
    if (node is DefaultFormalParameter) {
      return getTypeInferenceError(node.parameter);
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.getTypeInferenceError(node);
    } else if (node is SimpleFormalParameter) {
      return LazyFormalParameter.getTypeInferenceError(node);
    } else if (node is VariableDeclaration) {
      return LazyVariableDeclaration.getTypeInferenceError(node);
    } else {
      return null;
    }
  }

  TypeAnnotation getTypeParameterBound(TypeParameter node) {
    LazyTypeParameter.readBound(_astReader, node);
    return node.bound;
  }

  TypeParameterList getTypeParameters2(AstNode node) {
    if (node is ClassDeclaration) {
      return node.typeParameters;
    } else if (node is ClassTypeAlias) {
      return node.typeParameters;
    } else if (node is ConstructorDeclaration) {
      return null;
    } else if (node is DefaultFormalParameter) {
      return getTypeParameters2(node.parameter);
    } else if (node is ExtensionDeclaration) {
      return node.typeParameters;
    } else if (node is FieldFormalParameter) {
      return node.typeParameters;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
      return getTypeParameters2(node.functionExpression);
    } else if (node is FunctionExpression) {
      return node.typeParameters;
    } else if (node is FunctionTypedFormalParameter) {
      return node.typeParameters;
    } else if (node is FunctionTypeAlias) {
      return node.typeParameters;
    } else if (node is GenericFunctionType) {
      return node.typeParameters;
    } else if (node is GenericTypeAlias) {
      return node.typeParameters;
    } else if (node is MethodDeclaration) {
      return node.typeParameters;
    } else if (node is MixinDeclaration) {
      return node.typeParameters;
    } else if (node is SimpleFormalParameter) {
      return null;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  Token getTypeParameterVariance(TypeParameter node) {
    // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is
    // added to the interface.
    return (node as TypeParameterImpl).varianceKeyword;
  }

  WithClause getWithClause(AstNode node) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readWithClause(_astReader, node);
      return node.withClause;
    } else if (node is ClassTypeAlias) {
      LazyClassTypeAlias.readWithClause(_astReader, node);
      return node.withClause;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  bool hasDefaultValue(FormalParameter node) {
    if (node is DefaultFormalParameter) {
      return LazyFormalParameter.hasDefaultValue(node);
    }
    return false;
  }

  bool hasImplicitReturnType(AstNode node) {
    if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
      return node.returnType == null;
    }
    if (node is MethodDeclaration) {
      LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
      return node.returnType == null;
    }
    return false;
  }

  bool hasImplicitType(AstNode node) {
    if (node is DefaultFormalParameter) {
      return hasImplicitType(node.parameter);
    } else if (node is SimpleFormalParameter) {
      return node.type == null;
    } else if (node is VariableDeclaration) {
      VariableDeclarationList parent = node.parent;
      LazyVariableDeclarationList.readTypeNode(_astReader, parent);
      return parent.type == null;
    }
    return false;
  }

  bool hasInitializer(VariableDeclaration node) {
    return LazyVariableDeclaration.hasInitializer(node);
  }

  bool hasOperatorEqualParameterTypeFromObject(MethodDeclaration node) {
    return LazyAst.hasOperatorEqualParameterTypeFromObject(node);
  }

  bool hasOverrideInferenceDone(AstNode node) {
    // Only nodes in the libraries being linked might be not inferred yet.
    if (_astReader.isLazy) return true;

    return LazyAst.hasOverrideInferenceDone(node);
  }

  bool isAbstract(AstNode node) {
    if (node is ClassDeclaration) {
      return node.abstractKeyword != null;
    } else if (node is ClassTypeAlias) {
      return node.abstractKeyword != null;
    } else if (node is ConstructorDeclaration) {
      return false;
    } else if (node is FunctionDeclaration) {
      return false;
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.isAbstract(node);
    } else if (node is VariableDeclaration) {
      var parent = node.parent;
      if (parent is VariableDeclarationList) {
        var grandParent = parent.parent;
        if (grandParent is FieldDeclaration) {
          return grandParent.abstractKeyword != null;
        } else {
          throw UnimplementedError('${grandParent.runtimeType}');
        }
      } else {
        throw UnimplementedError('${parent.runtimeType}');
      }
    } else if (node is EnumConstantDeclaration) {
      return false;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  bool isAsynchronous(AstNode node) {
    if (node is ConstructorDeclaration) {
      return false;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
      return isAsynchronous(node.functionExpression);
    } else if (node is FunctionExpression) {
      return LazyFunctionExpression.isAsynchronous(node);
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.isAsynchronous(node);
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  bool isConst(AstNode node) {
    if (node is FormalParameter) {
      return node.isConst;
    }
    if (node is VariableDeclaration) {
      VariableDeclarationList parent = node.parent;
      return parent.isConst;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  bool isExplicitlyCovariant(AstNode node) {
    if (node is DefaultFormalParameter) {
      return isExplicitlyCovariant(node.parameter);
    } else if (node is EnumConstantDeclaration) {
      return false;
    } else if (node is FormalParameter) {
      return node.covariantKeyword != null;
    } else if (node is VariableDeclaration) {
      var parent2 = node.parent.parent;
      return parent2 is FieldDeclaration && parent2.covariantKeyword != null;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  bool isExternal(AstNode node) {
    if (node is ConstructorDeclaration) {
      return node.externalKeyword != null;
    } else if (node is FunctionDeclaration) {
      return node.externalKeyword != null;
    } else if (node is MethodDeclaration) {
      return node.externalKeyword != null || node.body is NativeFunctionBody;
    } else if (node is VariableDeclaration) {
      var parent = node.parent;
      if (parent is VariableDeclarationList) {
        var grandParent = parent.parent;
        if (grandParent is FieldDeclaration) {
          return grandParent.externalKeyword != null;
        } else if (grandParent is TopLevelVariableDeclaration) {
          return grandParent.externalKeyword != null;
        } else {
          throw UnimplementedError('${grandParent.runtimeType}');
        }
      } else {
        throw UnimplementedError('${parent.runtimeType}');
      }
    } else if (node is EnumConstantDeclaration) {
      return false;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  bool isFinal(AstNode node) {
    if (node is EnumConstantDeclaration) {
      return false;
    }
    if (node is VariableDeclaration) {
      VariableDeclarationList parent = node.parent;
      return parent.isFinal;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  bool isGenerator(AstNode node) {
    if (node is ConstructorDeclaration) {
      return false;
    } else if (node is FunctionDeclaration) {
      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
      return isGenerator(node.functionExpression);
    } else if (node is FunctionExpression) {
      return LazyFunctionExpression.isGenerator(node);
    } else if (node is MethodDeclaration) {
      return LazyMethodDeclaration.isGenerator(node);
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  bool isGetter(AstNode node) {
    if (node is FunctionDeclaration) {
      return node.isGetter;
    } else if (node is MethodDeclaration) {
      return node.isGetter;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  bool isLate(AstNode node) {
    if (node is VariableDeclaration) {
      return node.isLate;
    }
    if (node is EnumConstantDeclaration) {
      return false;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  bool isNative(AstNode node) {
    if (node is MethodDeclaration) {
      return node.body is NativeFunctionBody;
    } else {
      throw UnimplementedError('${node.runtimeType}');
    }
  }

  bool isSetter(AstNode node) {
    if (node is FunctionDeclaration) {
      return node.isSetter;
    } else if (node is MethodDeclaration) {
      return node.isSetter;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  bool isSimplyBounded(AstNode node) {
    return LazyAst.isSimplyBounded(node);
  }

  bool isStatic(AstNode node) {
    if (node is FunctionDeclaration) {
      return true;
    } else if (node is MethodDeclaration) {
      return node.modifierKeyword != null;
    } else if (node is VariableDeclaration) {
      var parent2 = node.parent.parent;
      return parent2 is FieldDeclaration && parent2.isStatic;
    }
    throw UnimplementedError('${node.runtimeType}');
  }

  Expression readInitializer(AstNode node) {
    if (node is DefaultFormalParameter) {
      LazyFormalParameter.readDefaultValue(_astReader, node);
      return node.defaultValue;
    } else if (node is VariableDeclaration) {
      LazyVariableDeclaration.readInitializer(_astReader, node);
      return node.initializer;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  DartType readType(LinkedNodeType linkedType) {
    if (linkedType == null) return null;

    var kind = linkedType.kind;
    if (kind == LinkedNodeTypeKind.dynamic_) {
      return DynamicTypeImpl.instance;
    } else if (kind == LinkedNodeTypeKind.function) {
      var typeParameterDataList = linkedType.functionTypeParameters;

      var typeParametersLength = typeParameterDataList.length;
      var typeParameters = List<TypeParameterElement>(typeParametersLength);
      for (var i = 0; i < typeParametersLength; ++i) {
        var typeParameterData = typeParameterDataList[i];
        var element = TypeParameterElementImpl(typeParameterData.name, -1);
        typeParameters[i] = element;
        _typeParameters[_nextSyntheticTypeParameterId++] = element;
      }

      // Type parameters might use each other in bounds, including forward
      // references. So, we read bounds after reading all type parameters.
      for (var i = 0; i < typeParametersLength; ++i) {
        var typeParameterData = typeParameterDataList[i];
        TypeParameterElementImpl element = typeParameters[i];
        element.bound = readType(typeParameterData.bound);
      }

      var returnType = readType(linkedType.functionReturnType);
      var formalParameters = linkedType.functionFormalParameters.map((p) {
        var type = readType(p.type);
        var kind = _formalParameterKind(p.kind);
        return ParameterElementImpl.synthetic(p.name, type, kind);
      }).toList();

      for (var i = 0; i < typeParametersLength; ++i) {
        _typeParameters.remove(--_nextSyntheticTypeParameterId);
      }

      GenericTypeAliasElement typedefElement;
      List<DartType> typedefTypeArguments = const <DartType>[];
      if (linkedType.functionTypedef != 0) {
        typedefElement =
            bundleContext.elementOfIndex(linkedType.functionTypedef);
        typedefTypeArguments =
            linkedType.functionTypedefTypeArguments.map(readType).toList();
      }

      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);

      return FunctionTypeImpl(
        typeFormals: typeParameters,
        parameters: formalParameters,
        returnType: returnType,
        nullabilitySuffix: nullabilitySuffix,
        element: typedefElement,
        typeArguments: typedefTypeArguments,
      );
    } else if (kind == LinkedNodeTypeKind.interface) {
      var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
      return InterfaceTypeImpl(
        element: element,
        typeArguments: linkedType.interfaceTypeArguments.map(readType).toList(),
        nullabilitySuffix: nullabilitySuffix,
      );
    } else if (kind == LinkedNodeTypeKind.never) {
      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
      return NeverTypeImpl.instance.withNullability(nullabilitySuffix);
    } else if (kind == LinkedNodeTypeKind.typeParameter) {
      TypeParameterElement element;
      var id = linkedType.typeParameterId;
      if (id != 0) {
        element = _typeParameters[id];
        assert(element != null);
      } else {
        var index = linkedType.typeParameterElement;
        element = bundleContext.elementOfIndex(index);
      }
      var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
      return TypeParameterTypeImpl(
        element: element,
        nullabilitySuffix: nullabilitySuffix,
      );
    } else if (kind == LinkedNodeTypeKind.void_) {
      return VoidTypeImpl.instance;
    } else {
      throw UnimplementedError('$kind');
    }
  }

  void setInheritsCovariant(AstNode node, bool value) {
    if (node is DefaultFormalParameter) {
      setInheritsCovariant(node.parameter, value);
    } else if (node is FormalParameter) {
      LazyAst.setInheritsCovariant(node, value);
    } else if (node is VariableDeclaration) {
      LazyAst.setInheritsCovariant(node, value);
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  void setOperatorEqualParameterTypeFromObject(AstNode node, bool value) {
    LazyAst.setOperatorEqualParameterTypeFromObject(node, value);
  }

  void setOverrideInferenceDone(AstNode node) {
    // TODO(scheglov) This assert fails, check how to avoid this.
//    assert(!_astReader.isLazy);
    LazyAst.setOverrideInferenceDone(node);
  }

  void setReturnType(AstNode node, DartType type) {
    LazyAst.setReturnType(node, type);
  }

  void setVariableType(AstNode node, DartType type) {
    if (node is DefaultFormalParameter) {
      setVariableType(node.parameter, type);
    } else {
      LazyAst.setType(node, type);
    }
  }

  bool shouldBeConstFieldElement(AstNode node) {
    if (node is VariableDeclaration) {
      VariableDeclarationList variableList = node.parent;
      if (variableList.isConst) return true;

      FieldDeclaration fieldDeclaration = variableList.parent;
      if (fieldDeclaration.staticKeyword != null) return false;

      if (variableList.isFinal) {
        var class_ = fieldDeclaration.parent;
        if (class_ is ClassOrMixinDeclaration) {
          for (var member in class_.members) {
            if (member is ConstructorDeclaration &&
                member.constKeyword != null) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
    for (var declaration in unit.declarations) {
      if (declaration is TopLevelVariableDeclaration) {
        for (var variable in declaration.variables.variables) {
          yield variable;
        }
      }
    }
  }

  void _ensureUnitWithDeclarations() {
    if (_unit == null) {
      _unit = _astReader.readNode(data.node);

      var informativeData = getInformativeData(data.node);
      var lineStarts = informativeData?.compilationUnit_lineStarts ?? [];
      if (lineStarts.isEmpty) {
        lineStarts = [0];
      }
      _unit.lineInfo = LineInfo(lineStarts);
    }
  }

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

  List<ClassMember> _getClassOrExtensionOrMixinMembers(
    CompilationUnitMember node,
  ) {
    if (node is ClassDeclaration) {
      LazyClassDeclaration.readMembers(_astReader, node);
      return node.members;
    } else if (node is ClassTypeAlias) {
      return <ClassMember>[];
    } else if (node is ExtensionDeclaration) {
      LazyExtensionDeclaration.readMembers(_astReader, node);
      return node.members;
    } else if (node is MixinDeclaration) {
      LazyMixinDeclaration.readMembers(_astReader, node);
      return node.members;
    } else {
      throw StateError('${node.runtimeType}');
    }
  }

  NodeList<Annotation> _getPartDirectiveAnnotation() {
    var definingContext = libraryContext.definingUnit;
    var unit = definingContext.unit;
    var partDirectiveIndex = 0;
    for (var directive in unit.directives) {
      if (directive is PartDirective) {
        partDirectiveIndex++;
        if (partDirectiveIndex == indexInLibrary) {
          LazyDirective.readMetadata(definingContext._astReader, directive);
          return directive.metadata;
        }
      }
    }
    throw StateError('Expected to find $indexInLibrary part directive.');
  }

  static NullabilitySuffix _nullabilitySuffix(EntityRefNullabilitySuffix data) {
    switch (data) {
      case EntityRefNullabilitySuffix.starOrIrrelevant:
        return NullabilitySuffix.star;
      case EntityRefNullabilitySuffix.question:
        return NullabilitySuffix.question;
      case EntityRefNullabilitySuffix.none:
        return NullabilitySuffix.none;
      default:
        throw StateError('$data');
    }
  }
}
