// Copyright (c) 2012, 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.

part of dart.async;

/// A type representing values that are either `Future<T>` or `T`.
///
/// This class declaration is a public stand-in for an internal
/// future-or-value generic type, which is not a class type.
/// References to this class are resolved to the internal type.
///
/// It is a compile-time error for any class to extend, mix in or implement
/// `FutureOr`.
///
/// # Examples
/// ```dart
/// // The `Future<T>.then` function takes a callback [f] that returns either
/// // an `S` or a `Future<S>`.
/// Future<S> then<S>(FutureOr<S> f(T x), ...);
///
/// // `Completer<T>.complete` takes either a `T` or `Future<T>`.
/// void complete(FutureOr<T> value);
/// ```
///
/// # Advanced
/// The `FutureOr<int>` type is actually the "type union" of the types `int` and
/// `Future<int>`. This type union is defined in such a way that
/// `FutureOr<Object>` is both a super- and sub-type of `Object` (sub-type
/// because `Object` is one of the types of the union, super-type because
/// `Object` is a super-type of both of the types of the union). Together it
/// means that `FutureOr<Object>` is equivalent to `Object`.
///
/// As a corollary, `FutureOr<Object>` is equivalent to
/// `FutureOr<FutureOr<Object>>`, `FutureOr<Future<Object>>` is equivalent to
/// `Future<Object>`.
@pragma("vm:entry-point")
abstract class FutureOr<T> {
  // Private generative constructor, so that it is not subclassable, mixable, or
  // instantiable.
  FutureOr._() {
    throw new UnsupportedError("FutureOr can't be instantiated");
  }
}

