// Copyright (c) 2020, 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:async' show Future, StreamSubscription;

import 'dart:convert' show JsonEncoder, jsonDecode, utf8;

import 'dart:io' show BytesBuilder, File, stdin, stdout;

import 'dart:math' show max;

import 'dart:typed_data' show Uint8List;

import 'package:_fe_analyzer_shared/src/util/relativize.dart'
    show relativizeUri, isWindows;

import 'package:_fe_analyzer_shared/src/parser/parser.dart'
    show Listener, Parser;

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show ErrorToken, ScannerConfiguration, Token;

import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;

import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;

import 'package:front_end/src/api_prototype/compiler_options.dart'
    show CompilerOptions, DiagnosticMessage;

import 'package:front_end/src/api_prototype/experimental_flags.dart'
    show ExperimentalFlag;

import 'package:front_end/src/api_prototype/file_system.dart'
    show FileSystem, FileSystemEntity, FileSystemException;

import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;
import 'package:front_end/src/fasta/builder/library_builder.dart';

import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;

import 'package:front_end/src/fasta/incremental_compiler.dart'
    show IncrementalCompiler;

import 'package:front_end/src/fasta/kernel/utils.dart' show ByteSink;
import 'package:front_end/src/fasta/messages.dart' show Message;
import 'package:front_end/src/fasta/source/diet_parser.dart'
    show useImplicitCreationExpressionInCfe;
import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';

import 'package:front_end/src/fasta/util/textual_outline.dart'
    show textualOutline;

import 'package:kernel/ast.dart' show Component, LibraryPart;

import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;

import 'package:kernel/target/targets.dart' show Target, TargetFlags;
import 'package:package_config/package_config.dart';

import "package:vm/target/flutter.dart" show FlutterTarget;

import "package:vm/target/vm.dart" show VmTarget;

import 'incremental_suite.dart' show getOptions;

import 'parser_test_listener.dart' show ParserTestListener;

import 'parser_suite.dart' as parser_suite;

class TestMinimizerSettings {
  final _FakeFileSystem _fsInitial = new _FakeFileSystem();
  final _FakeFileSystem _fsNotInitial = new _FakeFileSystem();
  _FakeFileSystem get _fs {
    if (_useInitialFs) return _fsInitial;
    return _fsNotInitial;
  }

  bool _useInitialFs = true;
  Uri? mainUri;
  Uri? platformUri;
  bool noPlatform = false;
  bool experimentalInvalidation = false;
  bool serialize = false;
  bool widgetTransformation = false;
  final List<Uri> invalidate = [];
  String targetString = "VM";
  bool noTryToDeleteEmptyFilesUpFront = false;
  bool oldBlockDelete = false;
  bool lineDelete = false;
  bool byteDelete = false;
  bool askAboutRedirectCrashTarget = false;
  bool autoUncoverAllCrashes = false;
  int stackTraceMatches = 1;
  String? lookForErrorErrorOnReload;
  final Set<String> askedAboutRedirect = {};
  final List<Map<String, dynamic>> fileSystems = [];
  final Set<String> allAutoRedirects = {};

  void goToFileSystem(int i) {
    Map<String, dynamic> fileSystem = fileSystems[i];
    fileSystems[i] = _fsNotInitial.toJson();
    _fsNotInitial.initializeFromJson(fileSystem);
  }

  Map<String, dynamic> toJson() {
    List<Map<String, dynamic>> fileSystems =
        new List<Map<String, dynamic>>.from(this.fileSystems);
    fileSystems.add(_fsNotInitial.toJson());
    return {
      'mainUri': mainUri.toString(),
      'platformUri': platformUri.toString(),
      'noPlatform': noPlatform,
      'experimentalInvalidation': experimentalInvalidation,
      'serialize': serialize,
      'widgetTransformation': widgetTransformation,
      'invalidate': invalidate.map((uri) => uri.toString()).toList(),
      'targetString': targetString,
      'noTryToDeleteEmptyFilesUpFront': noTryToDeleteEmptyFilesUpFront,
      'oldBlockDelete': oldBlockDelete,
      'lineDelete': lineDelete,
      'byteDelete': byteDelete,
      'askAboutRedirectCrashTarget': askAboutRedirectCrashTarget,
      'autoUncoverAllCrashes': autoUncoverAllCrashes,
      'stackTraceMatches': stackTraceMatches,
      'askedAboutRedirect': askedAboutRedirect.toList(),
      'fileSystems': fileSystems,
      'allAutoRedirects': allAutoRedirects.toList(),
      'lookForErrorErrorOnReload': lookForErrorErrorOnReload,
    };
  }

  initializeFromJson(Map<String, dynamic> json) {
    mainUri = Uri.parse(json["mainUri"]);
    platformUri = Uri.parse(json["platformUri"]);
    noPlatform = json["noPlatform"];
    experimentalInvalidation = json["experimentalInvalidation"];
    serialize = json["serialize"];
    widgetTransformation = json["widgetTransformation"];
    invalidate.clear();
    invalidate.addAll(
        (json["invalidate"] as List).map((uriString) => Uri.parse(uriString)));
    targetString = json["targetString"];
    noTryToDeleteEmptyFilesUpFront = json["noTryToDeleteEmptyFilesUpFront"];
    oldBlockDelete = json["oldBlockDelete"];
    lineDelete = json["lineDelete"];
    byteDelete = json["byteDelete"];
    askAboutRedirectCrashTarget = json["askAboutRedirectCrashTarget"];
    autoUncoverAllCrashes = json["autoUncoverAllCrashes"];
    stackTraceMatches = json["stackTraceMatches"];
    askedAboutRedirect.clear();
    askedAboutRedirect.addAll((json["askedAboutRedirect"] as List).cast());
    fileSystems.clear();
    fileSystems.addAll((json["fileSystems"] as List).cast());
    allAutoRedirects.clear();
    allAutoRedirects.addAll((json["allAutoRedirects"] as List).cast());
    lookForErrorErrorOnReload = json["lookForErrorErrorOnReload"];

    _fsNotInitial.initializeFromJson(fileSystems.removeLast());
  }
}

// TODO(jensj): The different cuts and inlines in this file aren't tested.
// The probably should be. So they should probably be factored out so they can
// be tested and then tested.
// Similarly the whole +/- 1 thing to cut out what we want is weird and should
// be factored out into helpers too, or we should have some sort of visitor
// that can include the "real" numbers (which should then also be tested).

class TestMinimizer {
  final TestMinimizerSettings _settings;
  _FakeFileSystem get _fs => _settings._fs;
  Uri get _mainUri => _settings.mainUri!;
  String? _expectedCrashLine;
  bool _quit = false;
  bool _skip = false;
  bool _check = false;
  int _currentFsNum = -1;
  bool _gotWantedError = false;

  Component? _latestComponent;
  IncrementalCompiler? _latestCrashingIncrementalCompiler;
  StreamSubscription<List<int>>? _stdinSubscription;

  static const int _$LF = 10;

  TestMinimizer(this._settings);

  void _setupStdin() {
    try {
      stdin.echoMode = false;
      stdin.lineMode = false;
    } catch (e) {
      print("Trying to setup 'stdin' failed. Continuing anyway, "
          "but 'q', 'i' etc might not work.");
    }
    _stdinSubscription = stdin.listen((List<int> event) {
      if (event.length == 1 && event.single == "q".codeUnits.single) {
        print("\n\nGot told to quit!\n\n");
        _quit = true;
      } else if (event.length == 1 && event.single == "s".codeUnits.single) {
        print("\n\nGot told to skip!\n\n");
        _skip = true;
      } else if (event.length == 1 && event.single == "c".codeUnits.single) {
        print("\n\nGot told to check!\n\n");
        _check = true;
      } else if (event.length == 1 && event.single == "i".codeUnits.single) {
        print("\n\n--- STATUS INFORMATION START ---\n\n");
        print("Currently looking for this crash: $_expectedCrashLine\n\n");
        print("Currently on filesystem #$_currentFsNum out of "
            "${_settings.fileSystems.length}\n\n");

        int totalFiles = 0;
        int emptyFiles = 0;
        int combinedSize = 0;
        for (Uri? uri in _fs.data.keys) {
          final Uint8List? originalBytes = _fs.data[uri];
          if (originalBytes == null) continue;
          totalFiles++;
          if (originalBytes.isEmpty) emptyFiles++;
          combinedSize += originalBytes.length;
        }
        print("Total files left: $totalFiles.");
        print("Of which empty: $emptyFiles.");
        print("Combined size left: $combinedSize bytes.");
        print("\n\n--- STATUS INFORMATION END ---\n\n");
      } else {
        print("\n\nGot stdin input: $event\n\n");
      }
    });
  }

  Future tryToMinimize() async {
    _setupStdin();
    while (_currentFsNum < _settings.fileSystems.length) {
      try {
        if (_currentFsNum >= 0) {
          print("Replacing filesystem!");
          _settings.goToFileSystem(_currentFsNum);
          _expectedCrashLine = null;
          _latestComponent = null;
          _latestCrashingIncrementalCompiler = null;
        }
        await _tryToMinimizeImpl();
        if (_currentFsNum + 1 < _settings.fileSystems.length) {
          // We have more to do --- but we just printed something the user might
          // want to read. So wait a little before continuing.
          print("Waiting for 5 seconds before continuing.");
          await Future.delayed(new Duration(seconds: 5));
        }
      } catch (e) {
        if (e is _DoesntCrashOnInput) {
          print("Currently doesn't crash (or no longer crashes) the compiler.");
        } else {
          print("About to crash. Dumping settings including the filesystem so "
              "we can (hopefully) continue later.");
          _dumpToJson();
          rethrow;
        }
      }
      _currentFsNum++;
    }

    await _stdinSubscription!.cancel();
  }

