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

import 'package:args/args.dart';

import 'dartfuzz_api_table.dart';
import 'dartfuzz_ffi_api.dart';
import 'dartfuzz_type_table.dart';

// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
const String version = '1.101';

// Restriction on statements and expressions.
const int stmtDepth = 1;
const int exprDepth = 2;
const int nestDepth = 1;
const int numStatements = 2;
const int numGlobalVars = 4;
const int numLocalVars = 4;
const int numGlobalMethods = 4;
const int numMethodParams = 4;
const int numClasses = 4;
const int numExtensionMethodsPerClass = 3;
const int numDartTypeExtensions = 5;

// Naming conventions.
const varName = 'var';
const paramName = 'par';
const localName = 'loc';
const fieldName = 'fld';
const methodName = 'foo';

/// Enum for the different types of methods generated by the fuzzer.
enum MethodType {
  globalMethod,
  ffiMethod,
  instanceMethod,
  callMethod,
  extensionMethod
}

/// Base class for all methods in the program generated by DartFuzz.
abstract class Method {
  Method(this.name, this.parameters, this.fuzzer)
      : recursionAllowed = fuzzer.coinFlip() {
    if (recursionAllowed) {
      // Add the recursion depth parameter.
      parameters.add(DartType.INT);
    }
  }

  String get recursionDepthParamName => '$paramName${parameters.length - 1}';
  DartType get returnType => parameters[0];

  void emitCallParameters(int depth, bool isRecursiveCall,
      {RhsFilter? rhsFilter}) {
    if (isRecursiveCall && !recursionAllowed) {
      throw StateError('Did not expect a recursive call in $name');
    }
    fuzzer.emitParenWrapped(() => fuzzer.emitCommaSeparated((int i) {
          // If this function can be called recursively, the last parameter is the
          // recursion depth parameter.
          if (i == parameters.length - 1 && recursionAllowed) {
            if (isRecursiveCall) {
              // This is a recursive call, so we increase the recursion depth
              // parameter.
              fuzzer.emit('$recursionDepthParamName + 1');
            } else {
              // This isn't a recursive call. Our recursion depth is 0.
              fuzzer.emit('0');
            }
          } else {
            fuzzer.emitExpr(depth, parameters[i], rhsFilter: rhsFilter);
          }
        }, parameters.length, start: 1));
  }

  void disableRecursionScope(Function callback) {
    final originalState = recursionAllowed;
    recursionAllowed = false;
    callback();
    recursionAllowed = originalState;
  }

  void emitRecursionBaseCase() {
    fuzzer.emitIfStatement(() {
      fuzzer.emit('$recursionDepthParamName >= ');
      fuzzer.emitSmallPositiveInt();
    }, () {
      // Temporarily set recursionAllowed to false so that we don't have a
      // recursive call in the return statement of the base case.
      disableRecursionScope(fuzzer.emitReturn);
      return false;
    });
  }

  void emitFunctionBody() {
    if (!recursionAllowed && fuzzer.rollDice(10)) {
      // Emit a method using "=>" syntax.
      fuzzer.emit(' => ');
      fuzzer.emitExpr(0, returnType, includeSemicolon: true);
    } else {
      fuzzer.emitBraceWrapped(() {
        assert(fuzzer.localVars.isEmpty);
        if (recursionAllowed) {
          emitRecursionBaseCase();
        }
        if (fuzzer.emitStatements(0)) {
          fuzzer.emitReturn();
        }
        assert(fuzzer.localVars.isEmpty);
      });
    }
  }

  void emitFunctionAnnotations() {
    if (fuzzer.rollDice(6)) {
      fuzzer.emitLn('@pragma("vm:always-consider-inlining")');
    }
    if (fuzzer.rollDice(6)) {
      fuzzer.emitLn('@pragma("vm:entry-point")');
    }
    if (fuzzer.rollDice(6)) {
      fuzzer.emitLn('@pragma("vm:never-inline")');
    }
    if (fuzzer.rollDice(6)) {
      fuzzer.emitLn('@pragma("vm:prefer-inline")');
    }
    if (fuzzer.rollDice(10)) {
      fuzzer.emit('@pragma(');
      fuzzer.emitString();
      fuzzer.emit(')');
      fuzzer.emitNewline();
    }
  }

  void emitFunctionDefinition() {
    final type = returnType.dartName;
    emitFunctionAnnotations();
    fuzzer.emitLn('$type $name', newline: false);
    fuzzer.emitParenWrapped(() => fuzzer.emitParDecls(parameters));
    emitFunctionBody();
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    var outputName = name;
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  // Main emitter for a method.
  void emit() {
    emitFunctionDefinition();
  }

  final String name;
  final List<DartType> parameters;
  final DartFuzz fuzzer;
  bool recursionAllowed;
}

/// Class for global methods generated by DartFuzz.
class GlobalMethod extends Method {
  GlobalMethod(String name, List<DartType> parameters, DartFuzz fuzzer)
      : super(name, parameters, fuzzer);
}

/// Class for ffi methods generated by DartFuzz.
class FfiMethod extends Method {
  FfiMethod(
      String namePrefix, int index, List<DartType> parameters, DartFuzz fuzzer)
      : ffiCastName = '${namePrefix}FfiCast$index',
        super('${namePrefix}Ffi$index', parameters, fuzzer);

  @override
  void emitFunctionBody() {
    fuzzer.emitBraceWrapped(() {
      assert(fuzzer.localVars.isEmpty);
      if (recursionAllowed) {
        emitRecursionBaseCase();
      }
      if (fuzzer.emitStatements(0)) {
        fuzzer.emitReturn();
      }
      assert(fuzzer.localVars.isEmpty);
    });
  }

  @override
  void emit() {
    fuzzer.emitFfiTypedef(this);
    emitFunctionDefinition();
    fuzzer.emitFfiCast('$ffiCastName', '$name', '${name}Type', parameters);
    fuzzer.emitNewline();
    fuzzer.emitNewline();
  }

