//·························································· // Copyright (c) 2023-2026. Jonathan Bédard ~ JóôòKiwi // // This project is free to use. // All the right is reserved to the author of this project. // My projects: // - https://github.com/joooKiwi/type // - https://github.com/joooKiwi/lazy // - https://github.com/joooKiwi/collection // - https://github.com/joooKiwi/enumeration //·························································· import type {Lazy} from "@joookiwi/lazy" import type {Nullable, NullOr} from "@joookiwi/type" import {CommonLazy, lazy} from "@joookiwi/lazy" import type {EnumerableWithNullableGrandParent} from "./EnumerableWithNullableGrandParent" import type {EnumerableWithNullableGreatGrandParent} from "./EnumerableWithNullableGreatGrandParent" import type {EnumerableWithNullableParent} from "./EnumerableWithNullableParent" import type {Enumerable} from "./Enumerable" import type {NameOf, PossibleNameOf} from "./type/nameOf" import type {PossibleOrdinalOf} from "./type/ordinalOf" import type {PossibleEnumerableValueOrNameByValueOrCallback} from "./type/possibleInstance" import {EnumConstants} from "./EnumConstants" import {EnumWithNullableGrandParent} from "./EnumWithNullableGrandParent" import {KnownEnumConstructors} from "./KnownEnumConstructors" import {ImpossibleIntegrityException} from "./exception/ImpossibleIntegrityException" import {_getGreatGrandParentValueFromName} from "./method/_getGreatGrandParentValueFromName" /** * An {@link Enum} class in conjuncture with the {@link EnumerableWithNullableGreatGrandParent}. * * Compared to its sibling {@link EnumWithGreatGrandParent}, it can receive `null`. * * But it can still throw a {@link NullReferenceException} in different scenarios: * - An exception is thrown when attempting to retrieve its {@link CompanionEnumWithGreatGrandParent} * - An exception is thrown when attempting to retrieve the value by {@link CompanionEnumWithGreatGrandParentDeclaration.getValue getValue()} * * Also, it can throw a {@link ImpossibleIntegrityException} when receiving a `null` * on a value not expected to be null on the {@link EnumWithNullableGreatGrandParent.parent parent} & * {@link EnumWithNullableGreatGrandParent.grandParent grandparent} methods. * * @see EnumWithGreatGrandParent */ export class EnumWithNullableGreatGrandParent, const GRAND_PARENT extends EnumerableWithNullableParent, const GREAT_GRAND_PARENT extends Enumerable, const ORDINAL extends PossibleOrdinalOf = PossibleOrdinalOf, const NAME extends PossibleNameOf = PossibleNameOf, > extends EnumWithNullableGrandParent implements EnumerableWithNullableGreatGrandParent { //#region -------------------- Fields -------------------- readonly #grandParent: Lazy> readonly #greatGrandParent: Lazy> static { KnownEnumConstructors.add(EnumWithNullableGreatGrandParent,) } //#endregion -------------------- Fields -------------------- //#region -------------------- Constructor -------------------- /** * Create the instance with {@link EnumerableWithNullableGreatGrandParent.parent parent}, * {@link EnumerableWithNullableGreatGrandParent.grandParent grandparent} * & {@link EnumerableWithNullableGreatGrandParent.greatGrandParent great-grandparent} references * with the same {@link Enum.name name} as the current instance */ protected constructor() protected constructor(parent: Nullable,) protected constructor(parent: Nullable, grandParent: Nullable,) protected constructor(parent: Nullable, grandParent: Nullable, greatGrandParent: Nullable,) protected constructor(parent: Nullable, grandParent: Nullable, greatGrandParentName: Nullable>,) protected constructor(parent: Nullable, grandParent: Nullable, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parent: Nullable, grandParent: Nullable, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parent: Nullable, grandParentName: Nullable>,) protected constructor(parent: Nullable, grandParentName: Nullable>, greatGrandParent: Nullable,) protected constructor(parent: Nullable, grandParentName: Nullable>, greatGrandParentName: Nullable>,) protected constructor(parent: Nullable, grandParentName: Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parent: Nullable, grandParentName: Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parent: Nullable, lateGrandParent: Nullable<() => Nullable>,) protected constructor(parent: Nullable, lateGrandParent: Nullable<() => Nullable>, greatGrandParent: Nullable,) protected constructor(parent: Nullable, lateGrandParent: Nullable<() => Nullable>, greatGrandParentName: Nullable>,) protected constructor(parent: Nullable, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parent: Nullable, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parent: Nullable, lateGrandParentName: Nullable<() => Nullable>>,) protected constructor(parent: Nullable, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParent: Nullable,) protected constructor(parent: Nullable, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParentName: Nullable>,) protected constructor(parent: Nullable, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parent: Nullable, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parentName: Nullable>,) protected constructor(parentName: Nullable>, grandParent: Nullable,) protected constructor(parentName: Nullable>, grandParent: Nullable, greatGrandParent: Nullable,) protected constructor(parentName: Nullable>, grandParent: Nullable, greatGrandParentName: Nullable>,) protected constructor(parentName: Nullable>, grandParent: Nullable, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parentName: Nullable>, grandParent: Nullable, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parentName: Nullable>, grandParentName: Nullable>,) protected constructor(parentName: Nullable>, grandParentName: Nullable>, greatGrandParent: Nullable,) protected constructor(parentName: Nullable>, grandParentName: Nullable>, greatGrandParentName: Nullable>,) protected constructor(parentName: Nullable>, grandParentName: Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parentName: Nullable>, grandParentName: Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parentName: Nullable>, lateGrandParent: Nullable<() => Nullable>,) protected constructor(parentName: Nullable>, lateGrandParent: Nullable<() => Nullable>, greatGrandParent: Nullable,) protected constructor(parentName: Nullable>, lateGrandParent: Nullable<() => Nullable>, greatGrandParentName: Nullable>,) protected constructor(parentName: Nullable>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parentName: Nullable>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(parentName: Nullable>, lateGrandParentName: Nullable<() => Nullable>>,) protected constructor(parentName: Nullable>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParent: Nullable,) protected constructor(parentName: Nullable>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParentName: Nullable>,) protected constructor(parentName: Nullable>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(parentName: Nullable>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParent: Nullable,) protected constructor(lateParent: Nullable<() => Nullable>, grandParent: Nullable, greatGrandParent: Nullable,) protected constructor(lateParent: Nullable<() => Nullable>, grandParent: Nullable, greatGrandParentName: Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParent: Nullable, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParent: Nullable, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParentName: Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParentName: Nullable>, greatGrandParent: Nullable,) protected constructor(lateParent: Nullable<() => Nullable>, grandParentName: Nullable>, greatGrandParentName: Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParentName: Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, grandParentName: Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParent: Nullable<() => Nullable>, greatGrandParent: Nullable,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParent: Nullable<() => Nullable>, greatGrandParentName: Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParent: Nullable,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParentName: Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParent: Nullable<() => Nullable>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParent: Nullable,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParent: Nullable, greatGrandParent: Nullable,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParent: Nullable, greatGrandParentName: Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParent: Nullable, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParent: Nullable, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParentName: Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParentName: Nullable>, greatGrandParent: Nullable,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParentName: Nullable>, greatGrandParentName: Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParentName: Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, grandParentName: Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParent: Nullable<() => Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParent: Nullable<() => Nullable>, greatGrandParent: Nullable,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParent: Nullable<() => Nullable>, greatGrandParentName: Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParent: Nullable<() => Nullable>, lateGreatGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParentName: Nullable<() => Nullable>>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParent: Nullable,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParentName: Nullable<() => Nullable>>, greatGrandParentName: Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParent: Nullable<() => Nullable>,) protected constructor(lateParentName: Nullable<() => Nullable>>, lateGrandParentName: Nullable<() => Nullable>>, lateGreatGrandParentName: Nullable<() => Nullable>>,) /** * Create the instance with a parent & a grandparent from any possible values (in Javascript) * * @param parent The parent value (from any possibilities in Javascript) * @param grandParent The grandparent value (from any possibilities in Javascript) * @param greatGrandParent The great-grandparent value (from any possibilities in Javascript) * * @typescriptDefinition */ protected constructor(parent?: PossibleEnumerableValueOrNameByValueOrCallback, grandParent?: PossibleEnumerableValueOrNameByValueOrCallback, greatGrandParent?: PossibleEnumerableValueOrNameByValueOrCallback,) protected constructor(parent?: PossibleEnumerableValueOrNameByValueOrCallback, grandParent?: PossibleEnumerableValueOrNameByValueOrCallback, greatGrandParent?: PossibleEnumerableValueOrNameByValueOrCallback,) { if (arguments.length === 0) { super() this.#grandParent = lazy(() => super.grandParent,) this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } if (arguments.length === 1) { super(parent,) this.#grandParent = lazy(() => super.grandParent,) this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } super(parent, grandParent,) if (arguments.length === 2) { this.#grandParent = lazy(() => super.grandParent,) this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } this.#grandParent = lazy(() => { const grandParent = super.grandParent const greatGrandParent = this.greatGrandParent if (grandParent == null) if (greatGrandParent != null) throw new ImpossibleIntegrityException(`The grandparent reference in “${this.constructor.name}” was not expected to be null when its great-grandparent is not-null.`, this,) return grandParent },) if (greatGrandParent instanceof Function) greatGrandParent = greatGrandParent() if (greatGrandParent == null) { this.#greatGrandParent = CommonLazy.NULL return } this.#greatGrandParent = lazy(() => { if (typeof greatGrandParent == "string") return _getGreatGrandParentValueFromName(this, greatGrandParent,) if (greatGrandParent === EnumConstants.NULL_ENUM_REFERENCE_SYMBOL) return null if (greatGrandParent === EnumConstants.ENUM_REFERENCE_BY_ITS_NAME_SYMBOL) return _getGreatGrandParentValueFromName(this, this.name,) if (greatGrandParent instanceof String) return _getGreatGrandParentValueFromName(this, greatGrandParent.valueOf(),) return greatGrandParent },) } //#endregion -------------------- Constructor -------------------- //#region -------------------- Getter methods -------------------- /** * The {@link NullOr nullable} grandparent of the current instance * * @lazy * @throws {ImpossibleIntegrityException} * @throws {NullReferenceException} */ public override get grandParent(): NullOr { return this.#grandParent.value } /** * The {@link NullOr nullable} great-grandparent of the current instance * * @lazy * @throws {NullReferenceException} */ public get greatGrandParent(): NullOr { return this.#greatGrandParent.value } //#endregion -------------------- Getter methods -------------------- }