// Copyright (c) 2017, 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 'dart:io';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/task/inference_error.dart';
import 'package:test/test.dart';

import 'resolved_ast_printer.dart';

/// Set this path to automatically replace expectations in invocations of
/// [checkElementText] with the new actual texts.
const String? _testPath = null;

/// The list of replacements that update expectations.
final List<_Replacement> _replacements = [];

/// The cached content of the file with the [_testPath].
String? _testCode;

/// The cache line information for the [_testPath] file.
LineInfo? _testCodeLines;

void applyCheckElementTextReplacements() {
  if (_testPath != null && _replacements.isNotEmpty) {
    _replacements.sort((a, b) => b.offset - a.offset);
    String newCode = _testCode!;
    _replacements.forEach((r) {
      newCode =
          newCode.substring(0, r.offset) + r.text + newCode.substring(r.end);
    });
    File(_testPath!).writeAsStringSync(newCode);
  }
}

/// Write the given [library] elements into the canonical text presentation
/// taking into account the specified 'withX' options. Then compare the
/// actual text with the given [expected] one.
void checkElementText(
  LibraryElement library,
  String expected, {
  bool withAliasElementArguments = false,
  bool withCodeRanges = false,
  bool withConstElements = true,
  bool withExportScope = false,
  bool withFullyResolvedAst = false,
  bool withOffsets = false,
  bool withSyntheticAccessors = false,
  bool withSyntheticFields = false,
  bool withTypes = false,
  bool withTypeParameterVariance = false,
}) {
  var writer = _ElementWriter(
    selfUriStr: '${library.source.uri}',
    withAliasElementArguments: withAliasElementArguments,
    withCodeRanges: withCodeRanges,
    withConstElements: withConstElements,
    withExportScope: withExportScope,
    withFullyResolvedAst: withFullyResolvedAst,
    withOffsets: withOffsets,
    withSyntheticAccessors: withSyntheticAccessors,
    withSyntheticFields: withSyntheticFields,
    withTypes: withTypes,
    withTypeParameterVariance: withTypeParameterVariance,
  );
  writer.writeLibraryElement(library);

  String actualText = writer.buffer.toString();
  actualText =
      actualText.split('\n').map((line) => line.trimRight()).join('\n');

  if (_testPath != null && actualText != expected) {
    if (_testCode == null) {
      _testCode = File(_testPath!).readAsStringSync();
      _testCodeLines = LineInfo.fromContent(_testCode!);
    }

    try {
      throw 42;
    } catch (e, trace) {
      String traceString = trace.toString();

      // Assuming traceString contains "$_testPath:$invocationLine:$column",
      // figure out the value of invocationLine.

      int testFilePathOffset = traceString.indexOf(_testPath!);
      expect(testFilePathOffset, isNonNegative);

      // Sanity check: there must be ':' after the path.
      expect(traceString[testFilePathOffset + _testPath!.length], ':');

      int lineOffset = testFilePathOffset + _testPath!.length + ':'.length;
      int invocationLine = int.parse(traceString.substring(
          lineOffset, traceString.indexOf(':', lineOffset)));
      int invocationOffset =
          _testCodeLines!.getOffsetOfLine(invocationLine - 1);

      const String rawStringPrefix = "r'''";
      int expectationOffset =
          _testCode!.indexOf(rawStringPrefix, invocationOffset);

      // Sanity check: there must be no other strings or blocks.
      expect(_testCode!.substring(invocationOffset, expectationOffset),
          isNot(anyOf(contains("'"), contains('"'), contains('}'))));

      expectationOffset += rawStringPrefix.length;
      int expectationEnd = _testCode!.indexOf("'''", expectationOffset);

      _replacements.add(
          _Replacement(expectationOffset, expectationEnd, '\n' + actualText));
    }
  }

  // Print the actual text to simplify copy/paste into the expectation.
  // if (actualText != expected) {
  //   print('-------- Actual --------');
  //   print(actualText + '------------------------');
  // }

  expect(actualText, expected);
}

/// Writes the canonical text presentation of elements.
class _ElementWriter {
  final String? selfUriStr;
  final bool withAliasElementArguments;
  final bool withCodeRanges;
  final bool withExportScope;
  final bool withFullyResolvedAst;
  final bool withOffsets;
  final bool withConstElements;
  final bool withSyntheticAccessors;
  final bool withSyntheticFields;
  final bool withTypes;
  final bool withTypeParameterVariance;
  final StringBuffer buffer = StringBuffer();

  String indent = '';

  _ElementWriter({
    this.selfUriStr,
    this.withAliasElementArguments = false,
    this.withCodeRanges = false,
    this.withConstElements = true,
    this.withExportScope = false,
    this.withFullyResolvedAst = false,
    this.withOffsets = false,
    this.withSyntheticAccessors = false,
    this.withSyntheticFields = false,
    this.withTypes = false,
    this.withTypeParameterVariance = false,
  });

  bool isDynamicType(DartType type) => type is DynamicTypeImpl;

  bool isEnumField(Element e) {
    var enclosing = e.enclosingElement;
    return enclosing is ClassElement && enclosing.isEnum;
  }