/// The result of an asynchronous computation.
///
/// An _asynchronous computation_ cannot provide a result immediately
/// when it is started, unlike a synchronous computation which does compute
/// a result immediately by either returning a value or by throwing.
/// An asynchronous computation may need to wait for something external
/// to the program (reading a file, querying a database, fetching a web page)
/// which takes time.
/// Instead of blocking all computation until the result is available,
/// the asynchronous computation immediately returns a `Future`
/// which will *eventually* "complete" with the result.
///
/// ### Asynchronous programming
///
/// To perform an asynchronous computation, you use an `async` function
/// which always produces a future.
/// Inside such an asynchronous function, you can use the `await` operation
/// to delay execution until another asynchronous computation has a result.
/// While execution of the awaiting function is delayed,
/// the program is not blocked, and can continue doing other things.
///
/// Example:
/// ```dart
/// import "dart:io";
/// Future<bool> fileContains(String path, String needle) async {
///    var haystack = await File(path).readAsString();
///    return haystack.contains(needle);
/// }
/// ```
/// Here the `File.readAsString` method from `dart:io` is an asychronous
/// function returning a `Future<String>`.
/// The `fileContains` function is marked with `async` right before its body,
/// which means that you can use `await` insider it,
/// and that it must return a future.
/// The call to `File(path).readAsString()` initiates reading the file into
/// a string and produces a `Future<String>` which will eventually contain the
/// result.
/// The `await` then waits for that future to complete with a string
/// (or an error, if reading the file fails).
/// While waiting, the program can do other things.
/// When the future completes with a string, the `fileContains` function
/// computes a boolean and returns it, which then completes the original
/// future that it returned when first called.
///
/// If a future completes with an *error*, awaiting that future will
/// (re-)throw that error. In the example here, we can add error checking:
/// ```dart
/// import "dart:io";
/// Future<bool> fileContains(String path, String needle) async {
///   try {
///     var haystack = await File(path).readAsString();
///     return haystack.contains(needle);
///   } on FileSystemException catch (exception, stack) {
///     _myLog.logError(exception, stack);
///     return false;
///   }
/// }
/// ```
/// You use a normal `try`/`catch` to catch the failures of awaited
/// asynchronous computations.
///
/// In general, when writing asynchronous code, you should always await a
/// future when it is produced, and not wait until after another asynchronous
/// delay. That ensures that you are ready to receive any error that the
/// future might produce, which is important because an asynchronous error
/// that no-one is awaiting is an *uncaught* error and may terminate
/// the running program.
///
/// ### Programming with the `Future` API.
///
/// The `Future` class also provides a more direct, low-level functionality
/// for accessing the result that it completes with.
/// The `async` and `await` language features are built on top of this
/// functionality, and it sometimes makes sense to use it directly.
/// There are things that you cannot do by just `await`ing one future at
/// a time.
///
/// With a [Future], you can manually register callbacks
/// that handle the value, or error, once it is available.
/// For example:
/// ```dart
/// Future<int> future = getFuture();
/// future.then((value) => handleValue(value))
///       .catchError((error) => handleError(error));
/// ```
/// Since a [Future] can be completed in two ways,
/// either with a value (if the asynchronous computation succeeded)
/// or with an error (if the computation failed),
/// you can install callbacks for either or both cases.
///
/// In some cases we say that a future is completed *with another future*.
/// This is a short way of stating that the future is completed in the same way,
/// with the same value or error,
/// as the other future once that other future itself completes.
/// Most functions in the platform libraries that complete a future
/// (for example [Completer.complete] or [Future.value]),
/// also accepts another future, and automatically handles forwarding
/// the result to the future being completed.
///
/// The result of registering callbacks is itself a `Future`,
/// which in turn is completed with the result of invoking the
/// corresponding callback with the original future's result.
/// The new future is completed with an error if the invoked callback throws.
/// For example:
/// ```dart
/// Future<int> successor = future.then((int value) {
///     // Invoked when the future is completed with a value.
///     return 42;  // The successor is completed with the value 42.
///   },
///   onError: (e) {
///     // Invoked when the future is completed with an error.
///     if (canHandle(e)) {
///       return 499;  // The successor is completed with the value 499.
///     } else {
///       throw e;  // The successor is completed with the error e.
///     }
///   });
/// ```
///
/// If a future does not have any registered handler when it completes
/// with an error, it forwards the error to an "uncaught-error handler".
/// This behavior ensures that no error is silently dropped.
/// However, it also means that error handlers should be installed early,
/// so that they are present as soon as a future is completed with an error.
/// The following example demonstrates this potential bug:
/// ```dart
/// var future = getFuture();
/// Timer(const Duration(milliseconds: 5), () {
///   // The error-handler is not attached until 5 ms after the future has
///   // been received. If the future fails before that, the error is
///   // forwarded to the global error-handler, even though there is code
///   // (just below) to eventually handle the error.
///   future.then((value) { useValue(value); },
///               onError: (e) { handleError(e); });
/// });
/// ```
///
/// When registering callbacks, it's often more readable to register the two
/// callbacks separately, by first using [then] with one argument
/// (the value handler) and using a second [catchError] for handling errors.
/// Each of these will forward the result that they don't handle
/// to their successors, and together they handle both value and error result.
/// It also has the additional benefit of the [catchError] handling errors in the
/// [then] value callback too.
/// Using sequential handlers instead of parallel ones often leads to code that
/// is easier to reason about.
/// It also makes asynchronous code very similar to synchronous code:
/// ```dart
/// // Synchronous code.
/// try {
///   int value = foo();
///   return bar(value);
/// } catch (e) {
///   return 499;
/// }
/// ```
///
/// Equivalent asynchronous code, based on futures:
/// ```dart
/// Future<int> asyncValue = Future(foo);  // Result of foo() as a future.
/// asyncValue.then((int value) {
///   return bar(value);
/// }).catchError((e) {
///   return 499;
/// });
/// ```
///
/// Similar to the synchronous code, the error handler (registered with
/// [catchError]) is handling any errors thrown by either `foo` or `bar`.
/// If the error-handler had been registered as the `onError` parameter of
/// the `then` call, it would not catch errors from the `bar` call.
///
/// Futures can have more than one callback-pair registered. Each successor is
/// treated independently and is handled as if it was the only successor.
///
/// A future may also fail to ever complete. In that case, no callbacks are
/// called. That situation should generally be avoided if possible, unless
/// it's very clearly documented.
abstract class Future<T> {
  /// A `Future<Null>` completed with `null`.
  ///
  /// Currently shared with `dart:internal`.
  /// If that future can be removed, then change this back to
  /// `_Future<Null>.zoneValue(null, _rootZone);`
  static final _Future<Null> _nullFuture = nullFuture as _Future<Null>;

  /// A `Future<bool>` completed with `false`.
  static final _Future<bool> _falseFuture =
      new _Future<bool>.zoneValue(false, _rootZone);

  /// Creates a future containing the result of calling [computation]
  /// asynchronously with [Timer.run].
  ///
  /// If the result of executing [computation] throws, the returned future is
  /// completed with the error.
  ///
  /// If the returned value is itself a [Future], completion of
  /// the created future will wait until the returned future completes,
  /// and will then complete with the same result.
  ///
  /// If a non-future value is returned, the returned future is completed
  /// with that value.
  factory Future(FutureOr<T> computation()) {
    _Future<T> result = new _Future<T>();
    Timer.run(() {
      try {
        result._complete(computation());
      } catch (e, s) {
        _completeWithErrorCallback(result, e, s);
      }
    });
    return result;
  }

  /// Creates a future containing the result of calling [computation]
  /// asynchronously with [scheduleMicrotask].
  ///
  /// If executing [computation] throws,
  /// the returned future is completed with the thrown error.
  ///
  /// If calling [computation] returns a [Future], completion of
  /// the created future will wait until the returned future completes,
  /// and will then complete with the same result.
  ///
  /// If calling [computation] returns a non-future value,
  /// the returned future is completed with that value.
  factory Future.microtask(FutureOr<T> computation()) {
    _Future<T> result = new _Future<T>();
    scheduleMicrotask(() {
      try {
        result._complete(computation());
      } catch (e, s) {
        _completeWithErrorCallback(result, e, s);
      }
    });
    return result;
  }