  final String ffiCastName;
}

/// Class for instance methods generated by DartFuzz.
class InstanceMethod extends Method {
  InstanceMethod(
      String name, List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super(name, parameters, fuzzer);

  @override
  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    var outputName = name;
    if (fuzzer.currentClassIndex == null) {
      // If we're calling an instance method from outside the class, then we
      // should construct an object of that class first.
      outputName = '$className().$name';
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
}

class CallMethod extends Method {
  CallMethod(List<DartType> parameters, DartFuzz fuzzer, this.className)
      : super('call', parameters, fuzzer);

  @override
  String emitCall(int depth,
      {RhsFilter? rhsFilter,
      bool includeSemicolon = false,
      bool isRecursiveCall = false}) {
    String outputName;
    outputName = '$className()';
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  @override
  void emit() {
    // Override the parent class' call method.
    fuzzer.emit('@override');
    fuzzer.emitNewline();
    emitFunctionDefinition();
  }

  final String className;
}

// Class for extension methods generated by DartFuzz.
class ExtensionMethod extends Method {
  ExtensionMethod(String name, List<DartType> parameters, DartFuzz fuzzer,
      this.className, this.extensionName, this.type)
      : super(name, parameters, fuzzer);
  @override
  String emitCall(
    int depth, {
    RhsFilter? rhsFilter,
    bool includeSemicolon = false,
    bool isRecursiveCall = false,
  }) {
    var outputName = name;

    // If we're calling an extension method on a class from outside the class,
    // we must call it using an object of the class or using explicit extension
    // application. Extension methods on Dart types are presently always called
    // using a variable of the Dart type or using explicit extension
    // application.
    if (fuzzer.currentClassIndex == null || type != null) {
      var invokingObject = type != null
          ? fuzzer.pickScalarVar(type!.toNonNullable())
          : '$className()';

      if (fuzzer.coinFlip()) {
        outputName = '$extensionName($invokingObject).$name';
      } else {
        outputName = '$invokingObject.$name';
      }
    }
    fuzzer.emitLn(outputName, newline: false);
    emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
    if (includeSemicolon) {
      fuzzer.emit(';');
    }
    return outputName;
  }

  final String className;
  final String extensionName;
  final DartType? type;
}

// Class that tracks the state of the filter applied to the
// right-hand-side of an assignment in order to avoid generating
// left-hand-side variables.
class RhsFilter {
  RhsFilter(this._remaining, this.lhsVar);
  static RhsFilter? fromDartType(DartType tp, String lhsVar) {
    if (DartType.isGrowableType(tp)) {
      return RhsFilter(1, lhsVar);
    }
    return null;
  }

  // Clone the current RhsFilter instance and set remaining to 0.
  // This is used for parameter expressions.
  static RhsFilter? cloneEmpty(RhsFilter? rhsFilter) =>
      rhsFilter == null ? null : RhsFilter(0, rhsFilter.lhsVar);
  void consume() => _remaining--;
  bool get shouldFilter => _remaining <= 0;
  // Number of times the lhs variable can still be used on the rhs.
  int _remaining;
  // The name of the lhs variable to be filtered from the rhs.
  final String lhsVar;
}

/// Class that specifies the api for calling library and ffi functions (if
/// enabled).
class DartApi {
  DartApi(bool ffi) : typeToLibraryMethods = DartLib.typeToLibraryMethods {
    if (ffi) {
      typeToLibraryMethods[DartType.INT] = [
        ...[
          DartLib('intComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('takeMaxUint16', [DartType.VOID, DartType.INT], true),
          DartLib(
              'sumPlus42', [DartType.VOID, DartType.INT, DartType.INT], true),
          DartLib('returnMaxUint8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMaxUint32', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt8', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt16', [DartType.VOID, DartType.VOID], true),
          DartLib('returnMinInt32', [DartType.VOID, DartType.VOID], true),
          DartLib('takeMinInt16', [DartType.VOID, DartType.INT], true),
          DartLib('takeMinInt32', [DartType.VOID, DartType.INT], true),
          DartLib('uintComputation',
              [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
          DartLib('sumSmallNumbers',
              [DartType.VOID, ...List<DartType>.filled(6, DartType.INT)], true),
          DartLib('takeMinInt8', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint32', [DartType.VOID, DartType.INT], true),
          DartLib('takeMaxUint8', [DartType.VOID, DartType.INT], true),
          DartLib('minInt64', [DartType.VOID, DartType.VOID], true),
          DartLib('minInt32', [DartType.VOID, DartType.VOID], true),
          // Use small int to avoid overflow divergences due to size
          // differences in intptr_t on 32-bit and 64-bit platforms.
          DartLib('sumManyIntsOdd',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
          DartLib('sumManyInts',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(10, Restriction.small)
              ]),
          DartLib('regress37069',
              [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
              restrictions: [
                Restriction.none,
                ...List<Restriction>.filled(11, Restriction.small)
              ]),
        ],
        ...DartLib.intLibs,
      ];

      typeToLibraryMethods[DartType.DOUBLE] = [
        if (ffi) ...[
          DartLib('times1_337Float', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyDoubles',
              [DartType.VOID, ...List<DartType>.filled(10, DartType.DOUBLE)],
              true),
          DartLib('times1_337Double', [DartType.VOID, DartType.DOUBLE], true),
          DartLib(
              'sumManyNumbers',
              [
                DartType.VOID,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE,
                DartType.INT,
                DartType.DOUBLE
              ],
              true),
          DartLib('inventFloatValue', [DartType.VOID, DartType.VOID], true),
          DartLib('smallDouble', [DartType.VOID, DartType.VOID], true),
        ],
        ...DartLib.doubleLibs,
      ];
    }
  }

  final Map<DartType, List<DartLib>> typeToLibraryMethods;
}

/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
  DartFuzz(this.seed, this.fp, this.ffi, this.flatTp, this.file,
      {this.minimize = false, this.smask, this.emask});

  void run() {
    // Initialize program variables.
    rand = Random(seed);
    currentClassIndex = null;
    currentMethod = null;
    currentMethodIndex = null;
    // Setup Dart types.
    dartType = DartType.fromDartConfig(enableFp: fp, disableNesting: flatTp);
    // Setup minimization parameters.
    initMinimization();
    // Setup the library and ffi api.
    api = DartApi(ffi);
    // Setup the types.
    localVars = <DartType?>[];
    iterVars = <String>[];
    globalVars = fillTypes1(limit: numGlobalVars);
    globalVars.addAll(dartType.allTypes);
    globalMethods = getMethods(
        numGlobalMethods, numMethodParams, MethodType.globalMethod,
        namePrefix: methodName);
    classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
    final numClassMethods = 1 + numClasses - classFields.length;
    classMethods = getClassMethods(classFields.length, numClassMethods,
        numMethodParams, fillTypes1(limit: numMethodParams));
    virtualClassMethods = <Map<int, List<int>>>[];
    classParents = <int>[];
    // Setup optional ffi methods and types.
    if (ffi) {
      globalMethods.addAll(getMethods(
          numGlobalMethods, numMethodParams, MethodType.ffiMethod,
          namePrefix: methodName));
    }
    // Generate.
    emitHeader();
    emitVariableDeclarations(varName, globalVars);
    emitMethods(globalMethods);
    for (var i = 0; i < numDartTypeExtensions; ++i) {
      var type = oneOfSet(dartType.allTypes);
      emitAndAddExtensionMethods(globalMethods, type.name, '${methodName}E$i',
          '$methodName${i}_Extension',
          type: type);
    }
    emitClasses();
    emitMain();
    // Sanity.
    assert(currentClassIndex == null);
    assert(currentMethod == null);
    assert(currentMethodIndex == null);
    assert(indent == 0);
    assert(nest == 0);
    assert(localVars.isEmpty);
  }

  List<Method> getMethods(int maxMethods, int maxParams, MethodType methodType,
      {String? className,
      String? extensionName,
      String? namePrefix,
      DartType? type}) {
    final list = <Method>[];
    for (var i = 0, n = chooseOneUpTo(maxMethods); i < n; i++) {
      final params = fillTypes1(
          limit: maxParams, isFfi: methodType == MethodType.ffiMethod);
      switch (methodType) {
        case MethodType.globalMethod:
          list.add(GlobalMethod('$namePrefix$i', params, this));
          break;
        case MethodType.ffiMethod:
          list.add(FfiMethod(namePrefix!, i, params, this));
          break;
        case MethodType.instanceMethod:
          list.add(InstanceMethod('$namePrefix$i', params, this, className!));
          break;
        case MethodType.extensionMethod:
          list.add(ExtensionMethod(
              '$namePrefix$i', params, this, className!, extensionName!, type));
          break;
        default:
          break;
      }
    }
    return list;
  }

  List<List<Method>> getClassMethods(int numClasses, int maxMethods,
      int maxParams, List<DartType> callMethodParams) {
    final methodsForAllClasses = <List<Method>>[];
    for (var i = 0; i < numClasses; i++) {
      final methodsForCurrentClass = getMethods(
          maxMethods, maxParams, MethodType.instanceMethod,
          className: 'X$i', namePrefix: '$methodName${i}_');
      // Add the call method for the current class. The prototype for the call
      // method is pre-decided. This is because we are possibly overriding the
      // parent class' call method, in which case the prototype should be the
      // same. To simplify the dartfuzz logic, all call methods have the same
      // prototype.
      methodsForCurrentClass.add(CallMethod(callMethodParams, this, 'X$i'));
      methodsForAllClasses.add(methodsForCurrentClass);
    }
    return methodsForAllClasses;
  }

  //
  // General Helpers.
  //

  BigInt genMask(int m) => BigInt.from(1) << m;
  int choose(int c) => rand.nextInt(c);
  int chooseOneUpTo(int c) => choose(c) + 1;
  bool coinFlip() => rand.nextBool();
  bool rollDice(int c) => (choose(c) == 0);
  double uniform() => rand.nextDouble();

  // Picks one of the given choices.
  T oneOf<T>(List<T> choices) => choices[choose(choices.length)];
  T oneOfSet<T>(Set<T> choices) => choices.elementAt(choose(choices.length));

  //
  // Code Structure Helpers.
  //

  void incIndent() => indent += 2;
  void decIndent() => indent -= 2;

  void emitZero() => emit('0');

  void emitTryCatchFinally(Function tryBody, Function catchBody,
      {Function? finallyBody}) {
    emitLn('try ', newline: false);
    emitBraceWrapped(() => tryBody());
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' on StackOverflowError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' catch (e, st) ');
    emitBraceWrapped(catchBody);
    if (finallyBody != null) {
      emit(' finally ');
      emitBraceWrapped(finallyBody);
    }
  }

  dynamic emitWrapped(List<String> pair, Function exprEmitter,
      {bool shouldIndent = true}) {
    assert(pair.length == 2);
    emit(pair[0]);
    if (shouldIndent) {
      incIndent();
      emitNewline();
    }
    final result = exprEmitter();
    if (shouldIndent) {
      decIndent();
      emitNewline();
      emitLn(pair[1], newline: false);
    } else {
      emit(pair[1]);
    }
    return result;
  }

  dynamic emitParenWrapped(Function exprEmitter,
      {bool includeSemicolon = false}) {
    final result =
        emitWrapped(const ['(', ')'], exprEmitter, shouldIndent: false);
    if (includeSemicolon) {
      emit(';');
    }
    return result;
  }

  dynamic emitBraceWrapped(Function exprEmitter, {bool shouldIndent = true}) =>
      emitWrapped(const ['{', '}'], exprEmitter, shouldIndent: shouldIndent);

  dynamic emitSquareBraceWrapped(Function exprEmitter) =>
      emitWrapped(const ['[', ']'], exprEmitter, shouldIndent: false);

  dynamic emitCommaSeparated(Function(int) elementBuilder, int length,
      {int start = 0, bool newline = false}) {
    for (var i = start; i < length; ++i) {
      elementBuilder(i);
      if (i + 1 != length) {
        emit(',', newline: newline);
        if (!newline) {
          emit(' ');
        }
      }
    }
  }

  void emitFunctionDefinition(String name, Function body, {String? retType}) {
    emitIndentation();
    if (retType != null) {
      emit(retType + ' ');
    }
    emit(name);
    emit('() '); // TODO(bkonyi): handle params

    emitBraceWrapped(body);
  }

  bool emitIfStatement(
      Function ifConditionEmitter, bool Function() ifBodyEmitter,
      {bool Function()? elseBodyEmitter}) {
    emitLn('if ', newline: false);
    emitParenWrapped(ifConditionEmitter);
    emit(' ');
    final bool ifMayFallThrough = emitBraceWrapped(ifBodyEmitter);
    var elseMayFallThrough = true;
    if (elseBodyEmitter != null) {
      emit(' else ');
      elseMayFallThrough = emitBraceWrapped(elseBodyEmitter);
    }
    return ifMayFallThrough || elseMayFallThrough;
  }

  void emitImport(String library, {String? asName}) => (asName == null)
      ? emitLn("import '$library';")
      : emitLn("import '$library' as $asName;");

  void emitBinaryComparison(Function e1, String op, Function e2,
      {bool includeSemicolon = false}) {
    e1();
    emit(' $op ');
    e2();
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Randomly specialize interface if possible. E.g. num to int.
  DartType maybeSpecializeInterface(DartType tp) {
    if (!dartType.isSpecializable(tp)) return tp;
    var resolvedTp = oneOfSet(dartType.interfaces(tp));
    return resolvedTp;
  }

  //
  // Minimization components.
  //

  void initMinimization() {
    stmtCntr = 0;
    exprCntr = 0;
    skipStmt = false;
    skipExpr = false;
  }

  void emitMinimizedLiteral(DartType tp) {
    switch (tp) {
      case DartType.BOOL:
        emit('true');
        break;
      case DartType.INT:
        emit('1');
        break;
      case DartType.DOUBLE:
        emit('1.0');
        break;
      case DartType.STRING:
        emit('"a"');
        break;
      case DartType.LIST_INT:
        emit('[1]');
        break;
      case DartType.SET_INT:
        emit('{1}');
        break;
      case DartType.MAP_INT_STRING:
        emit('{1: "a"}');
        break;
      default:
        throw 'Unknown DartType $tp';
    }
  }

  // Process the opening of a statement.
  // Determine whether the statement should be skipped based on the
  // statement index stored in stmtCntr and the statement mask stored
  // in smask.
  // Returns true if the statement should be skipped.
  bool processStmtOpen() {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current statement number is set in the
    // statement bitmap. If so skip this statement.
    final newMask = genMask(stmtCntr);
    final maskBitSet = (smask! & newMask) != BigInt.zero;
    // Statements are nested, therefore masking one statement like e.g.
    // a for loop leads to other statements being omitted.
    // Here we update the statement mask to include the additionally
    // omitted statements.
    if (skipStmt) {
      smask = smask! | newMask;
    }
    // Increase the statement counter.
    stmtCntr++;
    if (!skipStmt && maskBitSet) {
      skipStmt = true;
      return true;
    }
    return false;
  }

  // Process the closing of a statement.
  // The variable resetSkipStmt indicates whether this
  // statement closes the sequence of skipped statement.
  // E.g. the end of a loop where all contained statements
  // were skipped.
  void processStmtClose(bool resetSkipStmt) {
    if (!minimize) {
      return;
    }
    if (resetSkipStmt) {
      skipStmt = false;
    }
  }

  // Process the opening of an expression.
  // Determine whether the expression should be skipped based on the
  // expression index stored in exprCntr and the expression mask stored
  // in emask.
  // Returns true is the expression is skipped.
  bool processExprOpen(DartType tp) {
    // Do nothing if we are not in minimization mode.
    if (!minimize) {
      return false;
    }
    // Check whether the bit for the current expression number is set in the
    // expression bitmap. If so skip this expression.
    final newMask = genMask(exprCntr);
    final maskBitSet = (emask! & newMask) != BigInt.zero;
    // Expressions are nested, therefore masking one expression like e.g.
    // a for loop leads to other expressions being omitted.
    // Similarly, if the whole statement is skipped, all the expressions
    // within that statement are implicitly masked.
    // Here we update the expression mask to include the additionally
    // omitted expressions.
    if (skipExpr || skipStmt) {
      emask = emask! | newMask;
    }
    exprCntr++;
    if (skipStmt) {
      return false;
    }
    if (!skipExpr && maskBitSet) {
      emitMinimizedLiteral(tp);
      skipExpr = true;
      return true;
    }
    return false;
  }

  void processExprClose(bool resetExprStmt) {
    if (!minimize || skipStmt) {
      return;
    }
    if (resetExprStmt) {
      skipExpr = false;
    }
  }

  //
  // Program components.
  //

  void emitHeader() {
    emitLn('// The Dart Project Fuzz Tester ($version).');
    emitLn('// Program generated as:');
    emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
        '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
    emitLn('// @dart=2.14');
    emitNewline();
    emitImport('dart:async');
    emitImport('dart:cli');
    emitImport('dart:collection');
    emitImport('dart:convert');
    emitImport('dart:core');
    emitImport('dart:io');
    emitImport('dart:isolate');
    emitImport('dart:math');
    emitImport('dart:typed_data');
    if (ffi) {
      emitImport('dart:ffi', asName: 'ffi');
      emitLn(DartFuzzFfiApi.ffiapi);
    }
    emitNewline();
  }

  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
      List<DartType> pars) {
    emit('${pars[0].name} Function');
    emitParenWrapped(() => emitCommaSeparated(
        (int i) => emit('${pars[i].name}'), pars.length,
        start: 1));
    emit(' $dartFuncName = ffi.Pointer.fromFunction<$typeName>');
    emitParenWrapped(() {
      emit('$ffiFuncName, ');
      emitLiteral(0, pars[0], smallPositiveValue: true);
    });
    emit('.cast<ffi.NativeFunction<$typeName>>().asFunction();');
    emitNewline();
  }

  void emitMethods(List<Method> methods) {
    for (var i = 0; i < methods.length; i++) {
      currentMethod = methods[i];
      currentMethodIndex = i;
      currentMethod!.emit();
      currentMethod = null;
      currentMethodIndex = null;
    }
  }

  // Randomly overwrite some methods from the parent classes.
  void emitVirtualMethods() {
    final currentClassTmp = currentClassIndex;
    var parentClass = classParents[currentClassIndex!];
    final vcm = <int, List<int>>{};
    // Chase randomly up in class hierarchy.
    while (parentClass >= 0) {
      vcm[parentClass] = <int>[];
      for (var j = 0, n = classMethods[parentClass].length; j < n; j++) {
        // Call methods are presently always already overridden, so we
        // shouldn't override them here.
        if (rollDice(8) && !(classMethods[parentClass][j] is CallMethod)) {
          currentClassIndex = parentClass;
          currentMethod = classMethods[parentClass][j];
          currentMethodIndex = j;
          classMethods[parentClass][j].emit();
          vcm[parentClass]!.add(currentMethodIndex!);
          currentClassIndex = null;
          currentMethod = null;
          currentMethodIndex = null;
        }
      }
      if (coinFlip() || classParents.length > parentClass) {
        break;
      } else {
        parentClass = classParents[parentClass];
      }
    }
    currentClassIndex = currentClassTmp;
    virtualClassMethods.add(vcm);
  }

  void emitClasses() {
    assert(classFields.length == classMethods.length);
    for (var i = 0; i < classFields.length; i++) {
      if (i == 0) {
        classParents.add(-1);
        emit('class X0 ');
      } else {
        final parentClass = choose(i);
        classParents.add(parentClass);
        if (classParents[parentClass] >= 0 || coinFlip()) {
          // Inheritance
          emit('class X$i extends X$parentClass ');
        } else {
          // Mixin
          emit('class X$i with X$parentClass ');
        }
      }
      emitBraceWrapped(() {
        emitVariableDeclarations('$fieldName${i}_', classFields[i]);
        currentClassIndex = i;
        emitVirtualMethods();
        emitMethods(classMethods[currentClassIndex!]);
        emitFunctionDefinition('run', () {
          if (i > 0) {
            // TODO(bkonyi): fix potential issue where we try to apply a class
            // as a mixin when it calls super.
            emitLn('super.run();');
          }
          assert(localVars.isEmpty);
          emitStatements(0);
          assert(localVars.isEmpty);
        }, retType: 'void');
      });
      emitNewline();
      emitNewline();
      emitAndAddExtensionMethods(
          classMethods[currentClassIndex!],
          'X$currentClassIndex',
          'XE$currentClassIndex',
          '$methodName${currentClassIndex}_Extension');
      currentClassIndex = null;
    }
  }

  void emitAndAddExtensionMethods(
      List<Method> methodList, className, extensionName, namePrefix,
      {DartType? type}) {
    var endIndex = methodList.length;
    methodList.addAll(getMethods(numExtensionMethodsPerClass, numMethodParams,
        MethodType.extensionMethod,
        className: className,
        // Randomly select between named and anonymous extensions.
        extensionName: coinFlip() ? extensionName : '',
        namePrefix: namePrefix,
        type: type));
    emit('extension $extensionName on $className ');
    emitBraceWrapped(() {
      // Emit the newly added methods.
      for (var i = endIndex; i < methodList.length; i++) {
        currentMethod = methodList[i];
        currentMethodIndex = i;
        methodList[i].emit();
        currentMethod = null;
        currentMethodIndex = null;
      }
    });
    emitNewline();
    emitNewline();
  }

  void emitLoadFfiLib() {
    if (ffi) {
      emitLn('// The following throws an uncaught exception if the ffi library '
          'is not found.');
      emitLn('// By not catching this exception, we terminate the program with '
          'a full stack trace');
      emitLn('// which, in turn, flags the problem prominently');
      emitIfStatement(() => emit('ffiTestFunctions == null'),
          () => emitPrint('Did not load ffi test functions'));
      emitNewline();
    }
  }

  void emitMain() => emitFunctionDefinition('main', () {
        emitLoadFfiLib();

        // Call each global method once.
        for (var i = 0; i < globalMethods.length; i++) {
          late String outputName;
          emitTryCatchFinally(
              () => outputName =
                  globalMethods[i].emitCall(1, includeSemicolon: true),
              () => emitPrint('${outputName}() throws'));
          emitNewline();
        }

        // Call each class method once.
        for (var i = 0; i < classMethods.length; i++) {
          for (var j = 0; j < classMethods[i].length; j++) {
            late String outputName;
            emitNewline();
            emitTryCatchFinally(
                () => outputName =
                    classMethods[i][j].emitCall(1, includeSemicolon: true),
                () => emitPrint('$outputName throws'));
          }
          // Call each virtual class method once.
          var parentClass = classParents[i];
          while (parentClass >= 0) {
            if (virtualClassMethods[i].containsKey(parentClass)) {
              for (var j = 0;
                  j < virtualClassMethods[i][parentClass]!.length;
                  j++) {
                late String outputName;
                emitNewline();
                emitTryCatchFinally(
                    () => outputName = classMethods[parentClass][j]
                        .emitCall(1, includeSemicolon: true),
                    () => emitPrint('$outputName throws'));
              }
            }
            parentClass = classParents[parentClass];
          }
        }

        emitNewline();
        emitTryCatchFinally(() {
          emitLn('X${classFields.length - 1}().run();', newline: false);
        }, () {
          emitPrint('X${classFields.length - 1}().run() throws');
        });

        emitNewline();
        emitTryCatchFinally(() {
          for (var i = 0; i < globalVars.length; i++) {
            emitPrint('$varName$i: \$$varName$i');
            emitNewline();
          }
        }, () => emitPrint('print() throws'));
      });

  //
  // Declarations.
  //

  void emitVariableDeclarations(String name, List<DartType> vars) {
    for (var i = 0; i < vars.length; i++) {
      var tp = vars[i];
      final varName = '$name$i';
      emitVariableDeclaration(varName, tp,
          initializerEmitter: () => emitConstructorOrLiteral(0, tp));
    }
    emitNewline();
  }

  void emitVariableDeclaration(String name, DartType tp,
      {Function? initializerEmitter,
      bool indent = true,
      bool newline = true,
      bool includeSemicolon = true}) {
    final typeName = tp.dartName;
    if (indent) {
      emitIndentation();
    }
    emit('$typeName $name', newline: false);
    if (initializerEmitter != null) {
      emit(' = ');
      initializerEmitter();
    }
    if (includeSemicolon) {
      emit(';', newline: newline);
    }
  }

  void emitParDecls(List<DartType> pars) => emitCommaSeparated((int i) {
        var tp = pars[i];
        emit('${tp.dartName} $paramName$i');
      }, pars.length, start: 1);

  //
  // Comments (for FE and analysis tools).
  //

  void emitComment() {
    switch (choose(4)) {
      case 0:
        emitLn('// Single-line comment.');
        break;
      case 1:
        emitLn('/// Single-line documentation comment.');
        break;
      case 2:
        emitLn('/*');
        emitLn(' * Multi-line');
        emitLn(' * comment.');
        emitLn(' */');
        break;
      default:
        emitLn('/**');
        emitLn(' ** Multi-line');
        emitLn(' ** documentation comment.');
        emitLn(' */');
        break;
    }
  }

  //
  // Statements.
  //

  // Emit an assignment statement.
  bool emitAssign() {
    final tp = oneOfSet(dartType.allTypes);
    String assignOp;
    if (DartType.isGrowableType(tp)) {
      // Assignments like *= and += on growable types (String, List, ...)
      // may lead to OOM, especially within loops.
      // TODO: Implement a more specific heuristic that selectively allows
      // modifying assignment operators (like += *=) for growable types.
      assignOp = '=';
    } else {
      // Select one of the assign operations for the given type.
      var assignOps = dartType.assignOps(tp);
      if (assignOps.isEmpty) {
        throw 'No assign operation for $tp';
      }
      assignOp = oneOfSet(assignOps);
    }
    emitIndentation();
    // Emit a variable of the lhs type.
    final emittedVar = emitVar(0, tp, isLhs: true, assignOp: assignOp)!;
    var rhsFilter = RhsFilter.fromDartType(tp, emittedVar);
    emit(' $assignOp ');
    // Select one of the possible rhs types for the given lhs type and assign
    // operation.
    var rhsTypes = dartType.assignOpRhs(tp, assignOp);
    if (rhsTypes.isEmpty) {
      throw 'No rhs type for assign $tp $assignOp';
    }
    var rhsType = oneOfSet(rhsTypes);
    emitExpr(0, rhsType, rhsFilter: rhsFilter, includeSemicolon: true);
    return true;
  }

  // Emit a print statement.
  bool emitPrint([String? body]) {
    emitLn('print', newline: false);
    emitParenWrapped(() {
      if (body != null) {
        emit("'$body'");
      } else {
        var tp = oneOfSet(dartType.allTypes);
        emitExpr(0, tp);
      }
    }, includeSemicolon: true);
    return true;
  }

  // Emit a return statement.
  bool emitReturn() {
    var proto = getCurrentProto();
    if (proto == null || proto[0] == DartType.VOID) {
      emitLn('return;');
    } else {
      emitLn('return ', newline: false);
      emitExpr(0, proto[0], includeSemicolon: true);
    }
    return false;
  }

  // Emit a throw statement.
  bool emitThrow() {
    DartType tp;
    do {
      tp = oneOfSet(dartType.allTypes).toNonNullable();
    } while (tp == DartType.NULL);
    emitLn('throw ', newline: false);
    emitExpr(0, tp, includeSemicolon: true);
    return false;
  }

  // Emit a one-way if statement.
  bool emitIf1(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1));

  // Emit a two-way if statement.
  bool emitIf2(int depth) => emitIfStatement(
      () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1),
      elseBodyEmitter: () => emitStatements(depth + 1));

  // Emit a simple increasing for-loop.
  bool emitFor(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: emitZero, newline: false, indent: false);
      emitBinaryComparison(() => emit(name), '<', emitSmallPositiveInt,
          includeSemicolon: true);
      emit('$name++');
    });
    emitBraceWrapped(() {
      nest++;
      iterVars.add('$localName$i');
      localVars.add(DartType.INT);
      emitStatements(depth + 1);
      localVars.removeLast();
      iterVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership for-in-loop.
  bool emitForIn(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    // Select one iterable type to be used in 'for in' statement.
    final iterType = oneOfSet(dartType.iterableTypes1);
    // Get the element type contained within the iterable type.
    final elementType = dartType.elementType(iterType);
    emitLn('for ', newline: false);
    emitParenWrapped(() {
      emit('${elementType.dartName} $localName$i in ');
      localVars.add(null); // declared, but don't use
      emitExpr(0, iterType.toNonNullable());
      localVars.removeLast(); // will get type
    });
    emitBraceWrapped(() {
      nest++;
      localVars.add(elementType);
      emitStatements(depth + 1);
      localVars.removeLast();
      nest--;
    });
    return true;
  }

  // Emit a simple membership forEach loop.
  bool emitForEach(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    emitIndentation();

    // Select one map type to be used in forEach loop.
    final mapType = oneOfSet(dartType.mapTypes);
    final emittedVar = emitScalarVar(mapType.toNonNullable(), isLhs: false);
    iterVars.add(emittedVar);
    emit('.forEach');
    final i = localVars.length;
    final j = i + 1;
    emitParenWrapped(() {
      emitParenWrapped(() => emit('$localName$i, $localName$j'));
      emitBraceWrapped(() {
        // Reset, since forEach cannot break out of own or enclosing context.
        final nestTmp = nest;
        nest = 0;
        // Reset, since return type of forEach is void.
        final currentMethodIndexTemp = currentMethodIndex;
        currentMethodIndex = null;

        // Get the type of the map key and add it to the local variables.
        localVars.add(dartType.indexType(mapType));
        // Get the type of the map values and add it to the local variables.
        localVars.add(dartType.elementType(mapType));
        emitStatements(depth + 1);
        localVars.removeLast();
        localVars.removeLast();

        currentMethodIndex = currentMethodIndexTemp;
        nest = nestTmp;
      });
    }, includeSemicolon: true);
    return true;
  }

  // Emit a while-loop.
  bool emitWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT,
          initializerEmitter: () => emitSmallPositiveInt());
      emitLn('while ', newline: false);
      emitParenWrapped(
          () => emitBinaryComparison(() => emit('--$name'), '>', emitZero));
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
    });
    return true;
  }

  // Emit a do-while-loop.
  bool emitDoWhile(int depth) {
    // Make deep nesting of loops increasingly unlikely.
    if (choose(nest + 1) > nestDepth) {
      return emitAssign();
    }
    final i = localVars.length;
    emitIndentation();
    emitBraceWrapped(() {
      final name = '$localName$i';
      emitVariableDeclaration(name, DartType.INT, initializerEmitter: emitZero);
      emitLn('do ', newline: false);
      emitBraceWrapped(() {
        nest++;
        iterVars.add(name);
        localVars.add(DartType.INT);
        emitStatements(depth + 1);
        localVars.removeLast();
        iterVars.removeLast();
        nest--;
      });
      emit(' while ');
      emitParenWrapped(
          () => emitBinaryComparison(
              () => emit('++$name'), '<', emitSmallPositiveInt),
          includeSemicolon: true);
    });
    emitNewline();
    return true;
  }

  // Emit a break/continue when inside iteration.
  bool emitBreakOrContinue(int depth) {
    if (nest > 0) {
      switch (choose(2)) {
        case 0:
          emitLn('continue;');
          return false;
        default:
          emitLn('break;');
          return false;
      }
    }
    return emitAssign(); // resort to assignment
  }

  // Emit a switch statement.
  bool emitSwitch(int depth) {
    void emitCase(Function bodyEmitter, {int? kase}) {
      if (kase == null) {
        emitLn('default: ', newline: false);
      } else {
        emitLn('case $kase: ', newline: false);
      }
      emitBraceWrapped(() {
        bodyEmitter();
        emitNewline();
        emitLn('break;',
            newline: false); // always generate, avoid FE complaints
      });
    }

    emitLn('switch ', newline: false);
    emitParenWrapped(() => emitExpr(0, DartType.INT));
    emitBraceWrapped(() {
      var start = choose(1 << 32);
      var step = chooseOneUpTo(10);
      final maxCases = 3;
      for (var i = 0; i < maxCases; i++, start += step) {
        emitCase(() => emitStatement(depth + 1),
            kase: (i == 2 && coinFlip()) ? null : start);
        if (i + 1 != maxCases) {
          emitNewline();
        }
      }
    });
    return true;
  }

  // Emit a new program scope that introduces a new local variable.
  bool emitScope(int depth) {
    emitIndentation();
    emitBraceWrapped(() {
      var tp = oneOfSet(dartType.allTypes);
      final i = localVars.length;
      final name = '$localName$i';
      emitVariableDeclaration(name, tp, initializerEmitter: () {
        localVars.add(null); // declared, but don't use
        emitExpr(0, tp);
        localVars.removeLast(); // will get type
      });
      localVars.add(tp);
      emitStatements(depth + 1);
      localVars.removeLast();
    });
    return true;
  }

  // Emit try/catch/finally.
  bool emitTryCatch(int depth) {
    final emitStatementsClosure = () => emitStatements(depth + 1);
    emitLn('try ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    emit(' on OutOfMemoryError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' on StackOverflowError ');
    emitBraceWrapped(() => emitLn('exit($oomExitCode);', newline: false));
    emit(' catch (exception, stackTrace) ', newline: false);
    emitBraceWrapped(emitStatementsClosure);
    if (coinFlip()) {
      emit(' finally ', newline: false);
      emitBraceWrapped(emitStatementsClosure);
    }
    return true;
  }

  // Emit a single statement.
  bool emitSingleStatement(int depth) {
    // Throw in a comment every once in a while.
    if (rollDice(10)) {
      emitComment();
    }
    // Continuing nested statements becomes less likely as the depth grows.
    if (choose(depth + 1) > stmtDepth) {
      return emitAssign();
    }
    // Possibly nested statement.
    switch (choose(17)) {
      // Favors assignment.
      case 0:
        return emitPrint();
      case 1:
        return emitReturn();
      case 2:
        return emitThrow();
      case 3:
        return emitIf1(depth);
      case 4:
        return emitIf2(depth);
      case 5:
        return emitFor(depth);
      case 6:
        return emitForIn(depth);
      case 7:
        return emitWhile(depth);
      case 8:
        return emitDoWhile(depth);
      case 9:
        return emitBreakOrContinue(depth);
      case 10:
        return emitSwitch(depth);
      case 11:
        return emitScope(depth);
      case 12:
        return emitTryCatch(depth);
      case 13:
        return emitForEach(depth);
      case 14:
        emitLibraryCall(depth, DartType.VOID, includeSemicolon: true);
        return true;
      default:
        return emitAssign();
    }
  }

  // Emit a statement (main entry).
  // Returns true if code *may* fall-through
  // (not made too advanced to avoid FE complaints).
  bool emitStatement(int depth) {
    final resetSkipStmt = processStmtOpen();
    var ret = emitSingleStatement(depth);
    processStmtClose(resetSkipStmt);
    return ret;
  }

  // Emit statements. Returns true if code may fall-through.
  bool emitStatements(int depth) {
    var s = chooseOneUpTo(numStatements);
    for (var i = 0; i < s; i++) {
      if (!emitStatement(depth)) {
        return false; // rest would be dead code
      }
      if (i + 1 != s) {
        emitNewline();
      }
    }
    return true;
  }

  //
  // Expressions.
  //

  void emitBool() => emit(coinFlip() ? 'true' : 'false');

  void emitNull() => emit('null');

  void emitSmallPositiveInt({int limit = 50, bool includeSemicolon = false}) {
    emit('${choose(limit)}');
    if (includeSemicolon) {
      emit(';');
    }
  }

  void emitSmallNegativeInt() => emit('-${choose(100)}');

  void emitInt() {
    switch (choose(7)) {
      // Favors small ints.
      case 0:
      case 1:
      case 2:
        emitSmallPositiveInt();
        break;
      case 3:
      case 4:
      case 5:
        emitSmallNegativeInt();
        break;
      default:
        emit('${oneOf(interestingIntegers)}');
        break;
    }
  }

  void emitDouble() => emit('${uniform()}');

  void emitNum({bool smallPositiveValue = false}) {
    if (!fp || coinFlip()) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else {
      emitDouble();
    }
  }

  void emitChar() {
    switch (choose(10)) {
      // Favors regular char.
      case 0:
        emit(oneOf(interestingChars));
        break;
      default:
        emit(regularChars[choose(regularChars.length)]);
        break;
    }
  }

  void emitString({int length = 8}) {
    final n = choose(length);
    emit("'");
    for (var i = 0; i < n; i++) {
      emitChar();
    }
    emit("'");
  }

  void emitElementExpr(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool isConst = false}) {
    // Inside a constant collection, keep collection elements constants too.
    if (isConst) {
      if (DartType.isCollectionType(tp)) {
        emitConstCollection(depth + 1, tp, rhsFilter: rhsFilter);
        return;
      }
    }
    // Use literals outside a class or inside a constant collection.
    if (currentMethodIndex == null || isConst) {
      emitLiteral(depth, tp, rhsFilter: rhsFilter);
    } else {
      emitExpr(depth, tp, rhsFilter: rhsFilter);
    }
  }

