/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Access, Aspect, Constraint } from "../aspects/index.js";
import { ElementTag } from "../common/index.js";
import { AnyElement } from "../elements/index.js";
import { Children } from "../models/Children.js";
import type { CommandModel, Model, ScopeModel, ValueModel } from "../models/index.js";
/**
 * This class performs lookups of models in the scope of a specific model.  We use a class so the lookup can maintain
 * state and guard against circular references.
 *
 * Any logic that requires traversal of a multi-model ownership or inheritance should use this class.
 *
 */
export declare class ModelTraversal {
    #private;
    /**
     * Perform an operation with iteration tracking.  If iteration depth limit
     */
    operation<T>(operator: () => T, toDismiss?: Model): T;
    /**
     * Perform an operation with a model dismissed from consideration for type lookup.
     */
    operationWithDismissal<T>(toDismiss: Model | undefined, operator: () => T): T;
    /**
     * Determine the type for a model.  This is the string name of the base model.  Usually this is simply the type
     * field but we infer the type in some cases where it is not supplied explicitly:
     *
     * - Children of maps and enums are uints of corresponding size
     * - Models that shadow another model in their parent's inheritance effectively inherit from the shadow so have
     *   their own name as the type name
     */
    getTypeName(model: Model | undefined): string | undefined;
    /**
     * Find the model in my inheritance hierarchy that has semantic meaning. This will be the first inherited model with
     * a metatype.
     */
    findMetabase(model: Model | undefined): Model | undefined;
    /**
     * Find the model a model derives from, if any.
     */
    findBase(model: Model | undefined): Model | undefined;
    /**
     * Find the first global model this model derives from, if any.
     */
    findGlobalBase(model: Model | undefined): Model | undefined;
    /**
     * Determine whether this model derives from another.
     */
    instanceOf(model: Model | undefined, other: Model | AnyElement | undefined): boolean;
    /**
     * Find an xref from this model or a parent.
     */
    findXref(model: Model | undefined): Model.CrossReference | undefined;
    /**
     * Find the model this model derives from that has children, if any.
     */
    findDefiningModel(model: ValueModel | undefined): ValueModel | undefined;
    /**
     * Find a child in the parent's inheritance hierarchy with the same tag and ID/name.
     */
    findShadow(model: Model | undefined): Model | undefined;
    /**
     * Get an aspect that reflects extension of any shadowed aspects.  Note that this searches the parent's inheritance
     * and the model's inheritance. This is because aspects can be inherited by overriding an element in the parent or
     * by direct type inheritance.  Aspects in shadowed elements take priority as they are presumably more specific.
     */
    findAspect(model: Model | undefined, symbol: symbol): Aspect<any> | undefined;
    /**
     * Constraint aspects are specialized because we infer constraint fields that are referenced in other models.
     */
    findConstraint(model: ValueModel, symbol: symbol, field?: "value" | "min" | "max"): Constraint | undefined;
    /**
     * Access aspects are specialized because access controls are inherited from the owner if not otherwise defined.
     *
     * That means access controls may come from 5 places, in order of priority:
     *
     *   1. The model itself
     *   2. A shadowed model in the owner hierarchy
     *   3. An overridden model in the model's class hierarchy
     *   4. A model in the parent hierarchy
     *   5. Access.Default
     *
     * This method uses {@link findAspect} for 1-3 then extends the result with 4 & 5 as necessary until
     * {@link Access.complete} is true.
     */
    findAccess(model: ValueModel | undefined, symbol: symbol, VM: typeof ValueModel): Access;
    /**
     * Search inherited scope for a named member.
     */
    findMember(scope: Model | undefined, key: Children.Selector, allowedTags: ElementTag[]): Model | undefined;
    /**
     * Search inherited scope for a bit definition.
     */
    findBitDefinition(scope: Model | undefined, bit: number): import("../models/FieldModel.js").FieldModel<import("../elements/FieldElement.js").FieldElement> | undefined;
    /**
     * Search inherited and structural type scope for a named type.
     */
    findType(owner: Model | undefined, name: string, tag: ElementTag): Model | undefined;
    /**
     * Similar to findType but operates with a qualified type name.
     *
     * Unlike findType, a qualified type may reference an element parented by any other, not just those within
     * ScopeModels.
     *
     * This is quite complicated and would be painfully slow except in practice we don't use many qualified types and
     * those we do use resolve with few failing branches in the search once the root qualifier of the name matches.
     */
    findQualifiedType(scope: Model | undefined, path: string[], tag: ElementTag): Model | undefined;
    /**
     * Find the response model for a command.
     */
    findResponse(command: CommandModel): Model<import("../elements/BaseElement.js").BaseElement> | undefined;
    /**
     * Find all children of a node that reference a specific type.
     */
    findReferences(scope: Model | undefined, type: Model | undefined): Model[];
    /**
     * Find an owning model of a specific type.
     */
    findOwner<T extends Model>(constructor: Model.Type<T>, model: Model | undefined): T | undefined;
    /**
     * Find the root model.
     */
    findRoot(model: Model | undefined): Model | undefined;
    /**
     * Visit all nodes in the model tree.
     */
    visit(model: Model, visitor: (model: Model) => boolean | void): boolean | undefined;
    /**
     * Visit all nodes in the inheritance hierarchy until the visitor returns false.
     */
    visitInheritance(model: Model | undefined, visitor: (model: Model) => boolean | void): boolean | undefined;
    /**
     * Find the parent for this model.
     */
    findParent(model?: Model): Model<import("../elements/BaseElement.js").BaseElement> | undefined;
    /**
     * Find an owner that defines type scope for a model.
     */
    findScope(model?: Model): ScopeModel | undefined;
    /**
     * If a model is not owned by a MatterModel, global resolution won't work.  This model acts as a fallback to work
     * around this.
     */
    static fallbackScope: ScopeModel | undefined;
    /**
     * This is a cheap hack to optimize analysis of large static models.  It temporarily memoizes key operations.
     *
     * It's not a huge win but does speed up model validation by approximately 50%
     */
    static memoize(fn: () => void): void;
}
//# sourceMappingURL=ModelTraversal.d.ts.map