  /// Returns a future containing the result of immediately calling
  /// [computation].
  ///
  /// If calling [computation] throws, the returned future is completed with the
  /// error.
  ///
  /// If calling [computation] returns a `Future<T>`, that future is returned.
  ///
  /// If calling [computation] returns a non-future value,
  /// a future is returned which has been completed with that value.
  factory Future.sync(FutureOr<T> computation()) {
    try {
      var result = computation();
      if (result is Future<T>) {
        return result;
      } else {
        // TODO(40014): Remove cast when type promotion works.
        return new _Future<T>.value(result as dynamic);
      }
    } catch (error, stackTrace) {
      var future = new _Future<T>();
      AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
      if (replacement != null) {
        future._asyncCompleteError(replacement.error, replacement.stackTrace);
      } else {
        future._asyncCompleteError(error, stackTrace);
      }
      return future;
    }
  }

  /// Creates a future completed with [value].
  ///
  /// If [value] is a future, the created future waits for the
  /// [value] future to complete, and then completes with the same result.
  /// Since a [value] future can complete with an error, so can the future
  /// created by [Future.value], even if the name suggests otherwise.
  ///
  /// If [value] is not a [Future], the created future is completed
  /// with the [value] value,
  /// equivalently to `new Future<T>.sync(() => value)`.
  ///
  /// If [value] is omitted or `null`, it is converted to `FutureOr<T>` by
  /// `value as FutureOr<T>`. If `T` is not nullable, then a non-`null` [value]
  /// must be provided, otherwise the construction throws.
  ///
  /// Use [Completer] to create a future now and complete it later.
  @pragma("vm:entry-point")
  @pragma("vm:prefer-inline")
  factory Future.value([FutureOr<T>? value]) {
    return new _Future<T>.immediate(value == null ? value as T : value);
  }

  /// Creates a future that completes with an error.
  ///
  /// The created future will be completed with an error in a future microtask.
  /// This allows enough time for someone to add an error handler on the future.
  /// If an error handler isn't added before the future completes, the error
  /// will be considered unhandled.
  ///
  /// Use [Completer] to create a future and complete it later.
  factory Future.error(Object error, [StackTrace? stackTrace]) {
    // TODO(40614): Remove once non-nullability is sound.
    checkNotNullable(error, "error");
    if (!identical(Zone.current, _rootZone)) {
      AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
      if (replacement != null) {
        error = replacement.error;
        stackTrace = replacement.stackTrace;
      }
    }
    stackTrace ??= AsyncError.defaultStackTrace(error);
    return new _Future<T>.immediateError(error, stackTrace);
  }

