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

library dart2js.abstract_value_domain;

import '../common/metrics.dart';
import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart' show DartType;
import '../serialization/serialization.dart';
import '../universe/member_hierarchy.dart';
import '../universe/record_shape.dart';
import '../universe/selector.dart';

/// Abstract booleans used for reporting known and unknown truth values.
enum AbstractBool {
  /// Used when the property is known _never_ to be true.
  False,

  /// Used when the property is known _always_ to be true.
  True,

  /// Used when the property might or might not be true.
  Maybe,
  ;

  bool get isDefinitelyTrue => this == True;

  bool get isPotentiallyTrue => this != False;

  bool get isDefinitelyFalse => this == False;

  bool get isPotentiallyFalse => this != True;

  static AbstractBool trueOrMaybe(bool value) => value ? True : Maybe;

  static AbstractBool trueOrFalse(bool value) => value ? True : False;

  static AbstractBool maybeOrFalse(bool value) => value ? Maybe : False;

  static AbstractBool strengthen(AbstractBool a, AbstractBool b) {
    //TODO(coam): Assert arguments a and b are consistent
    return a.isDefinitelyTrue ? True : (a.isDefinitelyFalse ? False : b);
  }

  AbstractBool operator &(AbstractBool other) {
    if (isDefinitelyTrue) return other;
    if (other.isDefinitelyTrue) return this;
    if (isDefinitelyFalse || other.isDefinitelyFalse) return False;
    return Maybe;
  }

  AbstractBool operator |(AbstractBool other) {
    if (isDefinitelyFalse) return other;
    if (other.isDefinitelyFalse) return this;
    if (isDefinitelyTrue || other.isDefinitelyTrue) return True;
    return Maybe;
  }

  AbstractBool operator ~() {
    if (isDefinitelyTrue) return AbstractBool.False;
    if (isDefinitelyFalse) return AbstractBool.True;
    return AbstractBool.Maybe;
  }
}

/// A value in an abstraction of runtime values.
abstract class AbstractValue {}

/// A pair of an AbstractValue and a precision flag. See
/// [AbstractValueDomain.createFromStaticType] for semantics of [isPrecise].
class AbstractValueWithPrecision {
  final AbstractValue abstractValue;
  final bool isPrecise;

  const AbstractValueWithPrecision(this.abstractValue, this.isPrecise);

  @override
  String toString() =>
      'AbstractValueWithPrecision($abstractValue, isPrecise: $isPrecise)';
}

