/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Conformance } from "#aspects/Conformance.js";
import { ElementTag } from "#common/ElementTag.js";
import { ModelIndex } from "./ModelIndex.js";
import type { Model } from "#models/index.js";
/**
 * Tracks extensions for a scope to models in parent scopes.
 *
 * A child model with the same {tag, name, type} tuple in a derived scope is a semantic extension of the model in the
 * parent scope even if it does not explicitly inherit from the parent via {@link Model#type}.  We refer to the implicit
 * base class as a *shadow* and the implicit child class as an *extension*.
 *
 * Note that "type" in above tuple includes either undefined, the model's own name, or extension of the exact same type
 * in both the shadow and the extension.  In the former case the shadow is implicit; in the latter case it is explicit.
 *
 * This utility provideds optimized lookup of extensions present in a particular scope.
 *
 * If the scope is frozen the analysis is cached.
 *
 * TODO - there is remaining ambiguity in shadow selection, fine for now but could be eliminated with conformance
 *
 * TODO - currently we only consider shadows at scope root but shadows of nested children is possible with this approach
 */
export interface Scope extends Conformance.FeatureContext {
    /**
     * The model analyzed.
     */
    owner: Model;
    /**
     * Determine if the model is a shadow.
     */
    isShadow(model?: Model): boolean;
    /**
     * Retrieve the extension for an element if it is a shadow.
     */
    extensionOf<T extends Model>(model?: T): undefined | T;
    /**
     * Obtain canonical definition for model.  If the input model is a shadow returns the extension, otherwise returns
     * the input model.
     */
    modelFor<T extends Model>(model: T): T;
    /**
     * Identify members (child properties) of the designated model in this scope.
     */
    membersOf<T extends Model>(parent: T, options?: Scope.MemberOptions): ModelIndex<Model.ChildOf<T>>;
    /**
     * Test whether an element is supported in this scope.
     *
     * We define "supported" as an element that is mandatory given active features or has
     * {@link Model#operationalIsSupported} set.
     */
    hasOperationalSupport(model: Model): boolean;
}
/**
 * Obtain the scope for a model.
 *
 * By default, if {@link subject} is not a {@link ScopeModel} the scope returned is for the nearest owning
 * {@link ScopeModel}.
 */
export declare function Scope(subject: Model, options?: Scope.ScopeOptions): Scope;
export declare namespace Scope {
    /**
     * Configuration for scope creation.
     */
    interface ScopeOptions {
        /**
         * Force the result to cache regardless of whether model is frozen.
         */
        forceCache?: boolean;
        /**
         * Disable loading of model from cache.  Will still write to cache if {@link forceCache} is true.
         */
        disableCache?: boolean;
        /**
         * Force the input model as an owner even if it is not a {@link ScopeOwner}.
         */
        forceOwner?: boolean;
    }
    /**
     * Return all members regardless of conformance.
     */
    const IgnoreConformance = "ignore";
    /**
     * Use conformance to resolve conflicts but otherwise return all members.  Useful to detect errors in input that may
     * contain non-conformant values.
     */
    const DeconflictedConformance = "deconflicted";
    /**
     * Only return conformant members.
     */
    const ConformantConformance = "conformant";
    /**
     * Determines how to apply conformance when selecting members.
     */
    type ConformanceMode = typeof IgnoreConformance | typeof DeconflictedConformance | typeof ConformantConformance;
    interface MemberOptions {
        /**
         * Conformance filtering mode.
         */
        conformance?: ConformanceMode;
        /**
         * Applicable tags.  Defaults to "field" and "attribute".
         */
        tags?: Set<ElementTag> | ElementTag[];
    }
}
//# sourceMappingURL=Scope.d.ts.map