  /// Creates a future that runs its computation after a delay.
  ///
  /// The [computation] will be executed after the given [duration] has passed,
  /// and the future is completed with the result of the computation.
  ///
  /// If [computation] returns a future,
  /// the future returned by this constructor will complete with the value or
  /// error of that future.
  ///
  /// If the duration is 0 or less,
  /// it completes no sooner than in the next event-loop iteration,
  /// after all microtasks have run.
  ///
  /// If [computation] is omitted,
  /// it will be treated as if [computation] was `() => null`,
  /// and the future will eventually complete with the `null` value.
  /// In that case, [T] must be nullable.
  ///
  /// If calling [computation] throws, the created future will complete with the
  /// error.
  ///
  /// See also [Completer] for a way to create and complete a future at a
  /// later time that isn't necessarily after a known fixed duration.
  factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
    if (computation == null && !typeAcceptsNull<T>()) {
      throw ArgumentError.value(
          null, "computation", "The type parameter is not nullable");
    }
    _Future<T> result = new _Future<T>();
    new Timer(duration, () {
      if (computation == null) {
        result._complete(null as T);
      } else {
        try {
          result._complete(computation());
        } catch (e, s) {
          _completeWithErrorCallback(result, e, s);
        }
      }
    });
    return result;
  }

  /// Waits for multiple futures to complete and collects their results.
  ///
  /// Returns a future which will complete once all the provided futures
  /// have completed, either with their results, or with an error if any
  /// of the provided futures fail.
  ///
  /// The value of the returned future will be a list of all the values that
  /// were produced in the order that the futures are provided by iterating
  /// [futures].
  ///
  /// If any future completes with an error,
  /// then the returned future completes with that error.
  /// If further futures also complete with errors, those errors are discarded.
  ///
  /// If `eagerError` is true, the returned future completes with an error
  /// immediately on the first error from one of the futures. Otherwise all
  /// futures must complete before the returned future is completed (still with
  /// the first error; the remaining errors are silently dropped).
  ///
  /// In the case of an error, [cleanUp] (if provided), is invoked on any
  /// non-null result of successful futures.
  /// This makes it possible to `cleanUp` resources that would otherwise be
  /// lost (since the returned future does not provide access to these values).
  /// The [cleanUp] function is unused if there is no error.
  ///
  /// The call to [cleanUp] should not throw. If it does, the error will be an
  /// uncaught asynchronous error.
  @pragma("vm:recognized", "other")
  static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
      {bool eagerError = false, void cleanUp(T successValue)?}) {
    // This is a VM recognised method, and the _future variable is deliberately
    // allocated in a specific slot in the closure context for stack unwinding.
    final _Future<List<T>> _future = _Future<List<T>>();
    List<T?>? values; // Collects the values. Set to null on error.
    int remaining = 0; // How many futures are we waiting for.
    late Object error; // The first error from a future.
    late StackTrace stackTrace; // The stackTrace that came with the error.

    // Handle an error from any of the futures.
    void handleError(Object theError, StackTrace theStackTrace) {
      remaining--;
      List<T?>? valueList = values;
      if (valueList != null) {
        if (cleanUp != null) {
          for (var value in valueList) {
            if (value != null) {
              // Ensure errors from cleanUp are uncaught.
              T cleanUpValue = value;
              new Future.sync(() {
                cleanUp(cleanUpValue);
              });
            }
          }
        }
        values = null;
        if (remaining == 0 || eagerError) {
          _future._completeError(theError, theStackTrace);
        } else {
          error = theError;
          stackTrace = theStackTrace;
        }
      } else if (remaining == 0 && !eagerError) {
        _future._completeError(error, stackTrace);
      }
    }

    try {
      // As each future completes, put its value into the corresponding
      // position in the list of values.
      for (var future in futures) {
        int pos = remaining;
        future.then((T value) {
          remaining--;
          List<T?>? valueList = values;
          if (valueList != null) {
            valueList[pos] = value;
            if (remaining == 0) {
              _future._completeWithValue(List<T>.from(valueList));
            }
          } else {
            if (cleanUp != null && value != null) {
              // Ensure errors from cleanUp are uncaught.
              new Future.sync(() {
                cleanUp(value);
              });
            }
            if (remaining == 0 && !eagerError) {
              // If eagerError is false, and valueList is null, then
              // error and stackTrace have been set in handleError above.
              _future._completeError(error, stackTrace);
            }
          }
        }, onError: handleError);
        // Increment the 'remaining' after the call to 'then'.
        // If that call throws, we don't expect any future callback from
        // the future, and we also don't increment remaining.
        remaining++;
      }
      if (remaining == 0) {
        return _future.._completeWithValue(<T>[]);
      }
      values = new List<T?>.filled(remaining, null);
    } catch (e, st) {
      // The error must have been thrown while iterating over the futures
      // list, or while installing a callback handler on the future.
      // This is a breach of the `Future` protocol, but we try to handle it
      // gracefully.
      if (remaining == 0 || eagerError) {
        // Throw a new Future.error.
        // Don't just call `_future._completeError` since that would propagate
        // the error too eagerly, not giving the callers time to install
        // error handlers.
        // Also, don't use `_asyncCompleteError` since that one doesn't give
        // zones the chance to intercept the error.
        return new Future.error(e, st);
      } else {
        // Don't allocate a list for values, thus indicating that there was an
        // error.
        // Set error to the caught exception.
        error = e;
        stackTrace = st;
      }
    }
    return _future;
  }

  /// Returns the result of the first future in [futures] to complete.
  ///
  /// The returned future is completed with the result of the first
  /// future in [futures] to report that it is complete,
  /// whether it's with a value or an error.
  /// The results of all the other futures are discarded.
  ///
  /// If [futures] is empty, or if none of its futures complete,
  /// the returned future never completes.
  static Future<T> any<T>(Iterable<Future<T>> futures) {
    var completer = new Completer<T>.sync();
    void onValue(T value) {
      if (!completer.isCompleted) completer.complete(value);
    }

    void onError(Object error, StackTrace stack) {
      if (!completer.isCompleted) completer.completeError(error, stack);
    }

    for (var future in futures) {
      future.then(onValue, onError: onError);
    }
    return completer.future;
  }

  /// Performs an action for each element of the iterable, in turn.
  ///
  /// The [action] may be either synchronous or asynchronous.
  ///
  /// Calls [action] with each element in [elements] in order.
  /// If the call to [action] returns a `Future<T>`, the iteration waits
  /// until the future is completed before continuing with the next element.
  ///
  /// Returns a [Future] that completes with `null` when all elements have been
  /// processed.
  ///
  /// Non-[Future] return values, and completion-values of returned [Future]s,
  /// are discarded.
  ///
  /// Any error from [action], synchronous or asynchronous,
  /// will stop the iteration and be reported in the returned [Future].
  static Future forEach<T>(Iterable<T> elements, FutureOr action(T element)) {
    var iterator = elements.iterator;
    return doWhile(() {
      if (!iterator.moveNext()) return false;
      var result = action(iterator.current);
      if (result is Future) return result.then(_kTrue);
      return true;
    });
  }

  // Constant `true` function, used as callback by [forEach].
  static bool _kTrue(Object? _) => true;

  /// Performs an operation repeatedly until it returns `false`.
  ///
  /// The operation, [action], may be either synchronous or asynchronous.
  ///
  /// The operation is called repeatedly as long as it returns either the [bool]
  /// value `true` or a `Future<bool>` which completes with the value `true`.
  ///
  /// If a call to [action] returns `false` or a [Future] that completes to
  /// `false`, iteration ends and the future returned by [doWhile] is completed
  /// with a `null` value.
  ///
  /// If a call to [action] throws or a future returned by [action] completes
  /// with an error, iteration ends and the future returned by [doWhile]
  /// completes with the same error.
  ///
  /// Calls to [action] may happen at any time,
  /// including immediately after calling `doWhile`.
  /// The only restriction is a new call to [action] won't happen before
  /// the previous call has returned, and if it returned a `Future<bool>`, not
  /// until that future has completed.
  static Future doWhile(FutureOr<bool> action()) {
    _Future<void> doneSignal = new _Future<void>();
    late void Function(bool) nextIteration;
    // Bind this callback explicitly so that each iteration isn't bound in the
    // context of all the previous iterations' callbacks.
    // This avoids, e.g., deeply nested stack traces from the stack trace
    // package.
    nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) {
      while (keepGoing) {
        FutureOr<bool> result;
        try {
          result = action();
        } catch (error, stackTrace) {
          // Cannot use _completeWithErrorCallback because it completes
          // the future synchronously.
          _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace);
          return;
        }
        if (result is Future<bool>) {
          result.then(nextIteration, onError: doneSignal._completeError);
          return;
        }
        // TODO(40014): Remove cast when type promotion works.
        keepGoing = result as bool;
      }
      doneSignal._complete(null);
    });
    nextIteration(true);
    return doneSignal;
  }

  /// Register callbacks to be called when this future completes.
  ///
  /// When this future completes with a value,
  /// the [onValue] callback will be called with that value.
  /// If this future is already completed, the callback will not be called
  /// immediately, but will be scheduled in a later microtask.
  ///
  /// If [onError] is provided, and this future completes with an error,
  /// the `onError` callback is called with that error and its stack trace.
  /// The `onError` callback must accept either one argument or two arguments
  /// where the latter is a [StackTrace].
  /// If `onError` accepts two arguments,
  /// it is called with both the error and the stack trace,
  /// otherwise it is called with just the error object.
  /// The `onError` callback must return a value or future that can be used
  /// to complete the returned future, so it must be something assignable to
  /// `FutureOr<R>`.
  ///
  /// Returns a new [Future]
  /// which is completed with the result of the call to `onValue`
  /// (if this future completes with a value)
  /// or to `onError` (if this future completes with an error).
  ///
  /// If the invoked callback throws,
  /// the returned future is completed with the thrown error
  /// and a stack trace for the error.
  /// In the case of `onError`,
  /// if the exception thrown is `identical` to the error argument to `onError`,
  /// the throw is considered a rethrow,
  /// and the original stack trace is used instead.
  ///
  /// If the callback returns a [Future],
  /// the future returned by `then` will be completed with
  /// the same result as the future returned by the callback.
  ///
  /// If [onError] is not given, and this future completes with an error,
  /// the error is forwarded directly to the returned future.
  ///
  /// In most cases, it is more readable to use [catchError] separately,
  /// possibly with a `test` parameter,
  /// instead of handling both value and error in a single [then] call.
  ///
  /// Note that futures don't delay reporting of errors until listeners are
  /// added. If the first `then` or `catchError` call happens
  /// after this future has completed with an error,
  /// then the error is reported as unhandled error.
  /// See the description on [Future].
  Future<R> then<R>(FutureOr<R> onValue(T value), {Function? onError});

  /// Handles errors emitted by this [Future].
  ///
  /// This is the asynchronous equivalent of a "catch" block.
  ///
  /// Returns a new [Future] that will be completed with either the result of
  /// this future or the result of calling the `onError` callback.
  ///
  /// If this future completes with a value,
  /// the returned future completes with the same value.
  ///
  /// If this future completes with an error,
  /// then [test] is first called with the error value.
  ///
  /// If `test` returns false, the exception is not handled by this `catchError`,
  /// and the returned future completes with the same error and stack trace
  /// as this future.
  ///
  /// If `test` returns `true`,
  /// [onError] is called with the error and possibly stack trace,
  /// and the returned future is completed with the result of this call
  /// in exactly the same way as for [then]'s `onError`.
  ///
  /// If `test` is omitted, it defaults to a function that always returns true.
  /// The `test` function should not throw, but if it does, it is handled as
  /// if the `onError` function had thrown.
  ///
  /// Note that futures don't delay reporting of errors until listeners are
  /// added. If the first `catchError` (or `then`) call happens after this future
  /// has completed with an error then the error is reported as unhandled error.
  /// See the description on [Future].
  // The `Function` below stands for one of two types:
  // - (dynamic) -> FutureOr<T>
  // - (dynamic, StackTrace) -> FutureOr<T>
  // Given that there is a `test` function that is usually used to do an
  // `isCheck` we should also expect functions that take a specific argument.
  Future<T> catchError(Function onError, {bool test(Object error)?});

  /// Registers a function to be called when this future completes.
  ///
  /// The [action] function is called when this future completes, whether it
  /// does so with a value or with an error.
  ///
  /// This is the asynchronous equivalent of a "finally" block.
  ///
  /// The future returned by this call, `f`, will complete the same way
  /// as this future unless an error occurs in the [action] call, or in
  /// a [Future] returned by the [action] call. If the call to [action]
  /// does not return a future, its return value is ignored.
  ///
  /// If the call to [action] throws, then `f` is completed with the
  /// thrown error.
  ///
  /// If the call to [action] returns a [Future], `f2`, then completion of
  /// `f` is delayed until `f2` completes. If `f2` completes with
  /// an error, that will be the result of `f` too. The value of `f2` is always
  /// ignored.
  ///
  /// This method is equivalent to:
  /// ```dart
  /// Future<T> whenComplete(action() {
  ///   return this.then((v) {
  ///     var f2 = action();
  ///     if (f2 is Future) return f2.then((_) => v);
  ///     return v;
  ///   }, onError: (e) {
  ///     var f2 = action();
  ///     if (f2 is Future) return f2.then((_) { throw e; });
  ///     throw e;
  ///   });
  /// }
  /// ```
  Future<T> whenComplete(FutureOr<void> action());

  /// Creates a [Stream] containing the result of this future.
  ///
  /// The stream will produce single data or error event containing the
  /// completion result of this future, and then it will close with a
  /// done event.
  ///
  /// If the future never completes, the stream will not produce any events.
  Stream<T> asStream();

  /// Time-out the future computation after [timeLimit] has passed.
  ///
  /// Returns a new future that completes with the same value as this future,
  /// if this future completes in time.
  ///
  /// If this future does not complete before `timeLimit` has passed,
  /// the [onTimeout] action is executed instead, and its result (whether it
  /// returns or throws) is used as the result of the returned future.
  /// The [onTimeout] function must return a [T] or a `Future<T>`.
  ///
  /// If `onTimeout` is omitted, a timeout will cause the returned future to
  /// complete with a [TimeoutException].
  Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?});
}

