// 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.core;

/// An [Expando] allows adding new properties to objects.
///
/// Does not work on numbers, strings, booleans, `null`, `dart:ffi` pointers,
/// `dart:ffi` structs, or `dart:ffi` unions.
///
/// An `Expando` does not hold on to the added property value after an object
/// becomes inaccessible.
///
/// Since you can always create a new number that is identical to an existing
/// number, it means that an expando property on a number could never be
/// released. To avoid this, expando properties cannot be added to numbers.
/// The same argument applies to strings, booleans and `null`, which also have
/// literals that evaluate to identical values when they occur more than once.
///
/// There is no restriction on other classes, even for compile time constant
/// objects. Be careful if adding expando properties to compile time constants,
/// since they will stay alive forever.
class Expando<T extends Object> {
  /// The name of the this [Expando] as passed to the constructor.
  ///
  /// If no name was passed to the constructor, the value is the `null` value.
  final String? name;

  /// Creates a new [Expando]. The optional name is only used for
  /// debugging purposes and creating two different [Expando]s with the
  /// same name yields two [Expando]s that work on different properties
  /// of the objects they are used on.
  external Expando([String? name]);

  /// Expando toString method override.
  String toString() => "Expando:$name";

  /// Gets the value of this [Expando]'s property on the given object.
  ///
  /// If the object hasn't been expanded, the result is the `null` value.
  ///
  /// The object must not be a number, a string, a boolean, `null`, a
  /// `dart:ffi` pointer, a `dart:ffi` struct, or a `dart:ffi` union.
  external T? operator [](Object object);

  /// Sets this [Expando]'s property value on the given object to [value].
  ///
  /// Properties can effectively be removed again
  /// by setting their value to `null`.
  ///
  /// The object must not be a number, a string, a boolean, `null`, a
  /// `dart:ffi` pointer, a `dart:ffi` struct, or a `dart:ffi` union.
  external void operator []=(Object object, T? value);
}

/// A weak reference to a Dart object.
///
/// A _weak_ reference to the [target] object which may be cleared
/// (set to reference `null` instead) at any time
/// when there is no other ways for the program to access the target object.
///
/// _Being the target of a weak reference does not keep an object
/// from being garbage collected._
///
/// There are no guarantees that a weak reference will ever be cleared
/// even if all references to its target are weak references.
///
/// Not all objects are supported as targets for weak references.
/// The [WeakReference] constructor will reject any object that is not
/// supported as an [Expando] key.
@Since("2.17")
abstract class WeakReference<T extends Object> {
  /// Creates a [WeakReference] pointing to the given [target].
  ///
  /// The [target] must be an object supported as an [Expando] key,
  /// which means [target] cannot be a number, a string, a boolean,
  /// the `null` value, or certain other types of special objects.
  external factory WeakReference(T target);

  /// The current object weakly referenced by [this], if any.
  ///
  /// The value is either the object supplied in the constructor,
  /// or `null` if the weak reference has been cleared.
  T? get target;
}