  void emitElement(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool isConst = false}) {
    // Get the element type contained in type tp.
    // E.g. element type of List<String> is String.
    final elementType = dartType.elementType(tp);
    // Decide whether we need to generate Map or List/Set type elements.
    if (DartType.isMapType(tp)) {
      // Emit construct for the map key type.
      final indexType = dartType.indexType(tp);
      emitIndentation();
      emitElementExpr(depth, indexType, rhsFilter: rhsFilter, isConst: isConst);
      emit(' : ');
      // Emit construct for the map value type.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    } else {
      // List and Set types.
      emitElementExpr(depth, elementType,
          rhsFilter: rhsFilter, isConst: isConst);
    }
  }

  void emitCollectionElement(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    var r = (depth <= exprDepth) ? choose(10) : 10;
    // TODO (felih): disable complex collection constructs for new types for
    // now.
    if (!{DartType.MAP_INT_STRING, DartType.LIST_INT, DartType.SET_INT}
        .contains(tp)) {
      emitElement(depth, tp, rhsFilter: rhsFilter);
      return;
    }
    switch (r) {
      // Favors elements over control-flow collections.
      case 0:
        emitLn('...', newline: false); // spread
        emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
        break;
      case 1:
        emitLn('if ', newline: false);
        emitParenWrapped(() =>
            emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter));
        emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        if (coinFlip()) {
          emitNewline();
          emitLn('else ', newline: false);
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
        }
        break;
      case 2:
        {
          final i = localVars.length;
          // TODO (felih): update to use new type system. Add types like
          // LIST_STRING etc.
          emitLn('for ', newline: false);
          emitParenWrapped(() {
            final local = '$localName$i';
            iterVars.add(local);
            // For-loop (induction, list, set).
            localVars.add(null); // declared, but don't use
            switch (choose(3)) {
              case 0:
                emitVariableDeclaration(local, DartType.INT,
                    initializerEmitter: emitZero, indent: false);
                emitBinaryComparison(() => emit(local), '<',
                    () => emitSmallPositiveInt(limit: 16),
                    includeSemicolon: true);
                emit('$local++');
                break;
              case 1:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.LIST_INT,
                    rhsFilter: rhsFilter);
                break;
              default:
                emitVariableDeclaration(local, DartType.INT,
                    includeSemicolon: false, indent: false);
                emit(' in ');
                emitCollection(depth + 1, DartType.SET_INT,
                    rhsFilter: rhsFilter);
                break;
            }
            localVars.removeLast(); // will get type
          });
          nest++;
          localVars.add(DartType.INT);
          emitNewline();
          emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
          localVars.removeLast();
          iterVars.removeLast();
          nest--;
          break;
        }
      default:
        emitElement(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  void emitCollection(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    String l, r;
    if (DartType.isListType(tp)) {
      var elementType = dartType.elementType(tp);
      l = '<${elementType.dartName}>[';
      r = ']';
    } else if (DartType.isSetType(tp)) {
      var elementType = dartType.elementType(tp);
      l = '<${elementType.dartName}>{';
      r = '}';
    } else if (DartType.isMapType(tp)) {
      var indexType = dartType.indexType(tp);
      var elementType = dartType.elementType(tp);
      l = '<${indexType.dartName},${elementType.dartName}>{';
      r = '}';
    } else {
      throw "Unrecognized collection type $tp";
    }
    emitWrapped([l, r], () {
      // Collection length decreases as depth increases.
      var collectionLength = max(1, 8 - depth);
      emitCommaSeparated(
          (int _) => emitCollectionElement(depth, tp, rhsFilter: rhsFilter),
          chooseOneUpTo(collectionLength),
          newline: DartType.isMapType(tp));
    }, shouldIndent: DartType.isMapType(tp));
  }

  void emitConstCollection(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    String l, r;
    bool canHaveElements;
    if (DartType.isListType(tp)) {
      var elementType = dartType.elementType(tp);
      l = 'const <${elementType.dartName}>[';
      r = ']';
      canHaveElements = true;
    } else if (DartType.isSetType(tp)) {
      var elementType = dartType.elementType(tp);
      l = 'const <${elementType.dartName}>{';
      r = '}';
      canHaveElements = (elementType != DartType.DOUBLE) &&
          (elementType != DartType.DOUBLE_NULLABLE);
    } else if (DartType.isMapType(tp)) {
      var indexType = dartType.indexType(tp);
      var elementType = dartType.elementType(tp);
      l = 'const <${indexType.dartName},${elementType.dartName}>{';
      r = '}';
      canHaveElements = (indexType != DartType.DOUBLE) &&
          (indexType != DartType.DOUBLE_NULLABLE);
    } else {
      throw "Unrecognized collection type $tp";
    }
    if (!canHaveElements) {
      // Dart does not like floating-point elements. A key would, for
      // example, yield "The key does not have a primitive operator '=='".
      // So emit an empty collection.
      emit(l);
      emit(r);
      return;
    }
    emitWrapped([l, r],
        () => emitElement(depth, tp, rhsFilter: rhsFilter, isConst: true),
        shouldIndent: DartType.isMapType(tp));
  }

  void emitLiteral(int depth, DartType tp,
      {bool smallPositiveValue = false, RhsFilter? rhsFilter}) {
    if (tp.isNullable) {
      if (choose(20) == 0) {
        emitNull();
        return;
      }
      tp = tp.toNonNullable();
    }
    // Randomly specialize interface if possible. E.g. num to int.
    tp = maybeSpecializeInterface(tp);
    if (tp == DartType.NULL) {
      emitNull();
    } else if (tp == DartType.BOOL) {
      emitBool();
    } else if (tp == DartType.INT) {
      if (smallPositiveValue) {
        emitSmallPositiveInt();
      } else {
        emitInt();
      }
    } else if (tp == DartType.DOUBLE) {
      emitDouble();
    } else if (tp == DartType.NUM) {
      emitNum(smallPositiveValue: smallPositiveValue);
    } else if (tp == DartType.STRING) {
      emitString();
    } else if (tp == DartType.ENDIAN) {
      // The Endian type doesn't have a public constructor, so we emit a
      // library call instead.
      emitLibraryCall(depth, tp);
    } else if (dartType.constructors(tp).isNotEmpty) {
      // Constructors serve as literals for non trivially constructable types.
      // Important note: We have to test for existence of a non trivial
      // constructor before testing for list type association, since some types
      // like ListInt32 are of list type but can not be constructed
      // from a literal.
      emitConstructorOrLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    } else if (DartType.isCollectionType(tp)) {
      final resetExprStmt = processExprOpen(tp);
      emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
      processExprClose(resetExprStmt);
    } else {
      throw 'Can not emit literal for $tp';
    }
  }

  // Emit a constructor for a type, this can either be a trivial constructor
  // (i.e. parsed from a literal) or an actual function invocation.
  void emitConstructorOrLiteral(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    // If there is at least one non trivial constructor for the type tp
    // select one of these constructors.
    if (dartType.hasConstructor(tp)) {
      var constructor = oneOfSet(dartType.constructors(tp));
      // There are two types of constructors, named constructors and 'empty'
      // constructors (e.g. X.fromList(...) and new X(...) respectively).
      // Empty constructors are invoked with new + type name, non-empty
      // constructors are static functions of the type.
      if (constructor.isNotEmpty) {
        emit('${tp.name}.$constructor');
      } else {
        // New is no longer necessary as of Dart 2, but is still supported.
        // Emit a `new` once in a while to ensure it's covered.
        emit('${rollDice(10) ? "new " : ""}${tp.name}');
      }
      emitParenWrapped(() {
        // Iterate over constructor parameters.
        var constructorParameters =
            dartType.constructorParameters(tp, constructor);
        emitCommaSeparated((int i) {
          // If we are emitting a constructor parameter, we want to use small
          // values to avoid programs that run out of memory.
          // TODO (felih): maybe allow occasionally?
          emitLiteral(depth + 1, constructorParameters[i],
              smallPositiveValue: true, rhsFilter: rhsFilter);
        }, constructorParameters.length);
      });
    } else {
      // Otherwise type can be constructed from a literal.
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
    }
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Pick an existing variable of the given type.
  String? pickScalarVar(DartType tp,
      {bool isLhs = false, RhsFilter? rhsFilter}) {
    // Randomly specialize interface type, unless emitting left hand side.
    if (!isLhs) tp = maybeSpecializeInterface(tp);
    // Collect all choices from globals, fields, locals, and parameters.
    var choices = <String>{};
    for (var i = 0; i < globalVars.length; i++) {
      if (tp == globalVars[i]) choices.add('$varName$i');
    }
    for (var i = 0; i < localVars.length; i++) {
      if (tp == localVars[i]) choices.add('$localName$i');
    }
    var fields = getCurrentFields();
    if (fields != null) {
      for (var i = 0; i < fields.length; i++) {
        if (tp == fields[i]) choices.add('$fieldName${currentClassIndex}_$i');
      }
    }
    var proto = getCurrentProto();
    if (proto != null) {
      // If recursion is allowed on the current method, the last parameter is
      // the recursion depth parameter. We should avoid reassigning the
      // recursion depth parameter to prevent infinite recursion.
      final endIndex =
          currentMethod!.recursionAllowed ? proto.length - 1 : proto.length;
      for (var i = 1; i < endIndex; i++) {
        if (tp == proto[i]) choices.add('$paramName$i');
      }
    }
    // Make modification of the iteration variable from the loop
    // body less likely.
    if (isLhs) {
      if (!rollDice(100)) {
        var cleanChoices = choices.difference(Set.from(iterVars));
        if (cleanChoices.isNotEmpty) {
          choices = cleanChoices;
        }
      }
    }
    // Filter out the current lhs of the expression to avoid recursive
    // assignments of the form x = x * x.
    if (rhsFilter != null && rhsFilter.shouldFilter) {
      var cleanChoices = choices.difference({rhsFilter.lhsVar});
      // If we have other choices of variables, use those.
      if (cleanChoices.isNotEmpty) {
        choices = cleanChoices;
      } else if (!isLhs) {
        // If we are emitting an rhs variable, we can emit a terminal.
        // note that if the variable type is a collection, this might
        // still result in a recursion.
        emitLiteral(0, tp);
        return null;
      }
      // Otherwise we have to risk creating a recursion.
    }
    // Then pick one.
    if (choices.isEmpty) {
      throw 'No variable to emit for type ${tp.name}';
    }

    return '${choices.elementAt(choose(choices.length))}';
  }

  String? emitScalarVar(DartType tp,
      {bool isLhs = false, RhsFilter? rhsFilter}) {
    final emittedVar = pickScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
    if (emittedVar != null) {
      if (rhsFilter != null && (emittedVar == rhsFilter.lhsVar)) {
        rhsFilter.consume();
      }
      emit(emittedVar);
    }
    return emittedVar;
  }

  String? emitSubscriptedVar(int depth, DartType tp,
      {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
    String? ret;
    // Check if type tp is an indexable element of some other type.
    if (dartType.isIndexableElementType(tp)) {
      // Select a list or map type that contains elements of type tp.
      var iterType = oneOfSet(dartType.indexableElementTypes(tp));
      // For `collection[key] <op>= value` to work, collection must not be a
      // Map or Expando because their subscript operators return a nullable
      // type.
      if (assignOp != null && assignOp != "=") {
        while (!DartType.isListType(iterType)) {
          iterType = oneOfSet(dartType.indexableElementTypes(tp));
        }
      }
      // Get the index type for the respective list or map type.
      final indexType = dartType.indexType(iterType);
      // Emit a variable of the selected list or map type.
      ret = emitScalarVar(iterType, isLhs: isLhs, rhsFilter: rhsFilter);
      emitSquareBraceWrapped(() =>
          // Emit an expression resolving into the index type. For
          // collection type, only constant collections are used
          // to avoid rehashing the same value into many entries.
          DartType.isCollectionType(indexType)
              ? emitConstCollection(depth + 1, indexType)
              : emitExpr(depth + 1, indexType));
      // Map.[] and Expando.[] have a nullable result, but we should not write
      // map[key]! = value.
      if (!tp.isNullable && !isLhs) {
        emit('!');
      }
    } else {
      ret = emitScalarVar(tp,
          isLhs: isLhs, rhsFilter: rhsFilter); // resort to scalar
    }
    return ret;
  }

  String? emitVar(int depth, DartType tp,
      {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
    switch (choose(2)) {
      case 0:
        return emitScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
      default:
        return emitSubscriptedVar(depth, tp,
            isLhs: isLhs, assignOp: assignOp, rhsFilter: rhsFilter);
    }
  }

  void emitTerminal(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    switch (choose(2)) {
      case 0:
        emitLiteral(depth, tp, rhsFilter: rhsFilter);
        break;
      default:
        emitVar(depth, tp, rhsFilter: rhsFilter);
        break;
    }
  }

  // Emit expression with unary operator: (~(x))
  void emitUnaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (dartType.uniOps(tp).isEmpty) {
      return emitTerminal(depth, tp, rhsFilter: rhsFilter);
    }
    emitParenWrapped(() {
      emit(oneOfSet(dartType.uniOps(tp)));
      var uniOpParam = tp.toNonNullable();
      emitParenWrapped(
          () => emitExpr(depth + 1, uniOpParam, rhsFilter: rhsFilter));
    });
  }

  // Emit expression with binary operator: (x + y)
  void emitBinaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (dartType.binOps(tp).isEmpty) {
      return emitLiteral(depth, tp);
    }

    var binop = oneOfSet(dartType.binOps(tp));
    var binOpParams = oneOfSet(dartType.binOpParameters(tp, binop));

    // Avoid recursive assignments of the form a = a * 100.
    if (binop == '*') {
      rhsFilter?.consume();
    }

    // Reduce the number of operations of type growable * large value
    // as these might lead to timeouts and/or oom errors.
    if (binop == '*' &&
        DartType.isGrowableType(binOpParams[0]) &&
        dartType.isInterfaceOfType(binOpParams[1], DartType.NUM)) {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitLiteral(depth + 1, binOpParams[1], smallPositiveValue: true);
      });
    } else if (binop == '*' &&
        DartType.isGrowableType(binOpParams[1]) &&
        dartType.isInterfaceOfType(binOpParams[0], DartType.NUM)) {
      emitParenWrapped(() {
        emitLiteral(depth + 1, binOpParams[0], smallPositiveValue: true);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    } else {
      emitParenWrapped(() {
        emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
        emit(' $binop ');
        emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
      });
    }
  }

  // Emit expression with ternary operator: (b ? x : y)
  void emitTernaryExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) =>
      emitParenWrapped(() {
        emitExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter);
        emit(' ? ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
        emit(' : ');
        emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
      });

  // Emit expression with pre/post-increment/decrement operator: (x++)
  void emitPreOrPostExpr(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    if (tp == DartType.INT) {
      emitParenWrapped(() {
        var pre = coinFlip();
        if (pre) {
          emitPreOrPostOp(tp);
        }
        emitScalarVar(tp, isLhs: true);
        if (!pre) {
          emitPreOrPostOp(tp);
        }
      });
    } else {
      emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
    }
  }

  bool isTypedDataFloatType(List<DartType> proto) {
    for (var i = 0; i < proto.length; ++i) {
      if (DartLib.typedDataFloatTypes.contains(proto[i])) {
        return true;
      }
    }
    return false;
  }

  // Emit library call.
  void emitLibraryCall(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    var lib = getLibraryMethod(tp);
    if (lib == null || (!fp && isTypedDataFloatType(lib.proto))) {
      // We cannot find a library method, or we found a library method but its
      // prototype has a floating point type, and fp is disabled. This can only
      // happen for non-void types. In those cases, we resort to a literal.
      assert(tp != DartType.VOID);
      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
      return;
    }
    emitParenWrapped(() {
      var prototype = lib.proto;
      // Receiver.
      if (prototype[0] != DartType.VOID) {
        emitParenWrapped(() => emitArg(
            depth + 1, prototype[0], lib.getRestriction(0),
            rhsFilter: rhsFilter));
        emit('.');
      }
      // Call.
      emit('${lib.name}');
      // Parameters.
      if (lib.isMethod) {
        emitParenWrapped(() {
          if (prototype[1] != DartType.VOID) {
            emitCommaSeparated(
                (int i) => emitArg(
                    depth + 1, prototype[i], lib.getRestriction(i),
                    rhsFilter: rhsFilter),
                prototype.length,
                start: 1);
          }
        });
      }
      // Add cast to avoid error of double or int being interpreted as num.
      if (dartType.isInterfaceOfType(tp, DartType.NUM)) {
        emit(' as ${tp.name}');
      }
    });
    if (includeSemicolon) {
      emit(';');
    }
  }

  // Helper for a method call.
  bool pickedCall(int depth, DartType tp, List<Method> methods, int m,
      {RhsFilter? rhsFilter}) {
    for (var i = m - 1; i >= 0; i--) {
      if (tp == methods[i].returnType) {
        var isRecursiveCall = (currentMethod == methods[i]);
        if (isRecursiveCall && !methods[i].recursionAllowed) {
          continue;
        }
        methods[i].emitCall(depth + 1,
            rhsFilter: rhsFilter, isRecursiveCall: isRecursiveCall);
        return true;
      }
    }
    return false;
  }

  // Emit method call within the program.
  void emitMethodCall(int depth, DartType tp, {RhsFilter? rhsFilter}) {
    // Only call an already emitted method or the current method to avoid mutual recursion.
    if (currentClassIndex == null) {
      // Outside a class but inside a method: call backward in global methods.
      if (currentMethodIndex != null &&
          pickedCall(depth, tp, globalMethods, currentMethodIndex! + 1,
              rhsFilter: rhsFilter)) {
        return;
      }
    } else {
      var classIndex = currentClassIndex;
      // Chase randomly up in class hierarchy.
      while (classParents[classIndex!] > 0) {
        if (coinFlip()) {
          break;
        }
        classIndex = classParents[classIndex];
      }
      var m1 = 0;
      // Inside a class: try to call backwards into current or parent class
      // methods first.
      if (currentMethodIndex == null || classIndex != currentClassIndex) {
        // If currently emitting the 'run' method or calling into a parent class
        // pick any of the current or parent class methods respectively.
        m1 = classMethods[classIndex].length;
      } else {
        // If calling into the current class from any method other than 'run'
        // pick one of the already emitted methods or the current method.
        // We allow simple recursion but avoid mutual recursion.
        // (to avoid infinite recursions).
        m1 = currentMethodIndex! + 1;
      }
      final m2 = globalMethods.length;
      if (pickedCall(depth, tp, classMethods[classIndex], m1,
              rhsFilter: rhsFilter) ||
          pickedCall(depth, tp, globalMethods, m2, rhsFilter: rhsFilter)) {
        return;
      }
    }
    emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal.
  }

  // Emit expression.
  void emitExpr(int depth, DartType tp,
      {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
    final resetExprStmt = processExprOpen(tp);
    // Continuing nested expressions becomes less likely as the depth grows.
    if (choose(depth + 1) > exprDepth) {
      emitTerminal(depth, tp, rhsFilter: rhsFilter);
    } else {
      // Possibly nested expression.
      switch (choose(7)) {
        case 0:
          emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 1:
          emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 2:
          emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 3:
          emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
          break;
        case 4:
          emitLibraryCall(depth, tp,
              rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        case 5:
          emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
          break;
        default:
          emitTerminal(depth, tp, rhsFilter: rhsFilter);
          break;
      }
    }
    processExprClose(resetExprStmt);
    if (includeSemicolon) {
      emit(';');
    }
  }

  //
  // Operators.
  //

  // Emit same type in-out increment operator.
  void emitPreOrPostOp(DartType tp) {
    assert(tp == DartType.INT);
    emit(oneOf(const <String>['++', '--']));
  }

  // Emit one type in, boolean out operator.
  void emitRelOp(DartType tp) {
    if (tp == DartType.INT || tp == DartType.DOUBLE) {
      emit(oneOf(const <String>[' > ', ' >= ', ' < ', ' <= ', ' != ', ' == ']));
    } else {
      emit(oneOf(const <String>[' != ', ' == ']));
    }
  }

  //
  // Library methods.
  //

  // Get a library method that returns given type.
  DartLib? getLibraryMethod(DartType tp) =>
      api.typeToLibraryMethods.containsKey(tp)
          ? oneOf(api.typeToLibraryMethods[tp]!)
          : null;

  // Emit a library argument, possibly subject to restrictions.
  void emitArg(int depth, DartType type, Restriction restriction,
      {RhsFilter? rhsFilter}) {
    if ((type == DartType.INT) && (restriction == Restriction.small)) {
      emitSmallPositiveInt();
    } else if ((type == DartType.DOUBLE) && !fp) {
      // resort to INT if floating point is disabled.
      emitExpr(depth, DartType.INT, rhsFilter: rhsFilter);
    } else if ((type == DartType.STRING) &&
        (restriction == Restriction.small)) {
      emitString(length: 2);
    } else {
      emitExpr(depth, type, rhsFilter: rhsFilter);
    }
  }

  //
  // Types.
  //

  List<DartType> fillTypes1({int limit = 4, bool isFfi = false}) {
    final list = <DartType>[];
    for (var i = 0, n = chooseOneUpTo(limit); i < n; i++) {
      if (isFfi) {
        list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
      } else {
        list.add(oneOfSet(dartType.allTypes));
      }
    }
    return list;
  }

  List<List<DartType>> fillTypes2(
      {bool isFfi = false, int limit2 = 4, int limit1 = 4}) {
    final list = <List<DartType>>[];
    for (var i = 0, n = chooseOneUpTo(limit2); i < n; i++) {
      list.add(fillTypes1(limit: limit1, isFfi: isFfi));
    }
    return list;
  }

  List<DartType>? getCurrentProto() {
    if (currentClassIndex != null) {
      if (currentMethodIndex != null) {
        return classMethods[currentClassIndex!][currentMethodIndex!].parameters;
      }
    } else if (currentMethodIndex != null) {
      return globalMethods[currentMethodIndex!].parameters;
    }
    return null;
  }

  List<DartType>? getCurrentFields() {
    if (currentClassIndex != null) {
      return classFields[currentClassIndex!];
    }
    return null;
  }

  void emitFfiType(DartType tp) {
    if (tp == DartType.INT) {
      emit(oneOf(
          const <String>['ffi.Int8', 'ffi.Int16', 'ffi.Int32', 'ffi.Int64']));
    } else if (tp == DartType.DOUBLE) {
      emit(oneOf(const <String>['ffi.Float', 'ffi.Double']));
    } else {
      throw 'Invalid FFI type ${tp.name}';
    }
  }

  void emitFfiTypedef(Method method) {
    var pars = method.parameters;
    emit('typedef ${method.name}Type = ');
    emitFfiType(pars[0]);
    emit(' Function');
    emitParenWrapped(
        () => emitCommaSeparated((int i) => emitFfiType(pars[i]), pars.length,
            start: 1),
        includeSemicolon: true);
    emitNewline();
    emitNewline();
  }

  //
  // Output.
  //

  // Emits a newline to the program.
  void emitNewline() => emit('', newline: true);

  // Emits indentation based on the current indentation count.
  void emitIndentation() => file.writeStringSync(' ' * indent);

  // Emits indented line to append to program.
  void emitLn(String line, {bool newline = true}) {
    emitIndentation();
    emit(line, newline: newline);
  }

  // Emits text to append to program.
  void emit(String txt, {bool newline = false}) {
    if (skipStmt || skipExpr) {
      return;
    }
    file.writeStringSync(txt);
    if (newline) {
      file.writeStringSync('\n');
    }
  }

  // Special return code to handle oom errors.
  static const oomExitCode = 254;

  // Random seed used to generate program.
  final int seed;

  // Enables floating-point operations.
  final bool fp;

  // Enables FFI method calls.
  final bool ffi;

  // Disables nested types.
  final bool flatTp;

  // File used for output.
  final RandomAccessFile file;

  // Library and ffi api.
  late DartApi api;

  // Program variables.
  late Random rand;
  int indent = 0;
  int nest = 0;
  int? currentClassIndex;
  Method? currentMethod;
  int? currentMethodIndex;

  // DartType instance.
  late DartType dartType;

  // Types of local variables currently in scope.
  late List<DartType?> localVars;

  // Types of global variables.
  late List<DartType> globalVars;

  // Names of currently active iterator variables.
  // These are tracked to avoid modifications within the loop body,
  // which can lead to infinite loops.
  late List<String?> iterVars;

  // List of all global methods.
  late List<Method> globalMethods;

  // Types of fields over all classes.
  late List<List<DartType>> classFields;

  // List of methods over all classes.
  late List<List<Method>> classMethods;

  // List of virtual functions per class. Map is from parent class index to List
  // of overloaded functions from that parent.
  late List<Map<int, List<int>>> virtualClassMethods;

  // Parent class indices for all classes.
  late List<int> classParents;

  // Minimization mode extensions.
  final bool minimize;
  BigInt? smask;
  BigInt? emask;
  bool skipStmt = false;
  bool skipExpr = false;
  bool skipExprCntr = false;
  int stmtCntr = 0;
  int exprCntr = 0;

  // Interesting characters.
  static const List<String> interestingChars = [
    '\\u2665',
    '\\u{1f600}', // rune
  ];

  // Regular characters.
  static const regularChars =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';

  // Interesting integer values.
  static const List<int> interestingIntegers = [
    0x0000000000000000,
    0x0000000000000001,
    0x000000007fffffff,
    0x0000000080000000,
    0x0000000080000001,
    0x00000000ffffffff,
    0x0000000100000000,
    0x0000000100000001,
    0x000000017fffffff,
    0x0000000180000000,
    0x0000000180000001,
    0x00000001ffffffff,
    0x7fffffff00000000,
    0x7fffffff00000001,
    0x7fffffff7fffffff,
    0x7fffffff80000000,
    0x7fffffff80000001,
    0x7fffffffffffffff,
    0x8000000000000000,
    0x8000000000000001,
    0x800000007fffffff,
    0x8000000080000000,
    0x8000000080000001,
    0x80000000ffffffff,
    0x8000000100000000,
    0x8000000100000001,
    0x800000017fffffff,
    0x8000000180000000,
    0x8000000180000001,
    0x80000001ffffffff,
    0xffffffff00000000,
    0xffffffff00000001,
    0xffffffff7fffffff,
    0xffffffff80000000,
    0xffffffff80000001,
    0xffffffffffffffff
  ];
}

// Generate seed. By default (no user-defined nonzero seed given),
// pick the system's best way of seeding randomness and then pick
// a user-visible nonzero seed.
int getSeed(String userSeed) {
  var seed = int.parse(userSeed);
  if (seed == 0) {
    final rand = Random();
    while (seed == 0) {
      seed = rand.nextInt(1 << 32);
    }
  }
  return seed;
}

/// Main driver when dartfuzz.dart is run stand-alone.
void main(List<String> arguments) {
  const kSeed = 'seed';
  const kFp = 'fp';
  const kFfi = 'ffi';
  const kFlat = 'flat';
  const kMini = 'mini';
  const kSMask = 'smask';
  const kEMask = 'emask';
  final parser = ArgParser()
    ..addOption(kSeed,
        help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
    ..addFlag(kFp, help: 'enables floating-point operations', defaultsTo: true)
    ..addFlag(kFfi,
        help: 'enables FFI method calls (default: off)', defaultsTo: false)
    ..addFlag(kFlat,
        help: 'enables flat types (default: off)', defaultsTo: false)
    // Minimization mode extensions.
    ..addFlag(kMini,
        help: 'enables minimization mode (default: off)', defaultsTo: false)
    ..addOption(kSMask,
        help: 'Bitmask indicating which statements to omit'
            '(Bit=1 omits)',
        defaultsTo: '0')
    ..addOption(kEMask,
        help: 'Bitmask indicating which expressions to omit'
            '(Bit=1 omits)',
        defaultsTo: '0');
  final ArgResults results;
  try {
    results = parser.parse(arguments);
  } catch (e) {
    print('Usage: dart dartfuzz.dart [OPTIONS] FILENAME\n${parser.usage}\n$e');
    exitCode = 255;
    return;
  }
  final seed = getSeed(results[kSeed]);
  final fp = results[kFp];
  final ffi = results[kFfi];
  final flatTp = results[kFlat];
  final file = File(results.rest.single).openSync(mode: FileMode.write);
  final minimize = results[kMini];
  final smask = BigInt.parse(results[kSMask]);
  final emask = BigInt.parse(results[kEMask]);
  final dartFuzz = DartFuzz(seed, fp, ffi, flatTp, file,
      minimize: minimize, smask: smask, emask: emask);
  dartFuzz.run();
  file.closeSync();
  // Print information that will be parsed by minimize.py
  if (minimize) {
    // Updated statement mask.
    // This might be different from the input parameter --smask
    // since masking a statement that contains nested statements leads to
    // those being masked as well.
    print(dartFuzz.smask!.toRadixString(10));
    // Total number of statements in the generated program.
    print(dartFuzz.stmtCntr);
    // Updated expression mask.
    // This might be different from the input parameter --emask
    // since masking a statement that contains expressions or
    // an expression that contains nested expressions leads to
    // those being masked as well.
    print(dartFuzz.emask!.toRadixString(10));
    // Total number of expressions in the generated program.
    print(dartFuzz.exprCntr);
  }
}