/// Explicitly ignores a future.
///
/// Not all futures need to be awaited.
/// The Dart linter has an optional ["unawaited futures" lint](https://dart-lang.github.io/linter/lints/unawaited_futures.html)
/// which enforces that potential futures
/// (expressions with a static type of [Future] or `Future?`)
/// in asynchronous functions are handled *somehow*.
/// If a particular future value doesn't need to be awaited,
/// you can call `unawaited(...)` with it, which will avoid the lint,
/// simply because the expression no longer has type [Future].
/// Using `unawaited` has no other effect.
/// You should use `unawaited` to convey the *intention* of
/// deliberately not waiting for the future.
///
/// If the future completes with an error,
/// it was likely a mistake to not await it.
/// That error will still occur and will be considered unhandled
/// unless the same future is awaited (or otherwise handled) elsewhere too.
/// Because of that, `unawaited` should only be used for futures that
/// are *expected* to complete with a value.
/// You can use [FutureExtensions.ignore] if you also don't want to know
/// about errors from this future.
@Since("2.15")
void unawaited(Future<void>? future) {}

/// Convenience methods on futures.
///
/// Adds functionality to futures which makes it easier to
/// write well-typed asynchronous code.
@Since("2.12")
extension FutureExtensions<T> on Future<T> {
  /// Handles errors on this future.
  ///
  /// Catches errors of type [E] that this future complete with.
  /// If [test] is supplied, only catches errors of type [E]
  /// where [test] returns `true`.
  /// If [E] is [Object], then all errors are potentially caught,
  /// depending only on a supplied [test].toString()
  ///
  /// If the error is caught,
  /// the returned future completes with the result of calling [handleError]
  /// with the error and stack trace.
  /// This result must be a value of the same type that this future
  /// could otherwise complete with.
  /// For example, if this future cannot complete with `null`,
  /// then [handleError] also cannot return `null`.
  /// Example:
  /// ```dart
  /// Future<T> retryOperation<T>(Future<T> operation(), T onFailure()) =>
  ///     operation().onError<RetryException>((e, s) {
  ///       if (e.canRetry) {
  ///         return retryOperation(operation, onFailure);
  ///       }
  ///       return onFailure();
  ///     });
  /// ```
  ///
  /// If [handleError] throws, the returned future completes
  /// with the thrown error and stack trace,
  /// except that if it throws the *same* error object again,
  /// then it is considered a "rethrow"
  /// and the original stack trace is retained.
  /// This can be used as an alternative to skipping the
  /// error in [test].
  /// Example:
  /// ```dart
  /// // Unwraps an an exceptions cause, if it has one.
  /// someFuture.onError<SomeException>((e, _) {
  ///   throw e.cause ?? e;
  /// });
  /// // vs.
  /// someFuture.onError<SomeException>((e, _) {
  ///   throw e.cause!;
  /// }, test: (e) => e.cause != null);
  /// ```
  ///
  /// If the error is not caught, the returned future
  /// completes with the same result, value or error,
  /// as this future.
  ///
  /// This method is effectively a more precisely typed version
  /// of [Future.catchError].
  /// It makes it easy to catch specific error types,
  /// and requires a correctly typed error handler function,
  /// rather than just [Function].
  /// Because of this, the error handlers must accept
  /// the stack trace argument.
  Future<T> onError<E extends Object>(
      FutureOr<T> handleError(E error, StackTrace stackTrace),
      {bool test(E error)?}) {
    // There are various ways to optimize this to avoid the double is E/as E
    // type check, but for now we are not optimizing the error path.
    return this.catchError(
        (Object error, StackTrace stackTrace) =>
            handleError(error as E, stackTrace),
        test: (Object error) => error is E && (test == null || test(error)));
  }