/// A system that implements an abstraction over runtime values.
mixin AbstractValueDomain {
  /// The [AbstractValue] that represents a type which has not yet been
  /// computed. Type graph nodes may carry this type during construction of the
  /// graph, but it should be replaced by a computed type by the time the graph
  /// is queried.
  AbstractValue get uncomputedType => emptyType;

  /// The [AbstractValue] that represents an unknown runtime value. This
  /// includes values internal to the implementation, such as late sentinels.
  AbstractValue get internalTopType;

  /// The [AbstractValue] that represents an unknown runtime Dart value.
  AbstractValue get dynamicType;

  /// The [AbstractValue] that represents a non-null subtype of `Type` at
  /// runtime.
  AbstractValue get typeType;

  /// The [AbstractValue] that represents a non-null subtype of `Function` at
  /// runtime.
  AbstractValue get functionType;

  /// The [AbstractValue] that represents a non-null subtype of `Record` at
  /// runtime.
  AbstractValue get recordType;

  /// The [AbstractValue] that represents a non-null subtype of `bool` at
  /// runtime.
  AbstractValue get boolType;

  /// The [AbstractValue] that represents a non-null subtype of `int` at
  /// runtime.
  AbstractValue get intType;

  /// The [AbstractValue] that represents a non-null subtype of `double` at
  /// runtime.
  AbstractValue get numNotIntType;

  /// The [AbstractValue] that represents a non-null subtype of `num` at
  /// runtime.
  AbstractValue get numType;

  /// The [AbstractValue] that represents a non-null subtype of `String` at
  /// runtime.
  AbstractValue get stringType;

  /// The [AbstractValue] that represents a non-null subtype of `List` at
  /// runtime.
  AbstractValue get listType;

  /// The [AbstractValue] that represents a non-null subtype of `Set` at
  /// runtime.
  AbstractValue get setType;

  /// The [AbstractValue] that represents a non-null subtype of `Map` at
  /// runtime.
  AbstractValue get mapType;

  /// The [AbstractValue] that represents a non-null value at runtime.
  AbstractValue get nonNullType;

  /// The [AbstractValue] that represents the `null` at runtime.
  AbstractValue get nullType;

  /// The [AbstractValue] that represents a late sentinel value at runtime.
  AbstractValue get lateSentinelType;

  /// The [AbstractValue] that represents a non-null growable JavaScript array
  /// at runtime.
  AbstractValue get growableListType;

  /// The [AbstractValue] that represents a non-null fixed size JavaScript array
  /// at runtime.
  AbstractValue get fixedListType;

  /// The [AbstractValue] that represents the union of [growableListType] and
  /// [fixedListType], i.e. JavaScript arrays that may have their elements
  /// assigned.
  AbstractValue get mutableArrayType;

  /// The [AbstractValue] that represents a non-null 31-bit unsigned integer at
  /// runtime.
  AbstractValue get uint31Type;

  /// The [AbstractValue] that represents a non-null 32-bit unsigned integer at
  /// runtime.
  AbstractValue get uint32Type;

  /// The [AbstractValue] that represents a non-null unsigned integer at
  /// runtime.
  AbstractValue get positiveIntType;

  /// The [AbstractValue] that represents a non-null constant list literal at
  /// runtime.
  AbstractValue get constListType;

  /// The [AbstractValue] that represents a non-null constant set literal at
  /// runtime.
  AbstractValue get constSetType;

  /// The [AbstractValue] that represents a non-null constant map literal at
  /// runtime.
  AbstractValue get constMapType;

  /// The [AbstractValue] that represents the empty set of runtime values.
  AbstractValue get emptyType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Iterable` class used for the `sync*` implementation.
  AbstractValue get syncStarIterableType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Future` class used for the `async` implementation.
  AbstractValue get asyncFutureType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Stream` class used for the `async*` implementation.
  AbstractValue get asyncStarStreamType;

  /// Returns an [AbstractValue] and a precision flag.
  ///
  /// Creates an [AbstractValue] corresponding to an expression of the given
  /// static [type] and [classRelation], and an `isPrecise` flag that is `true`
  /// if the [AbstractValue] precisely represents the [type], or `false` if the
  /// [AbstractValue] is an approximation.
  ///
  /// If `isPrecise` is `true`, then the abstract value is equivalent to [type].
  ///
  /// If `isPrecise` is `false` then the abstract value contains all types in
  /// [type] but might contain more. Two different Dart types can have the same
  /// approximation, so care must be taken not to make subtype judgements from
  /// imprecise abstract values.
  ///
  /// The type `T` where `T` is a type parameter would be modelled by an
  /// imprecise abstract value type since we don't know how `T` is
  /// instantiated. It might be approximated by the bound of `T`.  `List<T>`
  /// where `T` is a type parameter would be modelled as imprecise for the same
  /// reason.
  ///
  /// If the abstract value domain does not track generic type parameters (e.g.
  /// the current implementation of type-masks), then `List<int>` would need to
  /// be modelled by an imprecise abstract value. `List<dynamic>` might be the
  /// imprecise approximation.
  ///
  /// In the context of a run-time type check, an imprecise abstract value can
  /// be used to compute an output type by narrowing the input type, but only a
  /// precise abstract value could be used to remove the check on the basis of
  /// the input's abstract type. The check can only be removed with additional
  /// reasoning, for example, that a dominating check uses the same type
  /// expression.
  ///
  /// [nullable] determines if the type in weak or legacy mode should be
  /// interpreted as nullable. This is passed as `false` for is-tests and `true`
  /// for as-checks and other contexts (e.g. parameter checks).
  AbstractValueWithPrecision createFromStaticType(DartType type,
      {required bool nullable});

  /// Creates an [AbstractValue] for a non-null exact instance of [cls].
  AbstractValue createNonNullExact(ClassEntity cls);

  /// Creates an [AbstractValue] for a potentially null exact instance of [cls].
  AbstractValue createNullableExact(ClassEntity cls);

  /// Creates an [AbstractValue] for a non-null instance that extends [cls].
  AbstractValue createNonNullSubclass(ClassEntity cls);

  /// Creates an [AbstractValue] for a non-null instance that implements [cls].
  AbstractValue createNonNullSubtype(ClassEntity cls);

  /// Creates an [AbstractValue] for a potentially null instance that implements
  /// [cls].
  AbstractValue createNullableSubtype(ClassEntity cls);

  /// Returns an [AbstractBool] that describes whether [value] is a native typed
  /// array or `null` at runtime.
  AbstractBool isTypedArray(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] could be a native
  /// typed array at runtime.
  AbstractBool couldBeTypedArray(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that excludes `null`.
  AbstractValue excludeNull(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that includes `null`.
  AbstractValue includeNull(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that excludes the late
  /// sentinel.
  AbstractValue excludeLateSentinel(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that includes the late
  /// sentinel.
  AbstractValue includeLateSentinel(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] contains
  /// instances of [cls] at runtime.
  AbstractBool containsType(covariant AbstractValue value, ClassEntity cls);

  /// Returns an [AbstractBool] that describes whether [value] only contains
  /// subtypes of [cls] or `null` at runtime.
  AbstractBool containsOnlyType(covariant AbstractValue value, ClassEntity cls);

  /// Returns an [AbstractBool] that describes whether [value] is known to be an
  /// instance of [cls] at runtime.
  AbstractBool isInstanceOf(AbstractValue value, ClassEntity cls);

  /// Returns an [AbstractBool] that describes whether [value] is empty set of
  /// runtime values.
  AbstractBool isEmpty(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null
  /// exact class at runtime.
  AbstractBool isExact(covariant AbstractValue value);

  /// Returns the [ClassEntity] if this [value] is a non-null instance of an
  /// exact class at runtime, and `null` otherwise.
  ClassEntity? getExactClass(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is `null` at
  /// runtime.
  AbstractBool isNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a sentinel for
  /// an uninitialized late variable at runtime.
  AbstractBool isLateSentinel(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// bool, number, string, array or `null` at runtime.
  AbstractBool isPrimitive(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// number at runtime.
  AbstractBool isPrimitiveNumber(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// bool at runtime.
  AbstractBool isPrimitiveBoolean(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// string, array, native HTML list or `null` at runtime.
  AbstractBool isIndexablePrimitive(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a fixed-size
  /// or constant JavaScript array or `null` at runtime.
  AbstractBool isFixedArray(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a growable
  /// JavaScript array or `null` at runtime.
  AbstractBool isExtendableArray(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a mutable
  /// JavaScript array or `null` at runtime.
  AbstractBool isMutableArray(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a mutable
  /// JavaScript array, native HTML list or `null` at runtime.
  AbstractBool isMutableIndexable(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// array or `null` at runtime.
  AbstractBool isArray(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// string at runtime.
  AbstractBool isPrimitiveString(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is an interceptor
  /// at runtime.
  AbstractBool isInterceptor(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null
  /// integer value at runtime.
  AbstractBool isInteger(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null 32
  /// bit unsigned integer value at runtime.
  AbstractBool isUInt32(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null 31
  /// bit unsigned integer value at runtime.
  AbstractBool isUInt31(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null
  /// unsigned integer value at runtime.
  AbstractBool isPositiveInteger(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is an unsigned
  /// integer value or `null` at runtime.
  AbstractBool isPositiveIntegerOrNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is an integer
  /// value or `null` at runtime.
  AbstractBool isIntegerOrNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a non-null
  /// JavaScript number at runtime.
  AbstractBool isNumber(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// number or `null` at runtime.
  AbstractBool isNumberOrNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// bool at runtime.
  AbstractBool isBoolean(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// bool or `null` at runtime.
  AbstractBool isBooleanOrNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// string at runtime.
  AbstractBool isString(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] is a JavaScript
  /// string or `null` at runtime.
  AbstractBool isStringOrNull(covariant AbstractValue value);

  /// Returns an [AbstractBool] that describes whether [value] a JavaScript
  /// primitive, possible `null`.
  AbstractBool isPrimitiveOrNull(covariant AbstractValue value);

  /// Return an [AbstractBool] that describes whether [value] is a JavaScript
  /// 'truthy' value at runtime. This is effectively symbolically evaluating the
  /// abstract value as a JavaScript condition.
  AbstractBool isTruthy(covariant AbstractValue value);

  /// Returns [AbstractValue] for the runtime values contained in either [a] or
  /// [b].
  AbstractValue union(covariant AbstractValue a, covariant AbstractValue b);

  /// Returns [AbstractValue] for the runtime values contained in at least one
  /// of [values].
  AbstractValue unionOfMany(Iterable<AbstractValue> values);

  /// Returns [AbstractValue] for the runtime values that [a] and [b] have in
  /// common.
  AbstractValue intersection(
      covariant AbstractValue a, covariant AbstractValue b);

  /// Returns an [AbstractBool] that describes whether [a] and [b] have no
  /// runtime values in common.
  AbstractBool areDisjoint(
      covariant AbstractValue a, covariant AbstractValue b);

  /// Returns an [AbstractBool] that describes whether [a] contains all non-null
  /// runtime values.
  AbstractBool containsAll(covariant AbstractValue a);

  /// Computes the [AbstractValue] corresponding to the constant [value].
  AbstractValue computeAbstractValueForConstant(ConstantValue value);

  /// Returns `true` if [value] represents a container value at runtime.
  bool isContainer(covariant AbstractValue value);

  /// Creates a container value specialization of [originalValue] with the
  /// inferred [element] runtime value and inferred runtime [length].
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createContainerValue(
      AbstractValue? originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      AbstractValue elementType,
      int? length);

  /// Returns the element type of [value] if it represents a container value
  /// at runtime. Returns [dynamicType] otherwise.
  AbstractValue getContainerElementType(AbstractValue value);

  /// Return the known length of [value] if it represents a container value
  /// at runtime. Returns `null` if the length is unknown or if [value] doesn't
  /// represent a container value at runtime.
  int? getContainerLength(AbstractValue value);

  /// Returns `true` if [value] represents a set value at runtime.
  bool isSet(covariant AbstractValue value);

  /// Creates a set value specialization of [originalValue] with the inferred
  /// [elementType] runtime value.
  ///
  /// The [allocationNode] is used to identify this particular set allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createSetValue(
      AbstractValue? originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      AbstractValue elementType);

  /// Returns the element type of [value] if it represents a set value at
  /// runtime. Returns [dynamicType] otherwise.
  AbstractValue getSetElementType(AbstractValue value);

  /// Returns `true` if [value] represents a map value at runtime.
  bool isMap(covariant AbstractValue value);

  /// Creates a map value specialization of [originalValue] with the inferred
  /// [key] and [value] runtime values.
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createMapValue(
      AbstractValue? originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      AbstractValue key,
      AbstractValue value);

  /// Returns the key type of [value] if it represents a map value at runtime.
  /// Returns [dynamicType] otherwise.
  AbstractValue getMapKeyType(AbstractValue value);

  /// Returns the value type of [value] if it represents a map value at runtime.
  /// Returns [dynamicType] otherwise.
  AbstractValue getMapValueType(AbstractValue value);

  /// Returns `true` if [value] represents a dictionary value, that is, a map
  /// with strings as keys, at runtime.
  bool isDictionary(covariant AbstractValue value);

  /// Creates a dictionary value specialization of [originalValue] with the
  /// inferred [key] and [value] runtime values.
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createDictionaryValue(
      AbstractValue? originalValue,
      Object? allocationNode,
      MemberEntity? allocationElement,
      AbstractValue key,
      AbstractValue value,
      Map<String, AbstractValue> mappings);

  /// Returns `true` if [value] is a dictionary value which contains [key] as
  /// a key.
  bool containsDictionaryKey(AbstractValue value, String key);

  /// Returns the value type for [key] in [value] if it represents a dictionary
  /// value at runtime. Returns [dynamicType] otherwise.
  AbstractValue getDictionaryValueForKey(AbstractValue value, String key);

  /// Creates a record value with the specified [shape] and the specified type
  /// for each field in [types].
  AbstractValue createRecordValue(RecordShape shape, List<AbstractValue> types);

  /// Returns `true` if [value] represents a record value at runtime.
  bool isRecord(covariant AbstractValue value);

  /// Returns `true` if [value] is a record type containing a field with name
  /// [field].
  bool recordHasGetter(AbstractValue value, String field);

  /// Returns the value of the field record with name [field] in [value] if it
  /// is a record type otherwise returns [dynamicType].
  AbstractValue getGetterTypeInRecord(AbstractValue value, String field);

  /// Returns `true` if [specialization] is a specialization of
  /// [generalization].
  ///
  /// Specializations are created through [createPrimitiveValue],
  /// [createMapValue], [createDictionaryValue] and [createContainerValue].
  bool isSpecializationOf(
      AbstractValue specialization, AbstractValue generalization);

  /// Returns the value of which [value] is a specialization. Return `null` if
  /// [value] is not a specialization.
  ///
  /// Specializations are created through [createPrimitiveValue],
  /// [createMapValue], [createDictionaryValue] and [createContainerValue].
  AbstractValue? getGeneralization(AbstractValue? value);

  /// Return the object identifying the allocation of [value] if it is an
  /// allocation based specialization. Otherwise returns `null`.
  ///
  /// Allocation based specializations are created through [createMapValue],
  /// [createDictionaryValue] and [createContainerValue]
  Object? getAllocationNode(AbstractValue value);

  /// Return the allocation element of [value] if it is an allocation based
  /// specialization. Otherwise returns `null`.
  ///
  /// Allocation based specializations are created through [createMapValue],
  /// [createDictionaryValue] and [createContainerValue]
  MemberEntity? getAllocationElement(AbstractValue value);

  /// Returns `true` if [value] a known primitive JavaScript value at runtime.
  bool isPrimitiveValue(covariant AbstractValue value);

  /// Creates a primitive value specialization of [originalValue] with the
  /// inferred primitive constant [value].
  AbstractValue createPrimitiveValue(
      AbstractValue originalValue, PrimitiveConstantValue value);

  /// Returns the primitive JavaScript value of [value] if it represents a
  /// primitive JavaScript value at runtime, value at runtime. Returns `null`
  /// otherwise.
  PrimitiveConstantValue? getPrimitiveValue(covariant AbstractValue value);

  /// Compute the type of all potential receivers of the set of live [members].
  AbstractValue computeReceiver(Iterable<MemberEntity> members);

  /// Returns an [AbstractBool] that describes whether [member] is a potential
  /// target when being invoked on a [receiver]. [name] is used to ensure
  /// library privacy is taken into account.
  AbstractBool isTargetingMember(
      AbstractValue receiver, MemberEntity member, Name name);

  /// Returns an [AbstractBool] that describes whether [selector] invoked on a
  /// [receiver] can hit a [noSuchMethod].
  AbstractBool needsNoSuchMethodHandling(
      AbstractValue receiver, Selector selector);

  /// Returns the [AbstractValue] for the [parameterType] of a native
  /// method. May return `null`, for example, if [parameterType] is not modelled
  /// precisely by an [AbstractValue].
  AbstractValue? getAbstractValueForNativeMethodParameterType(DartType type);

  /// Returns an [AbstractBool] that describes if the set of runtime values of
  /// [subset] are known to all be in the set of runtime values of [superset].
  AbstractBool isIn(AbstractValue subset, AbstractValue superset);

  /// Returns the [MemberEntity] that is known to always be hit at runtime
  /// [receiver].
  ///
  /// Returns `null` if 0 or more than 1 member can be hit at runtime.
  MemberEntity? locateSingleMember(AbstractValue receiver, Selector selector);

  /// Returns an [AbstractBool] that describes if [value] is known to be an
  /// indexable JavaScript value at runtime.
  AbstractBool isJsIndexable(covariant AbstractValue value);

  /// RReturns an [AbstractBool] that describes if [value] is known to be an
  /// indexable or iterable JavaScript value at runtime.
  ///
  /// JavaScript arrays are both indexable and iterable whereas JavaScript
  /// strings are indexable but not iterable.
  AbstractBool isJsIndexableAndIterable(AbstractValue value);

  /// Returns an [AbstractBool] that describes if [value] is known to be a
  /// JavaScript indexable of fixed length.
  AbstractBool isFixedLengthJsIndexable(AbstractValue value);

  /// Returns compact a textual representation for [value] used for debugging.
  String getCompactText(AbstractValue value);

  /// Returns a set of members that are ancestors of all possible targets for
  /// a call targeting [selector] on an entity with type represented by
  /// [receiver].
  Iterable<DynamicCallTarget> findRootsOfTargets(AbstractValue receiver,
      Selector selector, MemberHierarchyBuilder memberHierarchyBuilder);

  /// Deserializes an [AbstractValue] for this domain from [source].
  AbstractValue readAbstractValueFromDataSource(DataSourceReader source);

  /// Serializes this [value] for this domain to [sink].
  void writeAbstractValueToDataSink(DataSinkWriter sink, AbstractValue? value);

  bool isInvalidRefinement(AbstractValue before, AbstractValue after);

  void finalizeMetrics() {}

  Metrics get metrics => Metrics.none();
}
