/**
 * @license
 * Copyright 2022-2024 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { DefinitionError, ElementTag, Specification } from "../common/index.js";
import { AnyElement, BaseElement } from "../elements/index.js";
import { Children } from "./Children.js";
/**
 * A "model" is a class that implements runtime functionality associated with the corresponding element type.
 *
 * @template T the element type this model implements
 */
export declare abstract class Model<T extends BaseElement = BaseElement> {
    #private;
    abstract readonly tag: ElementTag;
    type?: string;
    isSeed?: boolean;
    description?: string;
    details?: string;
    xref?: Model.CrossReference;
    errors?: DefinitionError[];
    asOf?: Specification.Revision;
    until?: Specification.Revision;
    id?: number;
    name: string;
    /**
     * Indicates that an element may have type definitions as children.
     */
    isTypeScope?: boolean;
    /**
     * Indicates that an element defines a datatype.
     */
    isType?: boolean;
    /**
     * Normally {@link base} performs lookup based on {@link type}.  Setting this field short circuits this resolution.
     *
     * The operational base also enables resolution from the operational base's tree.  This enables resolution on
     * operational models that are not installed in a parent hierarchy.
     *
     * We set the operational base when freezing the model.
     */
    operationalBase?: Model | null;
    /**
     * This is like {@link operationalBase} except for the element's shadow.
     */
    operationalShadow?: Model | null;
    /**
     * Did validation find errors?
     */
    get valid(): boolean;
    /**
     * The path ("." delimited) in the Matter tree.
     *
     * This is informational and generally tries to adhere to JS API conventions.
     */
    get path(): string;
    /**
     * Determine if this model resides in the global namespace.
     */
    get isGlobal(): boolean;
    /**
     * The structural parent.  This is the model for the element that contains this element's definition.
     */
    get parent(): Model | undefined;
    set parent(parent: Model | undefined);
    /**
     * Allows subclasses to pull a working ID from an alternate source.
     */
    get effectiveId(): number | undefined;
    /**
     * Get a string that uniquely identifies this model.  This is normally the effective ID but some models require a
     * generated identifier.
     */
    get key(): string | undefined;
    /**
     * Obtain a discriminator that differentiates different models with the same name
     */
    get discriminator(): string | undefined;
    /**
     * Children of models are always models.
     */
    get children(): Children;
    /**
     * Set the children of the model.
     */
    set children(children: Children.InputIterable<Model<AnyElement>>);
    /**
     * Factory support.  Populated by derivatives upon definition.
     */
    static types: {
        [type: string]: new (definition: any) => Model;
    };
    /**
     * In some circumstances the base type can be inferred.  This inference happens here.
     *
     * Does not recurse so only returns the direct base type.
     */
    get effectiveType(): string | undefined;
    /**
     * Get a model for my base type as defined by {@link type}, if any.
     */
    get base(): Model | undefined;
    /**
     * Get shadow model, if any.  A "shadow" is an element in my parent's inheritance hierarchy that I override.
     */
    get shadow(): Model | undefined;
    /**
     * Get the first global base type.  This may have semantic meaning more specific than the base primitive type.
     */
    get globalBase(): Model<BaseElement> | undefined;
    /**
     * A local or parent xref.
     */
    get effectiveXref(): Model.CrossReference | undefined;
    /**
     * The set of tags from which this model may derive.
     */
    get allowedBaseTags(): ElementTag[];
    /**
     * Determine whether this element applies to a specific revision.
     */
    appliesTo(revision: Specification.Revision): boolean;
    /**
     * Create a model for an element.
     */
    static create(definition: AnyElement): Model<BaseElement>;
    /**
     * Retrieve all models of a specific element type from local scope.
     *
     * @param type model class or a predicate object
     * @param key filters to models matching a specific type
     */
    all<T extends Model>(type: Model.Type<T>, key?: number | string): T[];
    /**
     * Retrieve a specific child by ID or name.
     */
    get<T extends Model>(type: Model.Type<T>, key: number | string): T | undefined;
    /**
     * Retrieve a model of a specific type from the ownership hierarchy.
     */
    owner<T extends Model>(constructor: Model.Type<T>): T | undefined;
    /**
     * Record a validation error for this model.
     */
    error(code: string, message: string): void;
    /**
     * Convert model to JSON.
     */
    toJSON(): T;
    /**
     * Convert to non-class structure.
     */
    valueOf(): T;
    /**
     * Apply a function to all tree elements.
     */
    visit(visitor: (model: Model) => boolean | void): boolean | undefined;
    /**
     * Find all children that reference a specific type.
     */
    references(type: Model): Model<BaseElement>[];
    /**
     * Search the inheritance chain for a child property.
     */
    member(key: Children.Selector, allowedTags?: ElementTag[]): Model | undefined;
    /**
     * Does this model derive from another?
     */
    instanceOf(other: Model | AnyElement): boolean;
    /**
     * Clone the model.  This deep copies all descendant child models but not other properties.
     */
    clone<This extends Model>(this: This): This;
    /**
     * Create an operational extension of the model.  This creates a new model that inherits from this model for
     * operational purposes.
     */
    extend<This extends Model>(this: This, properties?: Partial<BaseElement.Properties<T>>): This;
    constructor(definition: Model<T> | BaseElement.Properties<T>, ...children: Model.Definition<Model>[]);
    /**
     * Freeze the model hierarchy rooted at this model.
     *
     * When using a model as operational schema we implement various optimizations that assume the schema is immutable.
     * This function enforces that assumption and caches a few values that only make sense with frozen schema.
     *
     * To make changes to a frozen model use {@link clone}.
     */
    freeze(): void;
    toString(): string;
    [inspect](_depth: any, options: any, inspect: any): string;
}
export declare namespace Model {
    /**
     * Obtain the element type of a model type.
     */
    type ElementOf<T> = T extends Model<infer E extends AnyElement> ? E : never;
    /**
     * Obtain the child type of a model type.
     */
    type ChildOf<T> = T extends {
        children: Children<infer C>;
    } ? C : never;
    /**
     * Input model.  In most places elements and models are interchangeable on input.
     */
    type Definition<T extends Model> = ElementOf<T> | T;
    /**
     * A model constructor.
     */
    type Type<T extends Model = Model> = abstract new (...args: any) => T;
    type LookupPredicate<T extends Model> = Type<T> | {
        type: Type<T>;
        test: (model: Model) => boolean;
    };
    type PropertyValidation = {
        name: string;
        type: string | (new (...args: any[]) => any) | {
            [key: string | number]: any;
        } | undefined;
        required?: boolean;
        nullable?: boolean;
        values?: {
            [name: string]: any;
        };
    };
    class CrossReference implements Specification.CrossReference {
        document: Specification;
        section: string;
        private static instances;
        private constructor();
        toString(): string;
        static get(xref: Specification.CrossReference): CrossReference;
        [inspect](_depth: any, options: any, inspect: any): any;
    }
}
//# sourceMappingURL=Model.d.ts.map