  /// Completely ignores this future and its result.
  ///
  /// Not all futures are important, not even if they contain errors,
  /// for example if a request was made, but the response is no longer needed.
  /// Simply ignoring a future can result in uncaught asynchronous errors.
  /// This method instead handles (and ignores) any values or errors
  /// coming from this future, making it safe to otherwise ignore
  /// the future.
  ///
  /// Use `ignore` to signal that the result of the future is
  /// no longer important to the program, not even if it's an error.
  /// If you merely want to silence the ["unawaited futures" lint](https://dart-lang.github.io/linter/lints/unawaited_futures.html),
  /// use the [unawaited] function instead.
  /// That will ensure that an unexpected error is still reported.
  @Since("2.14")
  void ignore() {
    var self = this;
    if (self is _Future<T>) {
      self._ignore();
    } else {
      self.then<void>(_ignore, onError: _ignore);
    }
  }

  static void _ignore(Object? _, [Object? __]) {}
}

/// Thrown when a scheduled timeout happens while waiting for an async result.
class TimeoutException implements Exception {
  /// Description of the cause of the timeout.
  final String? message;

  /// The duration that was exceeded.
  final Duration? duration;

  TimeoutException(this.message, [this.duration]);

  String toString() {
    String result = "TimeoutException";
    if (duration != null) result = "TimeoutException after $duration";
    if (message != null) result = "$result: $message";
    return result;
  }
}