  void newLineIfNotEmpty() {
    if (buffer.isNotEmpty) {
      buffer.writeln();
    }
  }

  void writeBodyModifiers(ExecutableElement e) {
    if (e.isAsynchronous) {
      expect(e.isSynchronous, isFalse);
      buffer.write(' async');
    }

    if (e.isSynchronous && e.isGenerator) {
      expect(e.isAsynchronous, isFalse);
      buffer.write(' sync');
    }

    writeIf(e.isGenerator, '*');
  }

  void writeClassElement(ClassElement e) {
    writeDocumentation(e);
    writeMetadata(e, '', '\n');

    writeIf(e.isAbstract && !e.isMixin, 'abstract ');
    writeIf(!e.isSimplyBounded, 'notSimplyBounded ');

    if (e.isEnum) {
      buffer.write('enum ');
    } else if (e.isMixin) {
      buffer.write('mixin ');
    } else {
      buffer.write('class ');
    }

    writeIf(e.isMixinApplication, 'alias ');

    writeName(e);
    writeCodeRange(e);
    writeTypeParameterElements(e.typeParameters, withDefault: true);

    if (e.supertype != null && e.supertype!.element.name != 'Object' ||
        e.mixins.isNotEmpty) {
      buffer.write(' extends ');
      writeType(e.supertype!);
    }

    if (e.isMixin) {
      if (e.superclassConstraints.isEmpty) {
        throw StateError('At least Object is expected.');
      }
      writeList(' on ', '', e.superclassConstraints, ', ', writeType);
    }

    writeList(' with ', '', e.mixins, ', ', writeType);
    writeList(' implements ', '', e.interfaces, ', ', writeType);

    buffer.writeln(' {');

    _withIndent(() {
      e.fields.forEach(writePropertyInducingElement);
      e.accessors.forEach(writePropertyAccessorElement);

      if (e.isEnum) {
        expect(e.constructors, isEmpty);
      } else {
        expect(e.constructors, isNotEmpty);
      }

      if (e.constructors.length == 1 &&
          e.constructors[0].isSynthetic &&
          e.mixins.isEmpty) {
        expect(e.constructors[0].parameters, isEmpty);
      } else {
        e.constructors.forEach(writeConstructorElement);
      }

      e.methods.forEach(writeMethodElement);
    });

    buffer.writeln('}');

    if (withFullyResolvedAst) {
      _withIndent(() {
        _writeResolvedMetadata(e.metadata);
        _writeResolvedTypeParameters(e.typeParameters);
      });
    }
  }

  void writeCodeRange(Element e) {
    if (withCodeRanges) {
      var elementImpl = e as ElementImpl;
      buffer.write('/*codeOffset=');
      buffer.write(elementImpl.codeOffset);
      buffer.write(', codeLength=');
      buffer.write(elementImpl.codeLength);
      buffer.write('*/');
    }
  }

  void writeConstructorElement(ConstructorElement e) {
    writeDocumentation(e, '  ');
    writeMetadata(e, '  ', '\n');

    buffer.write('  ');

    writeIf(e.isSynthetic, 'synthetic ');
    writeIf(e.isExternal, 'external ');
    writeIf(e.isConst, 'const ');
    writeIf(e.isFactory, 'factory ');
    expect(e.isAbstract, isFalse);

    buffer.write(e.enclosingElement.name);
    if (e.name.isNotEmpty) {
      buffer.write('.');
      buffer.write(e.displayName);
    }
    if (!e.isSynthetic) {
      writeCodeRange(e);
      if (withOffsets) {
        var periodOffset = e.periodOffset;
        var nameEnd = e.nameEnd;
        if (periodOffset != null && nameEnd != null) {
          buffer.write('[periodOffset: $periodOffset]');
          buffer.write('[nameOffset: ${e.nameOffset}]');
          buffer.write('[nameEnd: $nameEnd]');
        } else {
          buffer.write('[nameOffset: ${e.nameOffset}]');
        }
      }
    }

    writeParameterElements(e.parameters);

    {
      var redirected = e.redirectedConstructor;
      if (redirected != null) {
        buffer.write(' = ');
        writeType(redirected.returnType);
        if (redirected.name.isNotEmpty) {
          buffer.write('.');
          buffer.write(redirected.name);
        }
      }
    }

    var initializers = (e as ConstructorElementImpl).constantInitializers;
    if (withFullyResolvedAst) {
      buffer.writeln(';');
      _withIndent(() {
        if (initializers.isNotEmpty) {
          _writelnWithIndent('constantInitializers');
          _withIndent(() {
            for (var initializer in initializers) {
              _writeResolvedNode(initializer);
            }
          });
        }
        _writeParameterElementDefaultValues(e.parameters);
      });
    } else {
      writeList(' : ', '', initializers, ', ', writeNode);
      buffer.writeln(';');
    }

    expect(e.isAsynchronous, isFalse);
    expect(e.isGenerator, isFalse);
  }