  Future _tryToMinimizeImpl() async {
    // Set main to be basically empty up front.
    _settings._useInitialFs = true;
    _fs.data[_mainUri] = utf8.encode("main() {}") as Uint8List;
    Component initialComponent = await _getInitialComponent();
    print("Compiled initially (without data)");
    // Remove fake cache.
    _fs.data.remove(_mainUri);
    _settings._useInitialFs = false;

    // First assure it actually crash on the input.
    if (!await _crashesOnCompile(initialComponent)) {
      throw new _DoesntCrashOnInput();
    }
    print("Step #1: We did crash on the input!");

    // All file should now be cached.
    _fs._redirectAndRecord = false;

    // For all dart files: Parse them as set their source as the parsed source
    // to "get around" any encoding issues when printing later.
    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
    for (Uri? uri in _fs.data.keys) {
      if (await _shouldQuit()) break;
      String uriString = uri.toString();
      if (uriString.endsWith(".json") ||
          uriString.endsWith(".packages") ||
          uriString.endsWith(".dill") ||
          _fs.data[uri] == null ||
          _fs.data[uri]!.isEmpty) {
        // skip
      } else {
        try {
          if (_knownByCompiler(uri!)) {
            String parsedString =
                _getFileAsStringContent(_fs.data[uri]!, _isUriNnbd(uri));
            _fs.data[uri] = utf8.encode(parsedString) as Uint8List;
          }
        } catch (e) {
          // crash in scanner/parser --- keep original file. This crash might
          // be what we're looking for!
        }
      }
    }
    if (!await _crashesOnCompile(initialComponent)) {
      // Now - for whatever reason - we didn't crash. Restore.
      _fs.data.clear();
      _fs.data.addAll(copy);
    }

    // Operate on one file at a time: Try to delete all content in file.
    List<Uri> uris = new List<Uri>.from(_fs.data.keys);

    // TODO(jensj): Can we "thread" this?
    bool changedSome = true;
    while (changedSome) {
      if (await _shouldQuit()) break;
      while (changedSome) {
        if (await _shouldQuit()) break;
        changedSome = false;
        for (int i = 0; i < uris.length; i++) {
          if (await _shouldQuit()) break;
          Uri uri = uris[i];
          if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
          print("About to work on file $i of ${uris.length}");
          await _deleteContent(uris, i, false, initialComponent);
          if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) {
            changedSome = true;
          }
        }
      }

      // Try to delete empty files.
      if (!_settings.noTryToDeleteEmptyFilesUpFront) {
        bool changedSome2 = true;
        while (changedSome2) {
          if (await _shouldQuit()) break;
          changedSome2 = false;
          for (int i = 0; i < uris.length; i++) {
            if (await _shouldQuit()) break;
            Uri uri = uris[i];
            if (_fs.data[uri] == null || _fs.data[uri]!.isNotEmpty) continue;
            print("About to work on file $i of ${uris.length}");
            await _deleteContent(uris, i, false, initialComponent,
                deleteFile: true);
            if (_fs.data[uri] == null) {
              changedSome = true;
              changedSome2 = true;
            }
          }
        }
      }

      int left = 0;
      for (Uri uri in uris) {
        if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
        left++;
      }
      print("There's now $left files of ${_fs.data.length} files left");

      // Operate on one file at a time.
      for (Uri? uri in _fs.data.keys) {
        if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
        if (await _shouldQuit()) break;

        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
          if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
          if (await _shouldQuit()) break;
        }

        if (_check) {
          _check = false;
          if (!await _crashesOnCompile(initialComponent)) {
            throw "Check revealed that the current file system doesn't crash.";
          } else {
            print("Check OK!");
          }
        }

        print("Now working on $uri");

        int prevLength = _fs.data[uri]!.length;

        await _deleteBlocks(uri!, initialComponent);
        await _deleteEmptyLines(uri, initialComponent);

        if (_settings.oldBlockDelete) {
          // Try to delete blocks.
          await _deleteBlocksOld(uri, initialComponent);
        }

        if (_settings.lineDelete) {
          // Try to delete lines.
          await _deleteLines(uri, initialComponent);
        }

        print("We're now at ${_fs.data[uri]!.length} bytes for $uri "
            "(was $prevLength).");
        if (prevLength != _fs.data[uri]!.length) changedSome = true;
        if (_fs.data[uri]!.isEmpty) continue;

        if (_settings.byteDelete) {
          // Now try to delete 'arbitrarily' (for any given start offset do an
          // exponential binary search).
          int prevLength = _fs.data[uri]!.length;
          while (true) {
            if (await _shouldQuit()) break;
            await _binarySearchDeleteData(uri, initialComponent);

            if (_fs.data[uri]!.length == prevLength) {
              // No progress.
              break;
            } else {
              print("We're now at ${_fs.data[uri]!.length} bytes");
              prevLength = _fs.data[uri]!.length;
              changedSome = true;
            }
          }
        }
      }
      for (Uri? uri in _fs.data.keys) {
        if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
        if (await _shouldQuit()) break;

        if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
          if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
          if (await _shouldQuit()) break;
        }