/// A way to produce Future objects and to complete them later
/// with a value or error.
///
/// Most of the time, the simplest way to create a future is to just use
/// one of the [Future] constructors to capture the result of a single
/// asynchronous computation:
/// ```dart
/// Future(() { doSomething(); return result; });
/// ```
/// or, if the future represents the result of a sequence of asynchronous
/// computations, they can be chained using [Future.then] or similar functions
/// on [Future]:
/// ```dart
/// Future doStuff(){
///   return someAsyncOperation().then((result) {
///     return someOtherAsyncOperation(result);
///   });
/// }
/// ```
/// If you do need to create a Future from scratch — for example,
/// when you're converting a callback-based API into a Future-based
/// one — you can use a Completer as follows:
/// ```dart
/// class AsyncOperation {
///   final Completer _completer = new Completer();
///
///   Future<T> doOperation() {
///     _startOperation();
///     return _completer.future; // Send future object back to client.
///   }
///
///   // Something calls this when the value is ready.
///   void _finishOperation(T result) {
///     _completer.complete(result);
///   }
///
///   // If something goes wrong, call this.
///   void _errorHappened(error) {
///     _completer.completeError(error);
///   }
/// }
/// ```
abstract class Completer<T> {
  /// Creates a new completer.
  ///
  /// The general workflow for creating a new future is to 1) create a
  /// new completer, 2) hand out its future, and, at a later point, 3) invoke
  /// either [complete] or [completeError].
  ///
  /// The completer completes the future asynchronously. That means that
  /// callbacks registered on the future are not called immediately when
  /// [complete] or [completeError] is called. Instead the callbacks are
  /// delayed until a later microtask.
  ///
  /// Example:
  /// ```dart
  /// var completer = new Completer();
  /// handOut(completer.future);
  /// later: {
  ///   completer.complete('completion value');
  /// }
  /// ```
  factory Completer() => new _AsyncCompleter<T>();