  void writeDocumentation(Element e, [String prefix = '']) {
    var comment = e.documentationComment;
    if (comment != null) {
      if (comment.startsWith('///')) {
        comment = comment.split('\n').join('\n$prefix');
      }
      buffer.write(prefix);
      buffer.writeln(comment);
    }
  }

  void writeExportElement(ExportElement e) {
    writeMetadata(e, '', '\n');
    buffer.write('export ');
    writeUri(e.exportedLibrary?.source);

    e.combinators.forEach(writeNamespaceCombinator);

    buffer.writeln(';');
  }

  void writeExportScope(LibraryElement e) {
    if (!withExportScope) return;

    buffer.writeln();
    buffer.writeln('-' * 20);
    buffer.writeln('Exports:');

    var map = e.exportNamespace.definedNames;
    var names = map.keys.toList()..sort();
    for (var name in names) {
      var element = map[name];
      var elementLocationStr = _getElementLocationString(element);
      buffer.writeln('  $name: $elementLocationStr');
    }
  }

  void writeExtensionElement(ExtensionElement e) {
    writeDocumentation(e);
    writeMetadata(e, '', '\n');

    buffer.write('extension ');
    writeName(e);
    writeCodeRange(e);
    writeTypeParameterElements(e.typeParameters, withDefault: false);
    buffer.write(' on ');
    writeType(e.extendedType);

    buffer.writeln(' {');

    _withIndent(() {
      e.fields.forEach(writePropertyInducingElement);
      e.accessors.forEach(writePropertyAccessorElement);
      e.methods.forEach(writeMethodElement);
    });

    buffer.writeln('}');

    if (withFullyResolvedAst) {
      _withIndent(() {
        _writeResolvedMetadata(e.metadata);
        _writeResolvedTypeParameters(e.typeParameters);
      });
    }
  }

  void writeFunctionElement(FunctionElement e) {
    writeDocumentation(e);
    writeMetadata(e, '', '\n');

    writeIf(e.isExternal, 'external ');

    writeType2(e.returnType);

    writeName(e);
    writeCodeRange(e);

    writeTypeParameterElements(e.typeParameters, withDefault: false);
    writeParameterElements(e.parameters);

    writeBodyModifiers(e);

    buffer.writeln(' {}');

    if (withFullyResolvedAst) {
      _withIndent(() {
        _writeParameterElementDefaultValues(e.parameters);
      });
    }
  }

  void writeIf(bool flag, String str) {
    if (flag) {
      buffer.write(str);
    }
  }

  void writeImportElement(ImportElement e) {
    if (!e.isSynthetic) {
      writeMetadata(e, '', '\n');
      buffer.write('import ');
      writeUri(e.importedLibrary?.source);

      writeIf(e.isDeferred, ' deferred');

      var prefix = e.prefix;
      if (prefix != null) {
        buffer.write(' as ');
        writeName(prefix);
        if (withOffsets) {
          buffer.write('(${prefix.nameOffset})');
        }
      }

      e.combinators.forEach(writeNamespaceCombinator);

      buffer.writeln(';');

      if (withFullyResolvedAst) {
        _withIndent(() {
          _writeResolvedMetadata(e.metadata);
        });
      }
    }
  }

  void writeInterfaceTypeArgsComment(Expression e) {
    var typeArguments = (e.staticType as InterfaceType).typeArguments;
    writeList('/*typeArgs=', '*/', typeArguments, ',', writeType);
  }

  void writeLibraryElement(LibraryElement e) {
    if (e.documentationComment != null) {
      buffer.writeln(e.documentationComment);
    }

    if (e.displayName != '') {
      writeMetadata(e, '', '\n');
      buffer.write('library ');
      writeName(e);
      buffer.writeln(';');
    }

    e.imports.forEach(writeImportElement);
    e.exports.forEach(writeExportElement);
    e.parts.forEach(writePartElement);

    e.units.forEach(writeUnitElement);

    writeExportScope(e);
  }

  void writeList<T>(String open, String close, List<T> items, String separator,
      Function(T item) writeItem,
      {bool includeEmpty = false}) {
    if (!includeEmpty && items.isEmpty) {
      return;
    }
    buffer.write(open);
    bool first = true;
    for (T item in items) {
      if (!first) {
        buffer.write(separator);
      }
      writeItem(item);
      first = false;
    }
    buffer.write(close);
  }

  void writeMetadata(Element e, String prefix, String separator) {
    if (withFullyResolvedAst) {
      return;
    }

    if (e.metadata.isNotEmpty) {
      writeList(prefix, '', e.metadata, '$separator$prefix', (a) {
        writeNode((a as ElementAnnotationImpl).annotationAst);
      });
      buffer.write(separator);
    }
  }

  void writeMethodElement(MethodElement e) {
    writeDocumentation(e, '  ');
    writeMetadata(e, '  ', '\n');

    buffer.write('  ');

    writeIf(e.isExternal, 'external ');
    writeIf(e.isStatic, 'static ');

    writeType2(e.returnType);

    writeName(e);
    writeCodeRange(e);
    writeTypeInferenceError(e);

    writeTypeParameterElements(e.typeParameters, withDefault: false);
    writeParameterElements(e.parameters);

    writeBodyModifiers(e);

    if (e.isAbstract) {
      buffer.writeln(';');
    } else {
      buffer.writeln(' {}');
    }

    if (withFullyResolvedAst) {
      _withIndent(() {
        _writeResolvedTypeParameters(e.typeParameters);
        _writeResolvedMetadata(e.metadata);
        _writeParameterElementDefaultValues(e.parameters);
      });
    }
  }