        if (await _attemptInline(uri!, initialComponent)) {
          changedSome = true;

          if (await _tryRemoveIfNotKnownByCompiler(uri, initialComponent)) {
            if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
            if (await _shouldQuit()) break;
          }
        }
      }

      // Partially a sanity-check, and partially to make sure there's a latest
      // component for [_tryToRemoveUnreferencedFileContent] to work with (if
      // crashing after an invalidation).
      if (!await _crashesOnCompile(initialComponent)) {
        throw "At a state where we should crash, we didn't!";
      }
      await _tryToRemoveUnreferencedFileContent(initialComponent,
          deleteFile: true);
    }

    if (await _shouldQuit()) {
      print("\n\nASKED TO QUIT\n\n");
    } else {
      print("\n\nDONE\n\n");
    }

    Uri jsonOut = _dumpToJson();

    if (!await _shouldQuit()) {
      // Test converting to incremental compiler yaml test.
      _outputIncrementalCompilerYamlTest();
      print("\n\n\n");

      for (Uri uri in uris) {
        if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) continue;
        print("Uri $uri has this content:");

        try {
          String utfDecoded = utf8.decode(_fs.data[uri]!, allowMalformed: true);
          print(utfDecoded);
        } catch (e) {
          print(_fs.data[uri]);
          print("(which crashes when trying to decode as utf8)");
        }
        print("\n\n====================\n\n");
      }

      print("Wrote json dump to $jsonOut");
    }
  }

  Future<bool> _shouldQuit() async {
    // allow some time for stdin.listen to process data.
    await new Future.delayed(new Duration(milliseconds: 5));
    return _quit;
  }

  Uri _dumpToJson() {
    JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
    String json = jsonEncoder.convert(_settings);
    int i = 0;
    Uri? jsonOut;
    while (jsonOut == null || new File.fromUri(jsonOut).existsSync()) {
      jsonOut = Uri.base.resolve("crash_minimizer_result_$i");
      i++;
    }
    new File.fromUri(jsonOut).writeAsStringSync(json);
    print("Wrote json dump to $jsonOut");
    return jsonOut;
  }

  /// Attempts to inline small files in other files.
  /// Returns true if anything was changed, i.e. if at least one inlining was a
  /// success.
  Future<bool> _attemptInline(Uri uri, Component initialComponent) async {
    // Don't attempt to inline the main uri --- that's our entry!
    if (uri == _mainUri) return false;

    Uint8List inlineData = _fs.data[uri]!;
    bool hasMultipleLines = false;
    for (int i = 0; i < inlineData.length; i++) {
      if (inlineData[i] == _$LF) {
        hasMultipleLines = true;
        break;
      }
    }
    // TODO(jensj): Maybe inline slightly bigger files too?
    if (hasMultipleLines) {
      return false;
    }

    Uri inlinableUri = uri;

    int compileTry = 0;
    bool changed = false;

    for (Uri? uri in _fs.data.keys) {
      if (!uri.toString().endsWith(".dart")) continue;
      if (inlinableUri == uri) continue;
      final Uint8List? originalBytes = _fs.data[uri];
      if (originalBytes == null || originalBytes.isEmpty) continue;
      DirectParserASTContentCompilationUnitEnd ast = getAST(originalBytes,
          includeBody: false,
          includeComments: false,
          enableExtensionMethods: true,
          enableNonNullable: _isUriNnbd(uri!));
      // Find all imports/exports of this file (if any).
      // If finding any:
      // * remove all of them, then
      // * find the end of the last import/export, and
      // * insert the content of the file there.
      // * if that *doesn't* work and we've inserted an export,
      //   try converting that to an import instead.
      List<_Replacement> replacements = [];
      for (DirectParserASTContentImportEnd import in ast.getImports()) {
        Token importUriToken = import.importKeyword.next!;
        Uri importUri = _getUri(importUriToken, uri);
        if (inlinableUri == importUri) {
          replacements.add(new _Replacement(
              import.importKeyword.offset - 1, import.semicolon!.offset + 1));
        }
      }
      for (DirectParserASTContentExportEnd export in ast.getExports()) {
        Token exportUriToken = export.exportKeyword.next!;
        Uri exportUri = _getUri(exportUriToken, uri);
        if (inlinableUri == exportUri) {
          replacements.add(new _Replacement(
              export.exportKeyword.offset - 1, export.semicolon.offset + 1));
        }
      }
      if (replacements.isEmpty) continue;

      // Step 1: Remove all imports/exports *of* this file (the inlinable file).
      final Uint8List withoutInlineable =
          _replaceRange(replacements, originalBytes);

      // Step 2: Find the last import/export.
      // TODO(jensj): This doesn't work if
      // * The file we're inlining into doesn't have any imports/exports but do
      //   have a `library` declaration.
      // * The file we're inlining has a library declaration.
      int offsetOfLast = 0;
      ast = getAST(withoutInlineable,
          includeBody: false,
          includeComments: false,
          enableExtensionMethods: true,
          enableNonNullable: _isUriNnbd(uri));
      for (DirectParserASTContentImportEnd import in ast.getImports()) {
        offsetOfLast = max(offsetOfLast, import.semicolon!.offset + 1);
      }
      for (DirectParserASTContentExportEnd export in ast.getExports()) {
        offsetOfLast = max(offsetOfLast, export.semicolon.offset + 1);
      }

      // Step 3: Insert the content of the file there. Note, though,
      // that any imports/exports in _that_ file should be changed to be valid
      // in regards to the new placement.
      final String withoutInlineableString = utf8.decode(withoutInlineable);
      StringBuffer builder = new StringBuffer();
      for (int i = 0; i < offsetOfLast; i++) {
        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
      }
      builder.write("\n");
      builder.write(utf8.decode(_rewriteImportsExportsToUri(
          inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri))));
      builder.write("\n");
      for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
        builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
      }
      final Uint8List inlinedWithoutChange =
          utf8.encode(builder.toString()) as Uint8List;

      if (!_parsesWithoutError(inlinedWithoutChange, _isUriNnbd(uri))) {
        print("WARNING: Parser error after stuff at ${StackTrace.current}");
      }

      // Step 4: Try it out.
      if (await _shouldQuit()) break;
      if (_skip) {
        _skip = false;
        break;
      }
      stdout.write(".");
      compileTry++;
      if (compileTry % 50 == 0) {
        stdout.write("(at $compileTry)\n");
      }
      _fs.data[uri] = inlinedWithoutChange;
      if (await _crashesOnCompile(initialComponent)) {
        print("Could inline $inlinableUri into $uri.");
        changed = true;
        // File was already updated.
      } else {
        // Couldn't replace that.
        // Insert the original again.
        _fs.data[uri] = originalBytes;

        // If we've inlined an export, try changing that to an import.
        builder = new StringBuffer();
        for (int i = 0; i < offsetOfLast; i++) {
          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
        }
        builder.write("\n");
        builder.write(utf8.decode(_rewriteImportsExportsToUri(
            inlineData, uri, inlinableUri, _isUriNnbd(inlinableUri),
            convertExportToImport: true)));
        builder.write("\n");
        for (int i = offsetOfLast; i < withoutInlineableString.length; i++) {
          builder.writeCharCode(withoutInlineableString.codeUnitAt(i));
        }
        Uint8List inlinedWithChange =
            utf8.encode(builder.toString()) as Uint8List;

        if (!_parsesWithoutError(inlinedWithChange, _isUriNnbd(uri))) {
          print("WARNING: Parser error after stuff at ${StackTrace.current}");
        }

        // Step 4: Try it out.
        if (await _shouldQuit()) break;
        if (_skip) {
          _skip = false;
          break;
        }
        stdout.write(".");
        compileTry++;
        if (compileTry % 50 == 0) {
          stdout.write("(at $compileTry)\n");
        }
        _fs.data[uri] = inlinedWithChange;
        if (await _crashesOnCompile(initialComponent)) {
          print("Could inline $inlinableUri into $uri "
              "(by converting export to import).");
          changed = true;
          // File was already updated.
        } else {
          // Couldn't replace that.
          // Insert the original again.
          _fs.data[uri] = originalBytes;
        }
      }
    }

    return changed;
  }

  Uint8List _rewriteImportsExportsToUri(
      Uint8List oldData, Uri newUri, Uri oldUri, bool nnbd,
      {bool convertExportToImport: false}) {
    DirectParserASTContentCompilationUnitEnd ast = getAST(oldData,
        includeBody: false,
        includeComments: false,
        enableExtensionMethods: true,
        enableNonNullable: nnbd);
    List<_Replacement> replacements = [];
    for (DirectParserASTContentImportEnd import in ast.getImports()) {
      _rewriteImportsExportsToUriInternal(
          import.importKeyword.next!, oldUri, replacements, newUri);
    }
    for (DirectParserASTContentExportEnd export in ast.getExports()) {
      if (convertExportToImport) {
        replacements.add(new _Replacement(
          export.exportKeyword.offset - 1,
          export.exportKeyword.offset + export.exportKeyword.length,
          nullOrReplacement: "import",
        ));
      }
      _rewriteImportsExportsToUriInternal(
          export.exportKeyword.next!, oldUri, replacements, newUri);
    }
    if (replacements.isNotEmpty) {
      Uint8List candidate = _replaceRange(replacements, oldData);
      return candidate;
    }
    return oldData;
  }

  void _outputIncrementalCompilerYamlTest() {
    int dartFiles = 0;
    for (MapEntry<Uri?, Uint8List?> entry in _fs.data.entries) {
      if (entry.key!.pathSegments.last.endsWith(".dart")) {
        if (entry.value != null) dartFiles++;
      }
    }

    print("------ Reproduction as semi-done incremental yaml test file ------");

    // TODO(jensj): don't use full uris.
    print("""
# Copyright (c) 2021, 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.md file.

# Reproduce a crash.

type: newworld""");
    if (_settings.widgetTransformation) {
      print("trackWidgetCreation: true");
      print("target: DDC # basically needed for widget creation to be run");
    }
    print("""
worlds:
  - entry: $_mainUri""");
    if (_settings.experimentalInvalidation) {
      print("    experiments: alternative-invalidation-strategy");
    }
    print("    sources:");
    for (MapEntry<Uri?, Uint8List?> entry in _fs.data.entries) {
      if (entry.value == null) continue;
      print("      ${entry.key}: |");
      String string = utf8.decode(entry.value!);
      List<String> lines = string.split("\n");
      for (String line in lines) {
        print("        $line");
      }
    }
    print("    expectedLibraryCount: $dartFiles "
        "# with parts this is not right");
    print("");

    for (Uri uri in _settings.invalidate) {
      print("  - entry: $_mainUri");
      if (_settings.experimentalInvalidation) {
        print("    experiments: alternative-invalidation-strategy");
      }
      print("    worldType: updated");
      print("    expectInitializeFromDill: false # or true?");
      print("    invalidate:");
      print("      - $uri");
      print("    expectedLibraryCount: $dartFiles "
          "# with parts this is not right");
      print("    expectsRebuildBodiesOnly: true # or false?");
      print("");
    }

    print("------------------------------------------------------------------");
  }

  void _rewriteImportsExportsToUriInternal(
      Token uriToken, Uri oldUri, List<_Replacement> replacements, Uri newUri) {
    Uri tokenUri = _getUri(uriToken, oldUri, resolvePackage: false);
    if (tokenUri.scheme == "package" || tokenUri.scheme == "dart") return;
    Uri asPackageUri = _getImportUri(tokenUri);
    if (asPackageUri.scheme == "package") {
      // Just replace with this package uri.
      replacements.add(new _Replacement(
        uriToken.offset - 1,
        uriToken.offset + uriToken.length,
        nullOrReplacement: '"${asPackageUri.toString()}"',
      ));
    } else {
      String relative = relativizeUri(newUri, tokenUri, isWindows);
      // TODO(jensj): Maybe if the relative uri becomes too long or has to many
      // "../../" etc we should just use the absolute uri instead.
      replacements.add(new _Replacement(
        uriToken.offset - 1,
        uriToken.offset + uriToken.length,
        nullOrReplacement: '"${relative}"',
      ));
    }
  }

  Uri _getUri(Token uriToken, Uri uri, {bool resolvePackage: true}) {
    String uriString = uriToken.lexeme;
    uriString = uriString.substring(1, uriString.length - 1);
    Uri uriTokenUri = uri.resolve(uriString);
    if (resolvePackage && uriTokenUri.scheme == "package") {
      Package package = _latestCrashingIncrementalCompiler!
          .currentPackagesMap![uriTokenUri.pathSegments.first]!;
      uriTokenUri = package.packageUriRoot
          .resolve(uriTokenUri.pathSegments.skip(1).join("/"));
    }
    return uriTokenUri;
  }

  Uri _getImportUri(Uri uri) {
    return _latestCrashingIncrementalCompiler!.userCode!
        .getEntryPointUri(uri, issueProblem: false);
  }

  Uint8List _sublist(Uint8List data, int start, int end) {
    Uint8List result = new Uint8List(end - start);
    result.setRange(0, result.length, data, start);
    return result;
  }

  Future<void> _binarySearchDeleteData(
      Uri uri, Component initialComponent) async {
    Uint8List latestCrashData = _fs.data[uri]!;
    int offset = 0;
    while (offset < latestCrashData.length) {
      print("Working at offset $offset of ${latestCrashData.length}");
      BytesBuilder builder = new BytesBuilder();
      builder.add(_sublist(latestCrashData, 0, offset));
      builder
          .add(_sublist(latestCrashData, offset + 1, latestCrashData.length));
      Uint8List candidate = builder.takeBytes();
      _fs.data[uri] = candidate;
      if (!await _crashesOnCompile(initialComponent)) {
        // Deleting 1 char didn't crash; don't try to delete anymore starting
        // here.
        offset++;
        continue;
      }

      // Find how long we can go.
      int crashingAt = 1;
      int? noLongerCrashingAt;
      while (true) {
        int deleteChars = 2 * crashingAt;
        if (offset + deleteChars > latestCrashData.length) {
          deleteChars = latestCrashData.length - offset;
        }
        builder = new BytesBuilder();
        builder.add(_sublist(latestCrashData, 0, offset));
        builder.add(_sublist(
            latestCrashData, offset + deleteChars, latestCrashData.length));
        candidate = builder.takeBytes();
        _fs.data[uri] = candidate;
        if (!await _crashesOnCompile(initialComponent)) {
          noLongerCrashingAt = deleteChars;
          break;
        }
        crashingAt = deleteChars;
        if (crashingAt + offset == latestCrashData.length) break;
      }

      if (noLongerCrashingAt == null) {
        // We can delete the rest.
        latestCrashData = candidate;
        continue;
      }

      // Binary search between [crashingAt] and [noLongerCrashingAt].
      while (crashingAt < noLongerCrashingAt!) {
        int mid = noLongerCrashingAt -
            ((noLongerCrashingAt - crashingAt) >>
                1); // Get middle, rounding up.
        builder = new BytesBuilder();
        builder.add(_sublist(latestCrashData, 0, offset));
        builder.add(
            _sublist(latestCrashData, offset + mid, latestCrashData.length));
        candidate = builder.takeBytes();
        _fs.data[uri] = candidate;
        if (await _crashesOnCompile(initialComponent)) {
          crashingAt = mid;
        } else {
          // [noLongerCrashingAt] might actually crash now.
          noLongerCrashingAt = mid - 1;
        }
      }

      // This is basically an assert.
      builder = new BytesBuilder();
      builder.add(_sublist(latestCrashData, 0, offset));
      builder.add(_sublist(
          latestCrashData, offset + crashingAt, latestCrashData.length));
      candidate = builder.takeBytes();
      _fs.data[uri] = candidate;
      if (!await _crashesOnCompile(initialComponent)) {
        throw "Error in binary search.";
      }
      latestCrashData = candidate;
    }

    _fs.data[uri] = latestCrashData;
  }

  Future<void> _tryToRemoveUnreferencedFileContent(Component initialComponent,
      {bool deleteFile: false}) async {
    // Check if there now are any unused files.
    if (_latestComponent == null) return;
    Set<Uri> neededUris = _latestComponent!.uriToSource.keys.toSet();
    Map<Uri, Uint8List> copy = new Map.from(_fs.data);
    bool removedSome = false;
    if (await _shouldQuit()) return;
    for (MapEntry<Uri?, Uint8List?> entry in _fs.data.entries) {
      if (entry.value == null) continue;
      if (!deleteFile && entry.value!.isEmpty) continue;
      if (!entry.key.toString().endsWith(".dart")) continue;
      if (!neededUris.contains(entry.key) &&
          (deleteFile || _fs.data[entry.key]!.length != 0)) {
        if (deleteFile) {
          _fs.data[entry.key] = null;
        } else {
          _fs.data[entry.key] = new Uint8List(0);
        }
        print(" => Can probably also delete ${entry.key}");
        removedSome = true;
      }
    }
    if (removedSome) {
      if (await _crashesOnCompile(initialComponent)) {
        print(" => Yes; Could remove those too!");
      } else {
        print(" => No; Couldn't remove those too!");
        _fs.data.clear();
        _fs.data.addAll(copy);
      }
    }
  }

  Future<void> _deleteContent(
      List<Uri> uris, int uriIndex, bool limitTo1, Component initialComponent,
      {bool deleteFile: false}) async {
    String extraMessageText = "all content of ";
    if (deleteFile) extraMessageText = "";

    if (!limitTo1) {
      if (await _shouldQuit()) return;
      Map<Uri, Uint8List> copy = new Map.from(_fs.data);
      // Try to remove content of i and the next 9 (10 files in total).
      for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
        Uri uri = uris[j];
        if (deleteFile) {
          _fs.data[uri] = null;
        } else {
          _fs.data[uri] = new Uint8List(0);
        }
      }
      if (!await _crashesOnCompile(initialComponent)) {
        // Couldn't delete all 10 files. Restore and try the single one.
        _fs.data.clear();
        _fs.data.addAll(copy);
      } else {
        for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
          Uri uri = uris[j];
          print("Can delete ${extraMessageText}file $uri");
        }
        await _tryToRemoveUnreferencedFileContent(initialComponent,
            deleteFile: deleteFile);
        return;
      }
    }

    if (await _shouldQuit()) return;
    Uri uri = uris[uriIndex];
    Uint8List? data = _fs.data[uri];
    if (deleteFile) {
      _fs.data[uri] = null;
    } else {
      _fs.data[uri] = new Uint8List(0);
    }
    if (!await _crashesOnCompile(initialComponent)) {
      print(
          "Can't delete ${extraMessageText}file $uri -- keeping it (for now)");
      _fs.data[uri] = data;

      // For dart files we can't truncate completely try to "outline" them
      // instead.
      if (uri.toString().endsWith(".dart")) {
        String? textualOutlined =
            textualOutline(data!, _getScannerConfiguration(uri))
                ?.replaceAll(RegExp(r'\n+'), "\n");

        bool outlined = false;
        if (textualOutlined != null) {
          Uint8List candidate = utf8.encode(textualOutlined) as Uint8List;
          // Because textual outline doesn't do the right thing for nnbd, only
          // replace if it's syntactically valid.
          if (candidate.length != _fs.data[uri]!.length &&
              _parsesWithoutError(candidate, _isUriNnbd(uri))) {
            if (await _shouldQuit()) return;
            _fs.data[uri] = candidate;
            if (!await _crashesOnCompile(initialComponent)) {
              print("Can't outline the file $uri -- keeping it (for now)");
              _fs.data[uri] = data;
            } else {
              outlined = true;
              print("Can outline the file $uri "
                  "(now ${_fs.data[uri]!.length} bytes)");
            }
          }
        }
        if (!outlined) {
          // We can probably at least remove all comments then...
          try {
            List<String> strings = utf8.decode(_fs.data[uri]!).split("\n");
            List<String> stringsLeft = [];
            for (String string in strings) {
              if (!string.trim().startsWith("//")) stringsLeft.add(string);
            }

            Uint8List candidate =
                utf8.encode(stringsLeft.join("\n")) as Uint8List;
            if (candidate.length != _fs.data[uri]!.length) {
              if (await _shouldQuit()) return;
              _fs.data[uri] = candidate;
              if (!await _crashesOnCompile(initialComponent)) {
                print("Can't remove comments for file $uri -- "
                    "keeping it (for now)");
                _fs.data[uri] = data;
              } else {
                print("Removed comments for the file $uri");
              }
            }
          } catch (e) {
            // crash in scanner/parser --- keep original file. This crash might
            // be what we're looking for!
          }
        }
      }
    } else {
      print("Can delete ${extraMessageText}file $uri");
      await _tryToRemoveUnreferencedFileContent(initialComponent);
    }
  }

  Future<void> _deleteBlocksOld(Uri uri, Component initialComponent) async {
    if (uri.toString().endsWith(".json")) {
      // Try to find annoying
      //
      //    },
      //    {
      //    }
      //
      // part of json and remove it.
      Uint8List data = _fs.data[uri]!;
      String string = utf8.decode(data);
      List<String> lines = string.split("\n");
      for (int i = 0; i < lines.length - 2; i++) {
        if (lines[i].trim() == "}," &&
            lines[i + 1].trim() == "{" &&
            lines[i + 2].trim() == "}") {
          // This is the pattern we wanted to find. Remove it.
          lines.removeRange(i, i + 2);
          i--;
        }
      }
      string = lines.join("\n");
      _fs.data[uri] = utf8.encode(string) as Uint8List;
      if (!await _crashesOnCompile(initialComponent)) {
        // For some reason that didn't work.
        _fs.data[uri] = data;
      }
    }
    if (!uri.toString().endsWith(".dart")) return;

    Uint8List data = _fs.data[uri]!;
    Uint8List latestCrashData = data;

    List<int> lineStarts = [];

    Token firstToken = parser_suite.scanRawBytes(
        data,
        _isUriNnbd(uri) ? _scannerConfiguration : _scannerConfigurationNonNNBD,
        lineStarts);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      print("Got null token from scanner for $uri");
      return;
    }

    int compileTry = 0;
    Token? token = firstToken;
    while (token is ErrorToken) {
      token = token.next;
    }
    List<_Replacement> replacements = [];
    while (token != null && !token.isEof) {
      bool tryCompile = false;
      Token skipToToken = token;
      // Skip very small blocks (e.g. "{}" or "{\n}");
      if (token.endGroup != null && token.offset + 3 < token.endGroup!.offset) {
        replacements
            .add(new _Replacement(token.offset, token.endGroup!.offset));
        tryCompile = true;
        skipToToken = token.endGroup!;
      } else if (token.lexeme == "@") {
        if (token.next!.next!.endGroup != null) {
          int end = token.next!.next!.endGroup!.offset;
          skipToToken = token.next!.next!.endGroup!;
          replacements.add(new _Replacement(token.offset - 1, end + 1));
          tryCompile = true;
        }
      } else if (token.lexeme == "assert") {
        if (token.next!.endGroup != null) {
          int end = token.next!.endGroup!.offset;
          skipToToken = token.next!.endGroup!;
          if (token.next!.endGroup!.next!.lexeme == ",") {
            end = token.next!.endGroup!.next!.offset;
            skipToToken = token.next!.endGroup!.next!;
          }
          // +/- 1 to not include the start and the end character.
          replacements.add(new _Replacement(token.offset - 1, end + 1));
          tryCompile = true;
        }
      } else if ((token.lexeme == "abstract" &&
              token.next!.lexeme == "class") ||
          token.lexeme == "class" ||
          token.lexeme == "enum" ||
          token.lexeme == "mixin" ||
          token.lexeme == "static" ||
          token.next!.lexeme == "get" ||
          token.next!.lexeme == "set" ||
          token.next!.next!.lexeme == "(" ||
          (token.next!.lexeme == "<" &&
              token.next!.endGroup != null &&
              token.next!.endGroup!.next!.next!.lexeme == "(")) {
        // Try to find and remove the entire class/enum/mixin/
        // static procedure/getter/setter/simple procedure.
        Token bracket = token;
        for (int i = 0; i < 20; i++) {
          // Find "{", but only go a maximum of 20 tokens to do that.
          bracket = bracket.next!;
          if (bracket.lexeme == "{" && bracket.endGroup != null) {
            break;
          } else if ((bracket.lexeme == "(" || bracket.lexeme == "<") &&
              bracket.endGroup != null) {
            bracket = bracket.endGroup!;
          }
        }
        if (bracket.lexeme == "{" && bracket.endGroup != null) {
          int end = bracket.endGroup!.offset;
          skipToToken = bracket.endGroup!;
          // +/- 1 to not include the start and the end character.
          replacements.add(new _Replacement(token.offset - 1, end + 1));
          tryCompile = true;
        }
      }

      if (tryCompile) {
        if (await _shouldQuit()) break;
        if (_skip) {
          _skip = false;
          break;
        }
        stdout.write(".");
        compileTry++;
        if (compileTry % 50 == 0) {
          stdout.write("(at $compileTry)\n");
        }
        Uint8List candidate = _replaceRange(replacements, data);
        _fs.data[uri] = candidate;
        if (await _crashesOnCompile(initialComponent)) {
          print("Found block from "
              "${replacements.last.from} to "
              "${replacements.last.to} "
              "that can be removed.");
          latestCrashData = candidate;
          token = skipToToken;
        } else {
          // Couldn't delete that.
          replacements.removeLast();
        }
      }
      token = token.next;
    }
    _fs.data[uri] = latestCrashData;
  }

  Future<void> _deleteBlocks(final Uri uri, Component initialComponent) async {
    if (uri.toString().endsWith(".json")) {
      // Try to find annoying
      //
      //    },
      //    {
      //    }
      //
      // part of json and remove it.
      Uint8List data = _fs.data[uri]!;
      String string = utf8.decode(data);
      List<String> lines = string.split("\n");
      for (int i = 0; i < lines.length - 2; i++) {
        if (lines[i].trim() == "}," &&
            lines[i + 1].trim() == "{" &&
            lines[i + 2].trim() == "}") {
          // This is the pattern we wanted to find. Remove it.
          lines.removeRange(i, i + 2);
          i--;
        }
      }
      string = lines.join("\n");
      Uint8List candidate = utf8.encode(string) as Uint8List;
      if (candidate.length != data.length) {
        _fs.data[uri] = candidate;
        if (!await _crashesOnCompile(initialComponent)) {
          // For some reason that didn't work.
          _fs.data[uri] = data;
        }
      }

      // Try to load json and remove blocks.
      try {
        Map json = jsonDecode(utf8.decode(data));
        Map jsonModified = new Map.from(json);
        List packages = json["packages"];
        List packagesModified = new List.from(packages);
        jsonModified["packages"] = packagesModified;
        int i = 0;
        print("Note there's ${packagesModified.length} packages in .json");
        JsonEncoder jsonEncoder = new JsonEncoder.withIndent("  ");
        while (i < packagesModified.length) {
          var oldEntry = packagesModified.removeAt(i);
          String jsonString = jsonEncoder.convert(jsonModified);
          candidate = utf8.encode(jsonString) as Uint8List;
          Uint8List? previous = _fs.data[uri];
          _fs.data[uri] = candidate;
          if (!await _crashesOnCompile(initialComponent)) {
            // Couldn't remove that part.
            _fs.data[uri] = previous;
            packagesModified.insert(i, oldEntry);
            i++;
          } else {
            print("Removed package from .json "
                "(${packagesModified.length} left).");
          }
        }
      } catch (e) {
        // Couldn't decode it, so don't try to do anything.
      }
      return;
    }
    if (!uri.toString().endsWith(".dart")) return;

    Uint8List data = _fs.data[uri]!;
    DirectParserASTContentCompilationUnitEnd ast = getAST(data,
        includeBody: true,
        includeComments: false,
        enableExtensionMethods: true,
        enableNonNullable: _isUriNnbd(uri));

    _CompilationHelperClass helper = new _CompilationHelperClass(data);

    // Try to remove top level things one at a time.
    for (DirectParserASTContent child in ast.children!) {
      bool shouldCompile = false;
      String what = "";
      if (child.isClass()) {
        DirectParserASTContentClassDeclarationEnd cls = child.asClass();
        helper.replacements.add(new _Replacement(
            cls.beginToken.offset - 1, cls.endToken.offset + 1));
        shouldCompile = true;
        what = "class";
      } else if (child.isMixinDeclaration()) {
        DirectParserASTContentMixinDeclarationEnd decl =
            child.asMixinDeclaration();
        helper.replacements.add(new _Replacement(
            decl.mixinKeyword.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "mixin";
      } else if (child.isNamedMixinDeclaration()) {
        DirectParserASTContentNamedMixinApplicationEnd decl =
            child.asNamedMixinDeclaration();
        helper.replacements.add(
            new _Replacement(decl.begin.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "named mixin";
      } else if (child.isExtension()) {
        DirectParserASTContentExtensionDeclarationEnd decl =
            child.asExtension();
        helper.replacements.add(new _Replacement(
            decl.extensionKeyword.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "extension";
      } else if (child.isTopLevelFields()) {
        DirectParserASTContentTopLevelFieldsEnd decl = child.asTopLevelFields();
        helper.replacements.add(new _Replacement(
            decl.beginToken.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "toplevel fields";
      } else if (child.isTopLevelMethod()) {
        DirectParserASTContentTopLevelMethodEnd decl = child.asTopLevelMethod();
        helper.replacements.add(new _Replacement(
            decl.beginToken.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "toplevel method";
      } else if (child.isEnum()) {
        DirectParserASTContentEnumEnd decl = child.asEnum();
        helper.replacements.add(new _Replacement(
            decl.enumKeyword.offset - 1, decl.leftBrace.endGroup!.offset + 1));
        shouldCompile = true;
        what = "enum";
      } else if (child.isTypedef()) {
        DirectParserASTContentFunctionTypeAliasEnd decl = child.asTypedef();
        helper.replacements.add(new _Replacement(
            decl.typedefKeyword.offset - 1, decl.endToken.offset + 1));
        shouldCompile = true;
        what = "typedef";
      } else if (child.isMetadata()) {
        DirectParserASTContentMetadataStarEnd decl = child.asMetadata();
        List<DirectParserASTContentMetadataEnd> metadata =
            decl.getMetadataEntries();
        if (metadata.isNotEmpty) {
          helper.replacements.add(new _Replacement(
              metadata.first.beginToken.offset - 1,
              metadata.last.endToken.offset));
          shouldCompile = true;
        }
        what = "metadata";
      } else if (child.isImport()) {
        DirectParserASTContentImportEnd decl = child.asImport();
        helper.replacements.add(new _Replacement(
            decl.importKeyword.offset - 1, decl.semicolon!.offset + 1));
        shouldCompile = true;
        what = "import";
      } else if (child.isExport()) {
        DirectParserASTContentExportEnd decl = child.asExport();
        helper.replacements.add(new _Replacement(
            decl.exportKeyword.offset - 1, decl.semicolon.offset + 1));
        shouldCompile = true;
        what = "export";
      } else if (child.isLibraryName()) {
        DirectParserASTContentLibraryNameEnd decl = child.asLibraryName();
        helper.replacements.add(new _Replacement(
            decl.libraryKeyword.offset - 1, decl.semicolon.offset + 1));
        shouldCompile = true;
        what = "library name";
      } else if (child.isPart()) {
        DirectParserASTContentPartEnd decl = child.asPart();
        helper.replacements.add(new _Replacement(
            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
        shouldCompile = true;
        what = "part";
      } else if (child.isPartOf()) {
        DirectParserASTContentPartOfEnd decl = child.asPartOf();
        helper.replacements.add(new _Replacement(
            decl.partKeyword.offset - 1, decl.semicolon.offset + 1));
        shouldCompile = true;
        what = "part of";
      } else if (child.isScript()) {
        var decl = child.asScript();
        helper.replacements.add(new _Replacement(
            decl.token.offset - 1, decl.token.offset + decl.token.length));
        shouldCompile = true;
        what = "script";
      }

      if (shouldCompile) {
        bool success =
            await _tryReplaceAndCompile(helper, uri, initialComponent, what);
        if (helper.shouldQuit) return;
        if (!success) {
          if (child.isClass()) {
            // Also try to remove all content of the class.
            DirectParserASTContentClassDeclarationEnd decl = child.asClass();
            DirectParserASTContentClassOrMixinBodyEnd body =
                decl.getClassOrMixinBody();
            if (body.beginToken.offset + 2 < body.endToken.offset) {
              helper.replacements.add(new _Replacement(
                  body.beginToken.offset, body.endToken.offset));
              what = "class body";
              success = await _tryReplaceAndCompile(
                  helper, uri, initialComponent, what);
              if (helper.shouldQuit) return;
            }

            if (!success) {
              // Also try to remove members one at a time.
              for (DirectParserASTContent child in body.children!) {
                shouldCompile = false;
                if (child is DirectParserASTContentMemberEnd) {
                  if (child.isClassConstructor()) {
                    DirectParserASTContentClassConstructorEnd memberDecl =
                        child.getClassConstructor();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "class constructor";
                    shouldCompile = true;
                  } else if (child.isClassFields()) {
                    DirectParserASTContentClassFieldsEnd memberDecl =
                        child.getClassFields();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "class fields";
                    shouldCompile = true;
                  } else if (child.isClassMethod()) {
                    DirectParserASTContentClassMethodEnd memberDecl =
                        child.getClassMethod();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "class method";
                    shouldCompile = true;
                  } else if (child.isClassFactoryMethod()) {
                    DirectParserASTContentClassFactoryMethodEnd memberDecl =
                        child.getClassFactoryMethod();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "class factory method";
                    shouldCompile = true;
                  } else {
                    // throw "$child --- ${child.children}";
                    continue;
                  }
                } else if (child.isMetadata()) {
                  DirectParserASTContentMetadataStarEnd decl =
                      child.asMetadata();
                  List<DirectParserASTContentMetadataEnd> metadata =
                      decl.getMetadataEntries();
                  if (metadata.isNotEmpty) {
                    helper.replacements.add(new _Replacement(
                        metadata.first.beginToken.offset - 1,
                        metadata.last.endToken.offset));
                    shouldCompile = true;
                  }
                  what = "metadata";
                }
                if (shouldCompile) {
                  success = await _tryReplaceAndCompile(
                      helper, uri, initialComponent, what);
                  if (helper.shouldQuit) return;
                  if (!success) {
                    DirectParserASTContentBlockFunctionBodyEnd? decl;
                    if (child is DirectParserASTContentMemberEnd) {
                      if (child.isClassMethod()) {
                        decl = child.getClassMethod().getBlockFunctionBody();
                      } else if (child.isClassConstructor()) {
                        decl =
                            child.getClassConstructor().getBlockFunctionBody();
                      }
                    }
                    if (decl != null &&
                        decl.beginToken.offset + 2 < decl.endToken.offset) {
                      helper.replacements.add(new _Replacement(
                          decl.beginToken.offset, decl.endToken.offset));
                      what = "class member content";
                      await _tryReplaceAndCompile(
                          helper, uri, initialComponent, what);
                      if (helper.shouldQuit) return;
                    }
                  }
                }
              }
            }

            // Try to remove "extends", "implements" etc.
            // TODO(jensj): The below removes from the "extends" (etc) until
            // (but excluding) the "{". This should be improved so it can remove
            // _one_ part at a time. E:g. if it says "class A implements B, C {"
            // we could try to remove "B, " or ", C" etc.
            if (decl.getClassExtends().extendsKeyword != null) {
              helper.replacements.add(new _Replacement(
                  decl.getClassExtends().extendsKeyword!.offset - 1,
                  body.beginToken.offset));
              what = "class extends";
              success = await _tryReplaceAndCompile(
                  helper, uri, initialComponent, what);
              if (helper.shouldQuit) return;
            }
            if (decl.getClassImplements().implementsKeyword != null) {
              helper.replacements.add(new _Replacement(
                  decl.getClassImplements().implementsKeyword!.offset - 1,
                  body.beginToken.offset));
              what = "class implements";
              success = await _tryReplaceAndCompile(
                  helper, uri, initialComponent, what);
              if (helper.shouldQuit) return;
            }
            if (decl.getClassWithClause() != null) {
              helper.replacements.add(new _Replacement(
                  decl.getClassWithClause()!.withKeyword.offset - 1,
                  body.beginToken.offset));
              what = "class with clause";
              success = await _tryReplaceAndCompile(
                  helper, uri, initialComponent, what);
              if (helper.shouldQuit) return;
            }
          } else if (child.isMixinDeclaration()) {
            // Also try to remove all content of the mixin.
            DirectParserASTContentMixinDeclarationEnd decl =
                child.asMixinDeclaration();
            DirectParserASTContentClassOrMixinBodyEnd body =
                decl.getClassOrMixinBody();
            if (body.beginToken.offset + 2 < body.endToken.offset) {
              helper.replacements.add(new _Replacement(
                  body.beginToken.offset, body.endToken.offset));
              what = "mixin body";
              success = await _tryReplaceAndCompile(
                  helper, uri, initialComponent, what);
              if (helper.shouldQuit) return;
            }

            if (!success) {
              // Also try to remove members one at a time.
              for (DirectParserASTContent child in body.children!) {
                shouldCompile = false;
                if (child is DirectParserASTContentMemberEnd) {
                  if (child.isMixinConstructor()) {
                    DirectParserASTContentMixinConstructorEnd memberDecl =
                        child.getMixinConstructor();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "mixin constructor";
                    shouldCompile = true;
                  } else if (child.isMixinFields()) {
                    DirectParserASTContentMixinFieldsEnd memberDecl =
                        child.getMixinFields();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "mixin fields";
                    shouldCompile = true;
                  } else if (child.isMixinMethod()) {
                    DirectParserASTContentMixinMethodEnd memberDecl =
                        child.getMixinMethod();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "mixin method";
                    shouldCompile = true;
                  } else if (child.isMixinFactoryMethod()) {
                    DirectParserASTContentMixinFactoryMethodEnd memberDecl =
                        child.getMixinFactoryMethod();
                    helper.replacements.add(new _Replacement(
                        memberDecl.beginToken.offset - 1,
                        memberDecl.endToken.offset + 1));
                    what = "mixin factory method";
                    shouldCompile = true;
                  } else {
                    // throw "$child --- ${child.children}";
                    continue;
                  }
                } else if (child.isMetadata()) {
                  DirectParserASTContentMetadataStarEnd decl =
                      child.asMetadata();
                  List<DirectParserASTContentMetadataEnd> metadata =
                      decl.getMetadataEntries();
                  if (metadata.isNotEmpty) {
                    helper.replacements.add(new _Replacement(
                        metadata.first.beginToken.offset - 1,
                        metadata.last.endToken.offset));
                    shouldCompile = true;
                  }
                  what = "metadata";
                }
                if (shouldCompile) {
                  success = await _tryReplaceAndCompile(
                      helper, uri, initialComponent, what);
                  if (helper.shouldQuit) return;
                  if (!success) {
                    DirectParserASTContentBlockFunctionBodyEnd? decl;
                    if (child is DirectParserASTContentMemberEnd) {
                      if (child.isClassMethod()) {
                        decl = child.getClassMethod().getBlockFunctionBody();
                      } else if (child.isClassConstructor()) {
                        decl =
                            child.getClassConstructor().getBlockFunctionBody();
                      }
                    }
                    if (decl != null &&
                        decl.beginToken.offset + 2 < decl.endToken.offset) {
                      helper.replacements.add(new _Replacement(
                          decl.beginToken.offset, decl.endToken.offset));
                      what = "class member content";
                      await _tryReplaceAndCompile(
                          helper, uri, initialComponent, what);
                      if (helper.shouldQuit) return;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  Future<bool> _tryReplaceAndCompile(_CompilationHelperClass data, Uri uri,
      Component initialComponent, String what) async {
    if (await _shouldQuit()) {
      data.shouldQuit = true;
      return false;
    }
    stdout.write(".");
    data.compileTry++;
    if (data.compileTry % 50 == 0) {
      stdout.write("(at ${data.compileTry})\n");
    }
    Uint8List candidate = _replaceRange(data.replacements, data.originalData);

    if (!_parsesWithoutError(candidate, _isUriNnbd(uri))) {
      print("WARNING: Parser error after stuff at ${StackTrace.current}");
      _parsesWithoutError(candidate, _isUriNnbd(uri));
      _parsesWithoutError(data.originalData, _isUriNnbd(uri));
    }

    _fs.data[uri] = candidate;
    if (await _crashesOnCompile(initialComponent)) {
      print("Found $what from "
          "${data.replacements.last.from} to "
          "${data.replacements.last.to} "
          "that can be removed.");
      data.latestCrashData = candidate;
      return true;
    } else {
      // Couldn't delete that.
      data.replacements.removeLast();
      _fs.data[uri] = data.latestCrashData;
      return false;
    }
  }

  Future<void> _deleteEmptyLines(Uri uri, Component initialComponent) async {
    Uint8List data = _fs.data[uri]!;
    List<Uint8List> lines = [];
    int start = 0;
    for (int i = 0; i < data.length; i++) {
      if (data[i] == _$LF) {
        if (i - start > 0) {
          lines.add(_sublist(data, start, i));
        }
        start = i + 1;
      }
    }
    if (data.length - start > 0) {
      lines.add(_sublist(data, start, data.length));
    }

    final BytesBuilder builder = new BytesBuilder();
    for (int j = 0; j < lines.length; j++) {
      if (builder.isNotEmpty) {
        builder.addByte(_$LF);
      }
      builder.add(lines[j]);
    }
    Uint8List candidate = builder.takeBytes();
    if (candidate.length == data.length) return;

    if (uri.path.endsWith(".dart") &&
        !_parsesWithoutError(candidate, _isUriNnbd(uri))) {
      print("WARNING: Parser error after stuff at ${StackTrace.current}");
    }

    if (await _shouldQuit()) return;
    _fs.data[uri] = candidate;
    if (!await _crashesOnCompile(initialComponent)) {
      // For some reason the empty lines are important.
      _fs.data[uri] = data;
    } else {
      print("\nDeleted empty lines.");
    }
  }

  Future<void> _deleteLines(Uri uri, Component initialComponent) async {
    // Try to delete "lines".
    Uint8List data = _fs.data[uri]!;
    List<Uint8List> lines = [];
    int start = 0;
    for (int i = 0; i < data.length; i++) {
      if (data[i] == _$LF) {
        lines.add(_sublist(data, start, i));
        start = i + 1;
      }
    }
    lines.add(_sublist(data, start, data.length));
    List<bool> include = new List.filled(lines.length, true);
    Uint8List latestCrashData = data;
    int length = 1;
    int i = 0;
    while (i < lines.length) {
      if (await _shouldQuit()) break;
      if (_skip) {
        _skip = false;
        break;
      }
      stdout.write(".");
      if (i % 50 == 0) {
        stdout.write("(at $i of ${lines.length})\n");
      }
      if (i + length > lines.length) {
        length = lines.length - i;
      }
      for (int j = i; j < i + length; j++) {
        include[j] = false;
      }
      final BytesBuilder builder = new BytesBuilder();
      for (int j = 0; j < lines.length; j++) {
        if (include[j]) {
          if (builder.isNotEmpty) {
            builder.addByte(_$LF);
          }
          builder.add(lines[j]);
        }
      }
      Uint8List candidate = builder.takeBytes();
      _fs.data[uri] = candidate;
      if (!await _crashesOnCompile(initialComponent)) {
        // Didn't crash => Can't remove line i-j.
        for (int j = i; j < i + length; j++) {
          include[j] = true;
        }
        if (length > 2) {
          // Retry with length 2 at same i.
          // The idea here is that for instance formatted json might have lines
          // looking like
          // {
          // }
          // where deleting just one line makes it invalid.
          length = 2;
        } else if (length > 1) {
          // Retry with length 1 at same i.
          length = 1;
        } else {
          // Couldn't with length 1 either.
          i++;
        }
      } else {
        print("\nCan delete line $i (inclusive) - ${i + length} (exclusive) "
            "(of ${lines.length})");
        latestCrashData = candidate;
        i += length;
        length *= 2;
      }
    }
    _fs.data[uri] = latestCrashData;
  }

  Future<bool> _tryRemoveIfNotKnownByCompiler(
      Uri? uri, initialComponent) async {
    if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) return false;
    if (!uri.toString().endsWith(".dart")) return false;

    if (_knownByCompiler(uri!)) return false;

    // Compiler might not know this. Can we delete it?
    await _deleteContent([uri], 0, true, initialComponent);
    if (_fs.data[uri] == null || _fs.data[uri]!.isEmpty) {
      await _deleteContent([uri], 0, true, initialComponent, deleteFile: true);
      return true;
    }

    return false;
  }

  bool _knownByCompiler(Uri uri) {
    LibraryBuilder? libraryBuilder = _latestCrashingIncrementalCompiler!
        .userCode!.loader.builders[_getImportUri(uri)];
    if (libraryBuilder != null) {
      return true;
    }
    // TODO(jensj): Parts.
    return false;
  }

  ScannerConfiguration _getScannerConfiguration(Uri uri) {
    return new ScannerConfiguration(
        enableExtensionMethods: true,
        enableNonNullable: _isUriNnbd(uri, crashOnFail: false),
        enableTripleShift: false);
  }

  bool _isUriNnbd(Uri uri, {bool crashOnFail: true}) {
    Uri asImportUri = _getImportUri(uri);
    LibraryBuilder? libraryBuilder = _latestCrashingIncrementalCompiler!
        .userCode!.loader.builders[asImportUri];
    if (libraryBuilder != null) {
      return libraryBuilder.isNonNullableByDefault;
    }
    print("Couldn't lookup $uri");
    for (LibraryBuilder libraryBuilder in _latestCrashingIncrementalCompiler!
        .userCode!.loader.builders.values) {
      if (libraryBuilder.importUri == uri) {
        print("Found $uri as ${libraryBuilder.importUri} (!= ${asImportUri})");
        return libraryBuilder.isNonNullableByDefault;
      }
      // Check parts too.
      for (LibraryPart part in libraryBuilder.library.parts) {
        Uri thisPartUri = libraryBuilder.importUri.resolve(part.partUri);
        if (thisPartUri == uri || thisPartUri == asImportUri) {
          print("Found $uri as part of ${libraryBuilder.importUri}");
          return libraryBuilder.isNonNullableByDefault;
        }
      }
    }
    if (crashOnFail) {
      throw "Couldn't lookup $uri at all!";
    } else {
      return false;
    }
  }

  Future<bool> _crashesOnCompile(Component initialComponent) async {
    IncrementalCompiler incrementalCompiler;
    _gotWantedError = false;
    bool didNotGetWantedErrorAfterFirstCompile = true;
    if (_settings.noPlatform) {
      incrementalCompiler = new IncrementalCompiler(_setupCompilerContext());
    } else {
      incrementalCompiler = new IncrementalCompiler.fromComponent(
          _setupCompilerContext(), initialComponent);
    }
    incrementalCompiler.invalidate(_mainUri);
    try {
      _latestComponent = await incrementalCompiler.computeDelta();
      if (_settings.serialize) {
        // We're asked to serialize, probably because it crashes in
        // serialization.
        ByteSink sink = new ByteSink();
        BinaryPrinter printer = new BinaryPrinter(sink);
        printer.writeComponentFile(_latestComponent!);
      }

      if (_gotWantedError) didNotGetWantedErrorAfterFirstCompile = false;

      for (Uri uri in _settings.invalidate) {
        incrementalCompiler.invalidate(uri);
        Component delta = await incrementalCompiler.computeDelta();
        if (_settings.serialize) {
          // We're asked to serialize, probably because it crashes in
          // serialization.
          ByteSink sink = new ByteSink();
          BinaryPrinter printer = new BinaryPrinter(sink);
          printer.writeComponentFile(delta);
          sink.builder.takeBytes();
        }
      }
      if (_settings.lookForErrorErrorOnReload != null &&
          _gotWantedError &&
          didNotGetWantedErrorAfterFirstCompile) {
        // We throw here so the "compile crashes"... This is looking for
        // crashes after-all :)
        throw "Got the wanted error!";
      }
      _latestComponent = null; // if it didn't crash this isn't relevant.
      return false;
    } catch (e, st) {
      // Find line with #0 in it.
      String eWithSt = "$e\n\n$st";
      List<String> lines = eWithSt.split("\n");
      String foundLine = "";
      int lookFor = 0;
      for (String line in lines) {
        if (line.startsWith("#$lookFor")) {
          foundLine += line;
          lookFor++;
          if (lookFor >= _settings.stackTraceMatches) {
            break;
          } else {
            foundLine += "\n";
          }
        }
      }
      // ignore: unnecessary_null_comparison
      if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
      if (_expectedCrashLine == null) {
        print("Got '$foundLine'");
        _expectedCrashLine = foundLine;
        _latestCrashingIncrementalCompiler = incrementalCompiler;
        return true;
      } else if (foundLine == _expectedCrashLine) {
        _latestCrashingIncrementalCompiler = incrementalCompiler;
        return true;
      } else {
        if (_settings.autoUncoverAllCrashes &&
            !_settings.allAutoRedirects.contains(foundLine)) {
          print("Crashed, but another place: $foundLine");
          print(" ==> Adding to auto redirects!");
          // Add the current one too, so we don't rediscover that one once we
          // try minimizing the new ones.
          _settings.allAutoRedirects.add(_expectedCrashLine!);
          _settings.allAutoRedirects.add(foundLine);
          _settings.fileSystems.add(_fs.toJson());
        } else if (_settings.askAboutRedirectCrashTarget &&
            !_settings.askedAboutRedirect.contains(foundLine)) {
          print("Crashed, but another place: $foundLine");
          while (true) {
            // Add the current one too, so we don't rediscover that again
            // and asks about going back to it.
            _settings.askedAboutRedirect.add(_expectedCrashLine!);
            _settings.askedAboutRedirect.add(foundLine);
            print(eWithSt);
            print("Should we redirect to searching for that? (y/n)");
            String answer = stdin.readLineSync()!;
            if (answer == "yes" || answer == "y") {
              _expectedCrashLine = foundLine;
              _latestCrashingIncrementalCompiler = incrementalCompiler;
              return true;
            } else if (answer == "no" || answer == "n") {
              break;
            } else {
              print("Didn't get that answer. "
                  "Please answer 'yes, 'y', 'no' or 'n'");
            }
          }
        }
        return false;
      }
    }
  }

  Future<Component> _getInitialComponent() async {
    IncrementalCompiler incrementalCompiler =
        new IncrementalCompiler(_setupCompilerContext());
    Component originalComponent = await incrementalCompiler.computeDelta();
    return originalComponent;
  }

  CompilerContext _setupCompilerContext() {
    CompilerOptions options = getOptions();

    if (_settings.experimentalInvalidation) {
      options.explicitExperimentalFlags[
          ExperimentalFlag.alternativeInvalidationStrategy] = true;
    }

    TargetFlags targetFlags = new TargetFlags(
        enableNullSafety: false,
        trackWidgetCreation: _settings.widgetTransformation);
    Target target;
    switch (_settings.targetString) {
      case "VM":
        target = new VmTarget(targetFlags);
        break;
      case "flutter":
        target = new FlutterTarget(targetFlags);
        break;
      case "ddc":
        target = new DevCompilerTarget(targetFlags);
        break;
      case "dart2js":
        target = new Dart2jsTarget("dart2js", targetFlags);
        break;
      default:
        throw "Unknown target '${_settings.targetString}'";
    }
    options.target = target;
    options.fileSystem = _fs;
    options.sdkRoot = null;
    options.sdkSummary = _settings.platformUri;
    options.omitPlatform = false;
    options.onDiagnostic = (DiagnosticMessage message) {
      // don't care.
      // Except if we're looking to trigger a specific error on reload.
      if (_settings.lookForErrorErrorOnReload != null &&
          message.ansiFormatted.first
              .contains(_settings.lookForErrorErrorOnReload!)) {
        _gotWantedError = true;
      }
    };
    if (_settings.noPlatform) {
      options.librariesSpecificationUri = null;
    }

    CompilerContext compilerContext = new CompilerContext(
        new ProcessedOptions(options: options, inputs: [_mainUri]));
    return compilerContext;
  }

  String _getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
    List<int> lineStarts = [];

    Token firstToken = parser_suite.scanRawBytes(
        rawBytes,
        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD,
        lineStarts);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      throw "Got null token from scanner";
    }

    ParserTestListener parserTestListener = new ParserTestListener(false);
    Parser parser = new Parser(parserTestListener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    parser.parseUnit(firstToken);
    String parsedString =
        parser_suite.tokenStreamToString(firstToken, lineStarts).toString();
    return parsedString;
  }

  bool _parsesWithoutError(Uint8List rawBytes, bool nnbd) {
    Token firstToken = parser_suite.scanRawBytes(rawBytes,
        nnbd ? _scannerConfiguration : _scannerConfigurationNonNNBD, null);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      return false;
    }

    ParserErrorListener parserErrorListener = new ParserErrorListener();
    Parser parser = new Parser(parserErrorListener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    parser.parseUnit(firstToken);
    return !parserErrorListener.gotError;
  }

  ScannerConfiguration _scannerConfiguration = new ScannerConfiguration(
      enableTripleShift: true,
      enableExtensionMethods: true,
      enableNonNullable: true);

  ScannerConfiguration _scannerConfigurationNonNNBD = new ScannerConfiguration(
      enableTripleShift: true,
      enableExtensionMethods: true,
      enableNonNullable: false);

  List<int>? _dataCache;
  String? _dataCacheString;

  Uint8List _replaceRange(
      List<_Replacement> unsortedReplacements, Uint8List rawData) {
    // The offsets are character offsets, not byte offsets, so for non-ascii
    // they are not the same so we need to work on the string, not the bytes.
    if (identical(rawData, _dataCache)) {
      // cache up to date.
    } else {
      _dataCache = rawData;
      _dataCacheString = utf8.decode(rawData);
    }

    // The below assumes these are sorted.
    List<_Replacement> sortedReplacements =
        new List<_Replacement>.from(unsortedReplacements)..sort();
    final StringBuffer builder = new StringBuffer();
    int prev = 0;
    for (int i = 0; i < sortedReplacements.length; i++) {
      _Replacement replacement = sortedReplacements[i];
      for (int j = prev; j <= replacement.from; j++) {
        builder.writeCharCode(_dataCacheString!.codeUnitAt(j));
      }
      if (replacement.nullOrReplacement != null) {
        builder.write(replacement.nullOrReplacement);
      }
      prev = replacement.to;
    }
    for (int j = prev; j < _dataCacheString!.length; j++) {
      builder.writeCharCode(_dataCacheString!.codeUnitAt(j));
    }

    Uint8List candidate = utf8.encode(builder.toString()) as Uint8List;
    return candidate;
  }
}

class ParserErrorListener extends Listener {
  bool gotError = false;
  List<Message> messages = [];
  void handleRecoverableError(
      Message message, Token startToken, Token endToken) {
    gotError = true;
    messages.add(message);
  }
}

class _CompilationHelperClass {
  int compileTry = 0;
  bool shouldQuit = false;
  List<_Replacement> replacements = [];
  Uint8List latestCrashData;
  final Uint8List originalData;

  _CompilationHelperClass(this.originalData) : latestCrashData = originalData;
}

class _Replacement implements Comparable<_Replacement> {
  final int from;
  final int to;
  final String? nullOrReplacement;

  _Replacement(this.from, this.to, {this.nullOrReplacement});

  @override
  int compareTo(_Replacement other) {
    return from - other.from;
  }
}

class _FakeFileSystem extends FileSystem {
  bool _redirectAndRecord = true;
  bool _initialized = false;
  final Map<Uri?, Uint8List?> data = {};

  @override
  FileSystemEntity entityForUri(Uri uri) {
    return new _FakeFileSystemEntity(this, uri);
  }

  initializeFromJson(Map<String, dynamic> json) {
    _initialized = true;
    _redirectAndRecord = json['_redirectAndRecord'];
    data.clear();
    List tmp = json['data'];
    for (int i = 0; i < tmp.length; i += 2) {
      Uri? key = tmp[i] == null ? null : Uri.parse(tmp[i]);
      if (tmp[i + 1] == null) {
        data[key] = null;
      } else if (tmp[i + 1] is String) {
        data[key] = utf8.encode(tmp[i + 1]) as Uint8List;
      } else {
        data[key] = Uint8List.fromList(new List<int>.from(tmp[i + 1]));
      }
    }
  }

  Map<String, dynamic> toJson() {
    List tmp = [];
    for (var entry in data.entries) {
      if (entry.value == null) continue;
      tmp.add(entry.key == null ? null : entry.key.toString());
      dynamic out = entry.value;
      if (entry.value != null && entry.value!.isNotEmpty) {
        try {
          String string = utf8.decode(entry.value!);
          out = string;
        } catch (e) {
          // not a string...
        }
      }
      tmp.add(out);
    }
    return {
      '_redirectAndRecord': _redirectAndRecord,
      'data': tmp,
    };
  }
}

class _FakeFileSystemEntity extends FileSystemEntity {
  final _FakeFileSystem fs;
  final Uri uri;
  _FakeFileSystemEntity(this.fs, this.uri);

  void _ensureCachedIfOk() {
    if (fs.data.containsKey(uri)) return;
    if (fs._initialized) return;
    if (!fs._redirectAndRecord) {
      throw "Asked for file in non-recording mode that wasn't known";
    }
    File f = new File.fromUri(uri);
    if (!f.existsSync()) {
      fs.data[uri] = null;
      return;
    }
    fs.data[uri] = f.readAsBytesSync();
  }

  @override
  Future<bool> exists() {
    _ensureCachedIfOk();
    Uint8List? data = fs.data[uri];
    if (data == null) return Future.value(false);
    return Future.value(true);
  }

  @override
  Future<bool> existsAsyncIfPossible() => exists();

  @override
  Future<List<int>> readAsBytes() {
    _ensureCachedIfOk();
    Uint8List? data = fs.data[uri];
    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
    return Future.value(data);
  }

  @override
  Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();

  @override
  Future<String> readAsString() {
    _ensureCachedIfOk();
    Uint8List? data = fs.data[uri];
    if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
    return Future.value(utf8.decode(data));
  }
}

class _DoesntCrashOnInput {
  _DoesntCrashOnInput();
}
