/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { type TreeNodeSchemaClass } from "./treeNodeSchema.js";
import { type WithType, typeNameSymbol, type typeSchemaSymbol } from "./withType.js";
/**
 * A non-{@link NodeKind.Leaf|leaf} SharedTree node. Includes objects, arrays, and maps.
 *
 * @remarks
 * Base type which all nodes extend.
 *
 * This type can be used as a type to indicate/document values which should be tree nodes.
 * Runtime use of this class object (for example when used with `instanceof` or extending it), is not currently supported.
 *
 * There are three ways to get instances of TreeNode:
 *
 * 1. From a {@link TreeView} loading nodes from an existing document, or creating local copies of nodes inserted by a remote collaborator.
 * This case provides an {@link InternalTreeNode} to the constructor: subclasses must not modify how the constructor handles this case.
 *
 * 2. Explicit construction of {@link Unhydrated} nodes using either {@link TreeNodeSchemaClass} as a constructor or {@link TreeNodeSchemaNonClass|TreeNodeSchemaNonClass.create}.
 * Either way the {@link TreeNodeSchema} produced must be produced using a {@link SchemaFactory}.
 *
 * 3. Implicit construction: Several APIs which logically require an unhydrated TreeNode also allow passing in a value which could be used to explicitly construct the node instead.
 * These APIs internally call the constructor with the provided value, so it's really just a special case of the above option.
 * Note that when constructing nodes, sometimes implicit construction is not allowed
 * (either at runtime due to ambiguous types or at compile time due to TypeScript limitations):
 * in such cases, explicit construction must be used.
 *
 * @privateRemarks
 * This is a class not an interface to enable stricter type checking (see {@link TreeNode.#brand})
 * and some runtime enforcement of schema class policy (see the the validation in the constructor).
 * This class is however only `type` exported not value exported, preventing the class object from being used,
 * similar to how interfaces work.
 *
 * Not all node implementations include this in their prototype chain (some hide it with a proxy),
 * and thus cause the default/built in `instanceof` to return false despite our type checking and all other APIs treating them as TreeNodes.
 * This class provides a custom `Symbol.hasInstance` to fix `instanceof` for this class and all classes extending it.
 * For now the type-only export prevents use of `instanceof` on this class (but allows it in subclasses like schema classes).
 * @sealed @public
 */
export declare abstract class TreeNode implements WithType {
    #private;
    /**
     * Adds a type symbol for stronger typing.
     * @privateRemarks
     * Subclasses provide more specific strings for this to get strong typing of otherwise type compatible nodes.
     * @deprecated Use {@link typeSchemaSymbol} instead.
     */
    abstract get [typeNameSymbol](): string;
    /**
     * Adds a type symbol for stronger typing.
     * @privateRemarks
     * Subclasses provide more specific strings for this to get strong typing of otherwise type compatible nodes.
     */
    abstract get [typeSchemaSymbol](): TreeNodeSchemaClass;
    /**
     * Provides `instanceof` support for testing if a value is a `TreeNode`.
     * @remarks
     * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
     * @privateRemarks
     * Due to type-only export, this functionality is not available outside the package.
     */
    static [Symbol.hasInstance](value: unknown): value is TreeNode;
    /**
     * Provides `instanceof` support for all schema classes with public constructors.
     * @remarks
     * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
     * @privateRemarks
     * Despite type-only export, this functionality is available outside the package since it is inherited by subclasses.
     */
    static [Symbol.hasInstance]<TSchema extends abstract new (...args: any[]) => TreeNode>(this: TSchema, value: unknown): value is InstanceType<TSchema>;
    /**
     * TreeNodes must extend schema classes created by SchemaFactory, and therefore this constructor should not be invoked directly by code outside this package.
     * @privateRemarks
     * `token` must be the {@link privateToken} value, which is not package exported.
     * This is used to detect invalid subclasses.
     *
     * All valid subclass should use {@link TreeNodeValid}, but this code doesn't directly reference it to avoid cyclic dependencies.
     */
    protected constructor(token: unknown);
}
/**
 * `token` to pass to {@link TreeNode}'s constructor used to detect invalid subclasses.
 */
export declare const privateToken: {};
/**
 * Check if the prototype derived's prototype chain contains `base`.
 * @param derived - prototype to check
 * @param base - prototype to search for
 * @returns true iff `base` is in the prototype chain starting at `derived`.
 */
export declare function inPrototypeChain(derived: object | null, base: object): boolean;
//# sourceMappingURL=treeNode.d.ts.map