  void writeName(Element e) {
    buffer.write(e.displayName);
    if (withOffsets) {
      buffer.write('@');
      buffer.write(e.nameOffset);
    }
  }

  void writeNamespaceCombinator(NamespaceCombinator e) {
    if (e is ShowElementCombinator) {
      buffer.write(' show ');
      buffer.write(e.shownNames.join(', '));
    } else if (e is HideElementCombinator) {
      buffer.write(' hide ');
      buffer.write(e.hiddenNames.join(', '));
    }
  }

  void writeNode(AstNode? e, {Expression? enclosing}) {
    bool needsParenthesis = e is Expression &&
        enclosing != null &&
        e.precedence < enclosing.precedence;

    if (needsParenthesis) {
      buffer.write('(');
    }

    if (e == null) {
      buffer.write('<null>');
    } else if (e is SimpleIdentifier && e.name == '#invalidConst') {
      buffer.write('#invalidConst');
    } else if (e is AdjacentStrings) {
      writeList("'", "'", e.strings, '',
          (StringLiteral s) => buffer.write(s.stringValue),
          includeEmpty: true);
    } else if (e is Annotation) {
      buffer.write('@');
      writeNode(e.name);
      if (e.constructorName != null) {
        buffer.write('.');
        writeNode(e.constructorName);
      }
      if (e.arguments != null) {
        writeList('(', ')', e.arguments!.arguments, ', ', writeNode,
            includeEmpty: true);
      }
    } else if (e is AsExpression) {
      writeNode(e.expression);
      buffer.write(' as ');
      writeNode(e.type);
    } else if (e is AssertInitializer) {
      buffer.write('assert(');
      writeNode(e.condition);
      if (e.message != null) {
        buffer.write(', ');
        writeNode(e.message);
      }
      buffer.write(')');
    } else if (e is BinaryExpression) {
      writeNode(e.leftOperand, enclosing: e);
      buffer.write(' ');
      buffer.write(e.operator.lexeme);
      buffer.write(' ');
      writeNode(e.rightOperand, enclosing: e);
    } else if (e is BooleanLiteral) {
      buffer.write(e.value);
    } else if (e is ConditionalExpression) {
      writeNode(e.condition);
      buffer.write(' ? ');
      writeNode(e.thenExpression);
      buffer.write(' : ');
      writeNode(e.elseExpression);
    } else if (e is ConstructorFieldInitializer) {
      writeNode(e.fieldName);
      buffer.write(' = ');
      writeNode(e.expression);
    } else if (e is ConstructorName) {
      writeNode(e.type);
      if (e.name != null) {
        buffer.write('.');
        writeNode(e.name);
      }
    } else if (e is DoubleLiteral) {
      buffer.write(e.value);
    } else if (e is GenericFunctionType) {
      if (e.returnType != null) {
        writeNode(e.returnType);
        buffer.write(' ');
      }
      buffer.write('Function');
      if (e.typeParameters != null) {
        writeList('<', '>', e.typeParameters!.typeParameters, ', ', writeNode);
      }
      writeList('(', ')', e.parameters.parameters, ', ', writeNode,
          includeEmpty: true);
    } else if (e is InstanceCreationExpression) {
      if (e.keyword != null) {
        buffer.write(e.keyword!.lexeme);
        buffer.write(' ');
      }
      if (withTypes && e.constructorName.type.typeArguments == null) {
        writeInterfaceTypeArgsComment(e);
      }
      writeNode(e.constructorName);
      writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
          includeEmpty: true);
    } else if (e is IntegerLiteral) {
      buffer.write(e.value);
    } else if (e is InterpolationExpression) {
      buffer.write(r'${');
      writeNode(e.expression);
      buffer.write(r'}');
    } else if (e is InterpolationString) {
      buffer.write(e.value.replaceAll("'", r"\'"));
    } else if (e is IsExpression) {
      writeNode(e.expression);
      buffer.write(e.notOperator == null ? ' is ' : ' is! ');
      writeNode(e.type);
    } else if (e is ListLiteral) {
      if (e.constKeyword != null) {
        buffer.write('const ');
      }
      if (e.typeArguments != null) {
        writeList('<', '>', e.typeArguments!.arguments, ', ', writeNode);
      } else if (withTypes) {
        writeInterfaceTypeArgsComment(e);
      }
      writeList('[', ']', e.elements, ', ', writeNode, includeEmpty: true);
    } else if (e is Label) {
      writeNode(e.label);
      buffer.write(': ');
    } else if (e is SetOrMapLiteral) {
      if (e.constKeyword != null) {
        buffer.write('const ');
      }
      if (e.typeArguments != null) {
        writeList('<', '>', e.typeArguments!.arguments, ', ', writeNode);
      } else if (withTypes) {
        writeInterfaceTypeArgsComment(e);
      }
      writeList('{', '}', e.elements, ', ', writeNode, includeEmpty: true);
      if (e.isMap) {
        buffer.write('/*isMap*/');
      }
      if (e.isSet) {
        buffer.write('/*isSet*/');
      }
    } else if (e is MapLiteralEntry) {
      writeNode(e.key);
      buffer.write(': ');
      writeNode(e.value);
    } else if (e is MethodInvocation) {
      if (e.target != null) {
        writeNode(e.target);
        buffer.write(e.operator);
      }
      writeNode(e.methodName);
      if (e.typeArguments != null) {
        writeList('<', '>', e.typeArguments!.arguments, ', ', writeNode);
      }
      writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
          includeEmpty: true);
    } else if (e is NamedExpression) {
      writeNode(e.name);
      buffer.write(e.expression);
    } else if (e is NullLiteral) {
      buffer.write('null');
    } else if (e is ParenthesizedExpression) {
      writeNode(e.expression, enclosing: e);
    } else if (e is PrefixExpression) {
      buffer.write(e.operator.lexeme);
      writeNode(e.operand, enclosing: e);
    } else if (e is PrefixedIdentifier) {
      writeNode(e.prefix);
      buffer.write('.');
      writeNode(e.identifier);
    } else if (e is PropertyAccess) {
      writeNode(e.target, enclosing: e);
      buffer.write('.');
      writeNode(e.propertyName);
    } else if (e is RedirectingConstructorInvocation) {
      buffer.write('this');
      if (e.constructorName != null) {
        buffer.write('.');
        writeNode(e.constructorName);
      }
      writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
          includeEmpty: true);
    } else if (e is SimpleFormalParameter) {
      writeNode(e.type);
      if (e.identifier != null) {
        buffer.write(' ');
        buffer.write(e.identifier!.name);
      }
    } else if (e is SimpleIdentifier) {
      if (withConstElements) {
        buffer.writeln();
        buffer.write('  ' * 4);
        buffer.write(e.name);
        buffer.write('/*');
        buffer.write('location: ');
        buffer.write(_getElementLocationString(e.staticElement));
        buffer.write('*/');
      } else {
        buffer.write(e.name);
      }
    } else if (e is SimpleStringLiteral) {
      buffer.write("'");
      buffer.write(e.value.replaceAll("'", r"\'"));
      buffer.write("'");
    } else if (e is StringInterpolation) {
      buffer.write("'");
      e.elements.forEach(writeNode);
      buffer.write("'");
    } else if (e is SuperConstructorInvocation) {
      buffer.write('super');
      if (e.constructorName != null) {
        buffer.write('.');
        writeNode(e.constructorName);
      }
      writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
          includeEmpty: true);
    } else if (e is SuperExpression) {
      buffer.write('super');
    } else if (e is SymbolLiteral) {
      buffer.write('#');
      writeList('', '', e.components, '.',
          (Token token) => buffer.write(token.lexeme));
    } else if (e is ThisExpression) {
      buffer.write('this');
    } else if (e is ThrowExpression) {
      buffer.write('throw ');
      writeNode(e.expression);
    } else if (e is TypeName) {
      writeNode(e.name);
      if (e.typeArguments != null) {
        writeList('<', '>', e.typeArguments!.arguments, ', ', writeNode);
      }
    } else if (e is SpreadElement) {
      buffer.write(e.spreadOperator.lexeme);
      writeNode(e.expression);
    } else if (e is IfElement) {
      buffer.write('if (');
      writeNode(e.condition);
      buffer.write(') ');
      writeNode(e.thenElement);
      var elseElement = e.elseElement;
      if (elseElement != null) {
        buffer.write(' else ');
        writeNode(elseElement);
      }
    } else {
      fail('Unsupported expression type: ${e.runtimeType}');
    }

    if (needsParenthesis) {
      buffer.write(')');
    }
  }

  void writeParameterElement(ParameterElement e) {
    String? defaultValueSeparator;
    Expression? defaultValue;
    String closeString;
    if (e.isRequiredPositional) {
      closeString = '';
    } else if (e.isOptionalPositional) {
      buffer.write('[');
      defaultValueSeparator = ' = ';
      defaultValue = (e as ConstVariableElement).constantInitializer;
      closeString = ']';
    } else if (e.isNamed) {
      buffer.write('{');
      defaultValueSeparator = ': ';
      defaultValue = (e as ConstVariableElement).constantInitializer;
      closeString = '}';
    } else {
      fail('Unknown parameter kind');
    }

    writeMetadata(e, '', ' ');

    writeIf(e.isCovariant, 'covariant ');
    writeIf(e.isFinal, 'final ');

    writeType2(e.type);

    if (e is FieldFormalParameterElement) {
      buffer.write('this.');
    }

    writeName(e);
    writeCodeRange(e);

    if (!withFullyResolvedAst) {
      if (e.typeParameters.isNotEmpty) {
        buffer.write('/*');
        writeTypeParameterElements(e.typeParameters, withDefault: false);
        buffer.write('*/');
      }

      if (e.parameters.isNotEmpty) {
        buffer.write('/*');
        writeList('(', ')', e.parameters, ', ', writeParameterElement);
        buffer.write('*/');
      }

      if (defaultValue != null) {
        buffer.write(defaultValueSeparator);
        writeNode(defaultValue);
      }
    }

    buffer.write(closeString);
  }

  void writeParameterElements(List<ParameterElement> elements) {
    writeList('(', ')', elements, ', ', writeParameterElement,
        includeEmpty: true);
  }

  void writePartElement(CompilationUnitElement e) {
    writeMetadata(e, '', '\n');
    buffer.write('part ');
    writeUri(e.source);
    buffer.writeln(';');
  }

  void writePropertyAccessorElement(PropertyAccessorElement e) {
    if (e.isSynthetic && !withSyntheticAccessors) {
      return;
    }

    if (!e.isSynthetic) {
      PropertyInducingElement variable = e.variable;
      expect(variable, isNotNull);

      if (e.isGetter) {
        // Usually we have a synthetic property for a non-synthetic accessor.
        expect(variable.isSynthetic, isTrue);
      } else {
        // But it is possible to have a non-synthetic property.
        // class A {
        //   final int foo;
        //   set foo(int newValue) {}
        // }
      }

      var variableEnclosing = variable.enclosingElement;
      if (variableEnclosing is CompilationUnitElement) {
        expect(variableEnclosing.topLevelVariables, contains(variable));
      } else if (variableEnclosing is ClassElement) {
        expect(variableEnclosing.fields, contains(variable));
      }

      if (e.isGetter) {
        expect(variable.getter, same(e));
        if (variable.setter != null) {
          expect(variable.setter!.variable, same(variable));
        }
      } else {
        expect(variable.setter, same(e));
        if (variable.getter != null) {
          expect(variable.getter!.variable, same(variable));
        }
      }
    }

    if (e.enclosingElement is ClassElement ||
        e.enclosingElement is ExtensionElement) {
      writeDocumentation(e, '  ');
      writeMetadata(e, '  ', '\n');

      buffer.write('  ');

      writeIf(e.isSynthetic, 'synthetic ');
      writeIf(e.isStatic, 'static ');
    } else {
      writeDocumentation(e);
      writeMetadata(e, '', '\n');
      writeIf(e.isSynthetic, 'synthetic ');
    }

    writeIf(e.isExternal, 'external ');

    writeType2(e.returnType);

    if (e.isGetter) {
      buffer.write('get ');
    } else {
      buffer.write('set ');
    }

    writeName(e);

    expect(e.typeParameters, isEmpty);

    if (e.isSetter || e.parameters.isNotEmpty) {
      writeParameterElements(e.parameters);
    }

    writeBodyModifiers(e);

    if (e.isAbstract || e.isExternal) {
      buffer.writeln(';');
    } else {
      buffer.writeln(' {}');
    }
  }

  void writePropertyInducingElement(PropertyInducingElement e) {
    if (e.isSynthetic && !withSyntheticFields && !isEnumField(e)) {
      return;
    }

    DartType type = e.type;
    expect(type, isNotNull);

    if (!e.isSynthetic) {
      expect(e.getter, isNotNull);
      _assertSyntheticAccessorEnclosing(e, e.getter!);

      if (e.setter != null) {
        _assertSyntheticAccessorEnclosing(e, e.setter!);
      }
    }

    if (e.enclosingElement is ClassElement ||
        e.enclosingElement is ExtensionElement) {
      writeDocumentation(e, '  ');
      writeMetadata(e, '  ', '\n');

      buffer.write('  ');

      writeIf(e.isSynthetic, 'synthetic ');
      writeIf(e.isStatic, 'static ');
      writeIf(e is FieldElementImpl && e.isAbstract, 'abstract ');
      writeIf(e is FieldElementImpl && e.isCovariant, 'covariant ');
      writeIf(e is FieldElementImpl && e.isExternal, 'external ');
    } else {
      writeDocumentation(e);
      writeMetadata(e, '', '\n');
      writeIf(e is TopLevelVariableElementImpl && e.isExternal, 'external ');
    }

    writeIf(e.isLate, 'late ');
    writeIf(e.isFinal, 'final ');
    writeIf(e.isConst, 'const ');
    writeType2(type);

    writeName(e);
    writeCodeRange(e);

    writeTypeInferenceError(e);

    if (withFullyResolvedAst) {
      buffer.writeln(';');
      _withIndent(() {
        _writeResolvedMetadata(e.metadata);
        if (e is ConstVariableElement) {
          var initializer = (e as ConstVariableElement).constantInitializer;
          if (initializer != null) {
            _writelnWithIndent('constantInitializer');
            _withIndent(() {
              _writeResolvedNode(initializer);
            });
          }
        }
      });
    } else {
      if (e is ConstVariableElement) {
        var initializer = (e as ConstVariableElement).constantInitializer;
        if (initializer != null) {
          buffer.write(' = ');
          writeNode(initializer);
        }
      }
      buffer.writeln(';');
    }

    // TODO(scheglov) Paul: One of the things that was hardest to get right
    // when resynthesizing the element model was the synthetic function for the
    // initializer.  Can we write that out (along with its return type)?
  }

  void writeType(DartType type) {
    var typeStr = _typeStr(type);
    buffer.write(typeStr);

    if (withAliasElementArguments) {
      var aliasElement = type.aliasElement;
      if (aliasElement is TypeAliasElementImpl) {
        buffer.write('<aliasElement: ');
        buffer.write(_referenceToString(aliasElement.reference!));
        var typeArguments = type.aliasArguments!;
        writeList(', aliasArguments: [', ']', typeArguments, ', ', writeType);
        buffer.write('>');
      }
    }
  }

  void writeType2(DartType type) {
    writeType(type);
    buffer.write(' ');
  }

  void writeTypeAliasElement(TypeAliasElement e) {
    writeDocumentation(e);
    writeMetadata(e, '', '\n');
    writeIf(!e.isSimplyBounded, 'notSimplyBounded ');

    buffer.write('typedef ');
    writeName(e);
    writeCodeRange(e);
    writeTypeParameterElements(e.typeParameters, withDefault: true);

    buffer.write(' = ');

    var aliasedElement = e.aliasedElement;
    if (aliasedElement is GenericFunctionTypeElement) {
      writeType(aliasedElement.returnType);
      buffer.write(' Function');
      writeTypeParameterElements(aliasedElement.typeParameters,
          withDefault: false);
      writeParameterElements(aliasedElement.parameters);
    } else {
      writeType(e.aliasedType);
    }

    buffer.writeln(';');

    if (withFullyResolvedAst) {
      _withIndent(() {
        _writeResolvedMetadata(e.metadata);
        _writeResolvedTypeParameters(e.typeParameters);
        var aliasedElement = e.aliasedElement;
        if (aliasedElement is GenericFunctionTypeElement) {
          _writelnWithIndent('aliasedElement');
          _withIndent(() {
            _writeResolvedTypeParameters(aliasedElement.typeParameters);
            _writeResolvedParameterElements(aliasedElement.parameters);
          });
        }
      });
    }
  }

  void writeTypeInferenceError(Element e) {
    TopLevelInferenceError? inferenceError;
    if (e is MethodElementImpl) {
      inferenceError = e.typeInferenceError;
    } else if (e is PropertyInducingElementImpl) {
      inferenceError = e.typeInferenceError;
    }

    if (inferenceError != null) {
      String kindName = inferenceError.kind.toString();
      if (kindName.startsWith('TopLevelInferenceErrorKind.')) {
        kindName = kindName.substring('TopLevelInferenceErrorKind.'.length);
      }
      buffer.write('/*error: $kindName*/');
    }
  }

  void writeTypeParameterElement(
    TypeParameterElement e, {
    required bool withDefault,
  }) {
    var impl = e as TypeParameterElementImpl;

    writeMetadata(e, '', '\n');

    // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
    // variance is added to the interface.
    if (withTypeParameterVariance) {
      var variance = impl.variance;
      buffer.write(variance.toString() + ' ');
    }

    writeName(e);
    writeCodeRange(e);
    if (e.bound != null && !e.bound!.isDartCoreObject) {
      buffer.write(' extends ');
      writeType(e.bound!);
    }

    if (withDefault) {
      var defaultType = impl.defaultType!;
      if (defaultType is! DynamicTypeImpl) {
        buffer.write(' = ');
        writeType(defaultType);
      }
    }
  }

  void writeTypeParameterElements(
    List<TypeParameterElement> elements, {
    required bool withDefault,
  }) {
    if (!withFullyResolvedAst) {
      writeList<TypeParameterElement>('<', '>', elements, ', ', (e) {
        writeTypeParameterElement(e, withDefault: withDefault);
      });
    }
  }

  void writeUnitElement(CompilationUnitElement e) {
    if (e.library.definingCompilationUnit != e) {
      buffer.writeln('-' * 20);
      buffer.writeln('unit: ${e.source.shortName}');
      buffer.writeln();
    }
    e.typeAliases.forEach(writeTypeAliasElement);
    e.enums.forEach(writeClassElement);
    e.types.forEach(writeClassElement);
    e.mixins.forEach(writeClassElement);
    e.extensions.forEach(writeExtensionElement);
    e.topLevelVariables.forEach(writePropertyInducingElement);
    e.accessors.forEach(writePropertyAccessorElement);
    e.functions.forEach(writeFunctionElement);
  }

  void writeUri(Source? source) {
    if (source != null) {
      Uri uri = source.uri;
      String uriStr = uri.toString();
      if (uri.isScheme('file')) {
        uriStr = uri.pathSegments.last;
      }
      buffer.write('\'$uriStr\'');
    } else {
      buffer.write('\'<unresolved>\'');
    }
  }

  /// Assert that the [accessor] of the [property] is correctly linked to
  /// the same enclosing element as the [property].
  void _assertSyntheticAccessorEnclosing(
      PropertyInducingElement property, PropertyAccessorElement accessor) {
    if (accessor.isSynthetic) {
      // Usually we have a non-synthetic property, and a synthetic accessor.
    } else {
      // But it is possible to have a non-synthetic setter.
      // class A {
      //   final int foo;
      //   set foo(int newValue) {}
      // }
      assert(accessor.isSetter, isTrue);
    }

    expect(accessor.variable, same(property));

    var propertyEnclosing = property.enclosingElement;
    expect(accessor.enclosingElement, same(propertyEnclosing));

    if (propertyEnclosing is CompilationUnitElement) {
      expect(propertyEnclosing.accessors, contains(accessor));
    } else if (propertyEnclosing is ClassElement) {
      expect(propertyEnclosing.accessors, contains(accessor));
    }
  }

  String _getElementLocationString(Element? element) {
    if (element == null || element is MultiplyDefinedElement) {
      return 'null';
    }

    String onlyName(String uri) {
      if (uri.startsWith('file:///')) {
        return uri.substring(uri.lastIndexOf('/') + 1);
      }
      return uri;
    }

    var location = element.location!;
    List<String> components = location.components.toList();
    if (components.isNotEmpty) {
      components[0] = onlyName(components[0]);
    }
    if (components.length >= 2) {
      components[1] = onlyName(components[1]);
      if (components[0] == components[1]) {
        components.removeAt(0);
      }
    }
    return components.join(';');
  }

  String _referenceToString(Reference reference) {
    var parent = reference.parent!;
    if (parent.parent == null) {
      var libraryUriStr = reference.name;
      if (libraryUriStr == selfUriStr) {
        return 'self';
      }
      return libraryUriStr;
    }

    // Ignore the unit, skip to the library.
    if (parent.name == '@unit') {
      return _referenceToString(parent.parent!);
    }

    var name = reference.name;
    return _referenceToString(parent) + '::$name';
  }

  String? _typeStr(DartType? type) {
    return type?.getDisplayString(
      withNullability: true,
    );
  }

  void _withIndent(void Function() f) {
    var savedIndent = indent;
    indent = '$savedIndent  ';
    f();
    indent = savedIndent;
  }

  void _writelnTypeWithIndent(String name, DartType? type) {
    buffer.write(indent);
    buffer.write('$name: ');
    buffer.writeln(_typeStr(type));
  }

  void _writelnWithIndent(String line) {
    buffer.write(indent);
    buffer.writeln(line);
  }

  void _writeParameterElementDefaultValues(
    List<ParameterElement> parameters, {
    String enclosingNames = '',
  }) {
    for (var parameter in parameters) {
      if (parameter is ConstVariableElement) {
        var defaultParameter = parameter as ConstVariableElement;
        var defaultValue = defaultParameter.constantInitializer;
        if (defaultValue != null) {
          _writelnWithIndent(enclosingNames + parameter.name);
          _withIndent(() {
            _writeResolvedNode(defaultValue);
          });
        }
      }
      var subParameters = parameter.parameters;
      _withIndent(() {
        _writeParameterElementDefaultValues(
          subParameters,
          enclosingNames: enclosingNames + parameter.name + '::',
        );
      });
    }
  }

  void _writeResolvedMetadata(List<ElementAnnotation> metadata) {
    if (metadata.isNotEmpty) {
      _writelnWithIndent('metadata');
      _withIndent(() {
        for (var annotation in metadata) {
          annotation as ElementAnnotationImpl;
          _writeResolvedNode(annotation.annotationAst);
        }
      });
    }
  }

  void _writeResolvedNode(AstNode node) {
    buffer.write(indent);
    node.accept(
      ResolvedAstPrinter(
        selfUriStr: selfUriStr,
        sink: buffer,
        indent: indent,
        withNullability: true,
      ),
    );
  }

  void _writeResolvedParameterElements(
    List<ParameterElement> parameters, {
    String enclosingNames = '',
  }) {
    if (parameters.isNotEmpty) {
      _writelnWithIndent('parameters');
      _withIndent(() {
        var index = 0;
        for (var formalParameter in parameters) {
          var metadata = formalParameter.metadata;
          var name = formalParameter.name;
          if (name.isEmpty) {
            name = '$index';
          }
          _writelnWithIndent(name);
          _withIndent(() {
            _writeResolvedMetadata(metadata);
            var subParameters = formalParameter.parameters;
            _withIndent(() {
              _writeResolvedParameterElements(
                subParameters,
                enclosingNames: enclosingNames + name + '::',
              );
            });
          });
          index++;
        }
      });
    }
  }

  void _writeResolvedTypeParameters(List<TypeParameterElement> elements) {
    if (elements.isNotEmpty) {
      _writelnWithIndent('typeParameters');
      _withIndent(() {
        for (var e in elements) {
          e as TypeParameterElementImpl;
          _writelnWithIndent(e.name);
          _withIndent(() {
            _writelnTypeWithIndent('bound', e.bound);
            _writelnTypeWithIndent('defaultType', e.defaultType);
            _writeResolvedMetadata(e.metadata);
          });
        }
      });
    }
  }
}

class _Replacement {
  final int offset;
  final int end;
  final String text;

  _Replacement(this.offset, this.end, this.text);
}