/// A finalizer which can be attached to Dart objects.
///
/// A finalizer can create attachments between
/// the finalizer and any number of Dart values,
/// by calling [attach] with the value, along with a
/// _finalization token_ and an optional _attach key_,
/// which are part of the attachment.
///
/// When a Dart value becomes inaccessible to the program,
/// any finalizer that currently has an attachment to
/// the value *may* have its callback function called
/// with the attachment's finalization token.
///
/// Example:
/// ```dart template:none
/// // Keep the finalizer itself reachable, otherwise might not do anything.
/// final Finalizer<DBConnection> _finalizer = Finalizer((connection) {
///   connection.close();
/// });
///
/// /// Access the database.
/// Database connect() {
///   // Wraps the connection in a nicer user-facing API,
///   // *and* closes connection if the user forgets to.
///   var connection = _connectToDatabase();
///   var wrapper = Database._fromConnection(connection, _finalizer);
///   // Get finalizer callback when `wrapper` is no longer reachable.
///   _finalizer.attach(wrapper, connection, detach: wrapper);
///   return wrapper;
/// }
///
/// class Database {
///   final DBConnection _connection;
///   final Finalizer<Connection> _finalizer;
///   Database._fromConnection(this._connection, this._finalizer);
///
///   // Some useful methods.
///
///   void close() {
///     // User requested close.
///     _connection.close();
///     // Detach from finalizer, no longer needed.
///     _finalizer.detach(this);
///   }
/// }
/// ```
/// This example has an example of an external resource that needs clean-up.
/// The finalizer is used to clean up an external connection when the
/// user of the API no longer has access to that connection.
/// The example uses the same object as attached object and detach key,
/// which is a useful approach when each attached object can be detached
/// individually. Being a detachment key doesn't keep an object alive.
///
/// No promises are made that the callback will ever be called.
/// The only thing that is guaranteed is that if a finalizer's callback
/// is called with a specific finalization token as argument,
/// then at least one value with an attachment to to the finalizer
/// that has that finalization token,
/// is no longer accessible to the program.
///
/// If the finalzier *itself* becomes unreachable,
/// it's allowed to be garbage collected
/// and then it won't trigger any further callbacks.
/// Always make sure to keep the finalizer itself reachable while it's needed.
///
/// If multiple finalizers are attached to a single object,
/// or the same finalizer is attached multiple times to an object,
/// and that object becomes inaccessible to the program,
/// then any number (including zero) of those attachments may trigger
/// their associated finalizer's callback.
/// It will not necessarily be all or none of them.
///
/// Finalization callbacks will happen as *events*.
/// They will not happen during execution of other code,
/// and not as a microtask,
/// but as high-level events similar to timer events.
///
/// Finalization callbacks must not throw.
@Since("2.17")
abstract class Finalizer<T> {
  /// Creates a finalizer with the given finalization callback.
  ///
  /// The [callback] is bound to the current zone
  /// when the [Finalizer] is created, and will run in that zone when called.
  external factory Finalizer(void Function(T) callback);

  /// Attaches this finalizer to [value].
  ///
  /// When [value] is longer accessible to the program,
  /// while still having an attachement to this finalizer,
  /// the callback of this finalizer *may* be called
  /// with [finalizationToken] as argument.
  /// The callback may be called at most once per active attachment,
  /// ones which have not been detached by calling [Finalizer.detach].
  ///
  /// If a non-`null` [detach] value is provided, that object can be
  /// passed to [Finalizer.detach] to remove the attachment again.
  ///
  /// The [value] and [detach] arguments do not count towards those
  /// objects being accessible to the program.
  /// Both must be objects supported as an [Expando] key.
  /// They may be the *same* object.
  ///
  /// Example:
  /// ```dart template:top
  /// /// Access the data base.
  /// Database connect() {
  ///   // Wraps the connection in a nice user API,
  ///   // *and* closes connection if the user forgets to.
  ///   var connection = _connectToDatabase();
  ///   var wrapper = Database._fromConnection(connection, _finalizer);
  ///   // Get finalizer callback when `wrapper` is no longer reachable.
  ///   _finalizer.attach(wrapper, connection, detach: wrapper);
  ///   return wrapper;
  /// }
  /// ````
  ///
  /// Multiple objects may be attached using the same finalization token,
  /// and the finalizer can be attached multiple times to the same object
  /// with different, or the same, finalization token.
  void attach(Object value, T finalizationToken, {Object? detach});

  /// Detaches the finalizer from values attached with [detachToken].
  ///
  /// Each attachment between this finalizer and a value,
  /// which was created by calling [attach] with the [detachToken] object as
  /// `detach` argument, is removed.
  ///
  /// If the finalizer was attached multiple times to the same value
  /// with different detachment keys,
  /// only those attachments which used [detachToken] are removed.
  ///
  /// After detaching, an attachment won't cause any callbacks to happen
  /// if the object become inaccessible.
  ///
  /// Example:
  /// ```dart template:none
  /// final Finalizer<DBConnection> _finalizer = Finalizer((connection) {
  ///   connection.close();
  /// });
  ///
  /// class Database {
  ///   final DBConnection _connection;
  ///   final Finalizer<Connection> _finalizer;
  ///   Database._fromConnection(this._connection, this._finalizer);
  ///
  ///   // Some useful methods.
  ///
  ///   void close() {
  ///     // User requested close.
  ///     _connection.close();
  ///     // Detach from finalizer, no longer needed.
  ///     // Was attached using this object as `detach` token.
  ///     _finalizer.detach(this);
  ///   }
  /// }
  /// ```
  void detach(Object detachToken);
}
