//·························································· // 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} from "@joookiwi/type" import {lazy} from "@joookiwi/lazy" import type {EnumerableWithGrandParent} from "./EnumerableWithGrandParent" import type {EnumerableWithGreatGrandParent} from "./EnumerableWithGreatGrandParent" import type {EnumerableWithParent} from "./EnumerableWithParent" 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 {EnumWithGrandParent} from "./EnumWithGrandParent" import {KnownEnumConstructors} from "./KnownEnumConstructors" import {NullReferenceException} from "./exception/NullReferenceException" import {_getGreatGrandParentValueFromName} from "./method/_getGreatGrandParentValueFromName" /** * An {@link Enum} class in conjuncture with the {@link EnumerableWithGreatGrandParent}. * * Compared to its sibling {@link EnumWithNullableGreatGrandParent}, it does not want `null`. * * It can throw a {@link NullReferenceException} in different scenarios: * - A `null` is received during the construction * - A `null` is interpreted on the {@link EnumWithGreatGrandParent.parent parent}, * {@link EnumWithGreatGrandParent.grandParent grandparent} & {@link EnumWithGreatGrandParent.greatGrandParent great-grandparent} * - 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()} * * @see EnumWithNullableGreatGrandParent */ export class EnumWithGreatGrandParent, const GRAND_PARENT extends EnumerableWithParent, const GREAT_GRAND_PARENT extends Enumerable, const ORDINAL extends PossibleOrdinalOf = PossibleOrdinalOf, const NAME extends PossibleNameOf = PossibleNameOf, > extends EnumWithGrandParent implements EnumerableWithGreatGrandParent { //#region -------------------- Fields -------------------- readonly #greatGrandParent: Lazy static { KnownEnumConstructors.add(EnumWithGreatGrandParent,) } //#endregion -------------------- Fields -------------------- //#region -------------------- Constructor -------------------- /** * Create the instance with {@link EnumerableWithGreatGrandParent.parent parent}, * {@link EnumerableWithGreatGrandParent.grandParent grandparent} * & {@link EnumerableWithGreatGrandParent.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) { // We default to the name of the instance super() this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } if (arguments.length === 1) { super(parent,) this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } super(parent, grandParent,) if (arguments.length === 2) { this.#greatGrandParent = lazy(() => _getGreatGrandParentValueFromName(this, this.name,),) return } if (greatGrandParent instanceof Function) greatGrandParent = greatGrandParent() this.#greatGrandParent = lazy(() => { if (greatGrandParent == null) throw new NullReferenceException(`The value received on the “${this.constructor.name}” cannot be null on an Enumerable with non-null value.`, greatGrandParent,) if (typeof greatGrandParent == "string") return _getGreatGrandParentValueFromName(this, greatGrandParent,) if (greatGrandParent === EnumConstants.ENUM_REFERENCE_BY_ITS_NAME_SYMBOL) return _getGreatGrandParentValueFromName(this, this.name,) if (greatGrandParent === EnumConstants.NULL_ENUM_REFERENCE_SYMBOL) throw new NullReferenceException(`The value received on the “${this.constructor.name}” cannot be null on an Enumerable with non-null value.`, greatGrandParent,) if (greatGrandParent instanceof String) return _getGreatGrandParentValueFromName(this, greatGrandParent.valueOf(),) return greatGrandParent },) } //#endregion -------------------- Constructor -------------------- //#region -------------------- Getter methods -------------------- /** * The great-grandparent of the current instance * * @lazy * @throws NullReferenceException An error happened while attempting to retrieve the great-grandparent value */ public get greatGrandParent(): GREAT_GRAND_PARENT { return this.#greatGrandParent.value } //#endregion -------------------- Getter methods -------------------- }