  /// Completes the future synchronously.
  ///
  /// This constructor should be avoided unless the completion of the future is
  /// known to be the final result of another asynchronous operation. If in doubt
  /// use the default [Completer] constructor.
  ///
  /// Using an normal, asynchronous, completer will never give the wrong
  /// behavior, but using a synchronous completer incorrectly can cause
  /// otherwise correct programs to break.
  ///
  /// A synchronous completer is only intended for optimizing event
  /// propagation when one asynchronous event immediately triggers another.
  /// It should not be used unless the calls to [complete] and [completeError]
  /// are guaranteed to occur in places where it won't break `Future` invariants.
  ///
  /// Completing synchronously means that the completer's future will be
  /// completed immediately when calling the [complete] or [completeError]
  /// method on a synchronous completer, which also calls any callbacks
  /// registered on that future.
  ///
  /// Completing synchronously must not break the rule that when you add a
  /// callback on a future, that callback must not be called until the code
  /// that added the callback has completed.
  /// For that reason, a synchronous completion must only occur at the very end
  /// (in "tail position") of another synchronous event,
  /// because at that point, completing the future immediately is be equivalent
  /// to returning to the event loop and completing the future in the next
  /// microtask.
  ///
  /// Example:
  /// ```dart
  /// var completer = Completer.sync();
  /// // The completion is the result of the asynchronous onDone event.
  /// // No other operation is performed after the completion. It is safe
  /// // to use the Completer.sync constructor.
  /// stream.listen(print, onDone: () { completer.complete("done"); });
  /// ```
  /// Bad example. Do not use this code. Only for illustrative purposes:
  /// ```dart
  /// var completer = Completer.sync();
  /// completer.future.then((_) { bar(); });
  /// // The completion is the result of the asynchronous onDone event.
  /// // However, there is still code executed after the completion. This
  /// // operation is *not* safe.
  /// stream.listen(print, onDone: () {
  ///   completer.complete("done");
  ///   foo();  // In this case, foo() runs after bar().
  /// });
  /// ```
  factory Completer.sync() => new _SyncCompleter<T>();

  /// The future that is completed by this completer.
  ///
  /// The future that is completed when [complete] or [completeError] is called.
  Future<T> get future;

  /// Completes [future] with the supplied values.
  ///
  /// The value must be either a value of type [T]
  /// or a future of type `Future<T>`.
  /// If the value is omitted or `null`, and `T` is not nullable, the call
  /// to `complete` throws.
  ///
  /// If the value is itself a future, the completer will wait for that future
  /// to complete, and complete with the same result, whether it is a success
  /// or an error.
  ///
  /// Calling [complete] or [completeError] must be done at most once.
  ///
  /// All listeners on the future are informed about the value.
  void complete([FutureOr<T>? value]);

  /// Complete [future] with an error.
  ///
  /// Calling [complete] or [completeError] must be done at most once.
  ///
  /// Completing a future with an error indicates that an exception was thrown
  /// while trying to produce a value.
  ///
  /// If `error` is a `Future`, the future itself is used as the error value.
  /// If you want to complete with the result of the future, you can use:
  /// ```dart
  /// thisCompleter.complete(theFuture)
  /// ```
  /// or if you only want to handle an error from the future:
  /// ```dart
  /// theFuture.catchError(thisCompleter.completeError);
  /// ```
  void completeError(Object error, [StackTrace? stackTrace]);

  /// Whether the [future] has been completed.
  ///
  /// Reflects whether [complete] or [completeError] has been called.
  /// A `true` value doesn't necessarily mean that listeners of this future
  /// have been invoked yet, either because the completer usually waits until
  /// a later microtask to propagate the result, or because [complete]
  /// was called with a future that hasn't completed yet.
  ///
  /// When this value is `true`, [complete] and [completeError] must not be
  /// called again.
  bool get isCompleted;
}

// Helper function completing a _Future with error, but checking the zone
// for error replacement and missing stack trace first.
void _completeWithErrorCallback(
    _Future result, Object error, StackTrace? stackTrace) {
  AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
  if (replacement != null) {
    error = replacement.error;
    stackTrace = replacement.stackTrace;
  } else {
    stackTrace ??= AsyncError.defaultStackTrace(error);
  }
  if (stackTrace == null) throw "unreachable"; // TODO(40088).
  result._completeError(error, stackTrace);
}

// Like [_completeWithErrorCallback] but completes asynchronously.
void _asyncCompleteWithErrorCallback(
    _Future result, Object error, StackTrace? stackTrace) {
  AsyncError? replacement = Zone.current.errorCallback(error, stackTrace);
  if (replacement != null) {
    error = replacement.error;
    stackTrace = replacement.stackTrace;
  } else {
    stackTrace ??= AsyncError.defaultStackTrace(error);
  }
  if (stackTrace == null) {
    throw "unreachable"; // TODO(lrn): Remove when type promotion works.
  }
  result._asyncCompleteError(error, stackTrace);
}
