/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { Brand } from "../../util/index.js";
import type { FieldKey } from "../schema-stored/index.js";
import { type DetachedField } from "./types.js";
/**
 * Identical to {@link UpPath}, but a duplicate declaration is needed to make
 * the default type parameter compile.
 */
export type UpPathDefault = UpPath;
/**
 * Path from a location in the tree upward.
 * UpPaths can be used with deduplicated upper parts to allow
 * working with paths localized to part of the tree without incurring
 * costs related to the depth of the local subtree.
 *
 * UpPaths can be thought of as terminating at a special root node (that is `undefined`)
 * whose FieldKeys correspond to detached sequences.
 *
 * UpPaths can be mutated over time and should be considered to be invalidated when any edits occurs:
 * Use of an UpPath that was acquired before the most recent edit is undefined behavior.
 */
export interface UpPath<TParent = UpPathDefault> {
    /**
     * The parent, or undefined in the case where this path is a member of a detached sequence.
     */
    readonly parent: TParent | undefined;
    /**
     * The Field under which this path points.
     * Note that if `parent` returns `undefined`, this key corresponds to a detached sequence.
     */
    readonly parentField: FieldKey;
    /**
     * The index within `parentField` this path is pointing to.
     */
    readonly parentIndex: NodeIndex;
}
/**
 * Path from a field in the tree upward.
 *
 * See {@link UpPath}.
 */
export interface FieldUpPath<TUpPath extends UpPath = UpPath> {
    /**
     * The parent, or undefined in the case where this path is to a detached sequence.
     */
    readonly parent: TUpPath | undefined;
    /**
     * The Field to which this path points.
     * Note that if `parent` returns `undefined`, this key  corresponds to a detached sequence.
     */
    readonly field: FieldKey;
}
/**
 * A range of nodes in a detached field.
 * Unlike RangeUpPath, such ranges are generated by create and detach operations,
 * as well as consumed by destroy and attach operations.
 */
export type DetachedRangeUpPath = Brand<Omit<RangeUpPath, "parent">, "DetachedRangeUpPath">;
/**
 * Delimits the extend of a range.
 */
export interface Range {
    /**
     * The location before the first node.
     * Must be less than or equal to `end`.
     */
    readonly start: PlaceIndex;
    /**
     * The location after the last node.
     * Must be greater than or equal to `start`.
     */
    readonly end: PlaceIndex;
}
/**
 * A possibly empty range of nodes in a field.
 * This object only characterizes the location of the range, it does not own/contain the nodes in the range.
 */
export interface RangeUpPath<TUpPath extends UpPath = UpPath> extends FieldUpPath<TUpPath>, Range {
}
/**
 * A place in a field.
 */
export interface PlaceUpPath<TUpPath extends UpPath = UpPath> extends FieldUpPath<TUpPath> {
    /**
     * The location in the field.
     */
    readonly index: PlaceIndex;
}
/**
 * A place in a detached field.
 */
export type DetachedPlaceUpPath = Brand<Omit<PlaceUpPath, "parent">, "DetachedRangeUpPath">;
/**
 * Indicates the index of a node in a field.
 * Zero indicates the first node in a field.
 */
export type NodeIndex = number;
/**
 * Indicates a place between nodes in a field or at the extremity of a field.
 * Zero indicates the place at the start of the field (before the first node if any).
 */
export type PlaceIndex = number;
/**
 * @returns the number of nodes above this one.
 * Zero when the path's parent is undefined, meaning the path represents a node in a detached field.
 * Runs in O(depth) time.
 */
export declare function getDepth(path: UpPath): number;
/**
 * @returns a deep copy of the provided path as simple javascript objects.
 * This is safe to hold onto and use deep object comparisons on.
 */
export declare function clonePath(path: UpPath): UpPath;
/**
 * @returns a deep copy of the provided path as simple javascript objects.
 * This is safe to hold onto and use deep object comparisons on.
 */
export declare function clonePath(path: UpPath | undefined): UpPath | undefined;
/**
 * @returns The elements of the given `path`, ordered from root-most to child-most.
 * These elements are unchanged and therefore still point "up".
 */
export declare function topDownPath(path: UpPath | undefined): UpPath[];
/**
 * @returns true iff `a` and `b` describe the same path.
 *
 * Note that for mutable paths (as used in `AnchorSet`), this equality may change over time: this only checks if the two paths are currently the same.
 */
export declare function compareUpPaths(a: UpPath | undefined, b: UpPath | undefined): boolean;
/**
 * @returns true iff `a` and `b` describe the same field path.
 *
 * Note that for mutable paths (as used in `AnchorSet`), this equality may change over time: this only checks if the two paths are currently the same.
 */
export declare function compareFieldUpPaths(a: FieldUpPath, b: FieldUpPath): boolean;
/**
 * Checks whether or not a given path is parented under the root field.
 * @param path - the path you want to check.
 * @returns the {@link DetachedField} which contains the path.
 */
export declare function getDetachedFieldContainingPath(path: UpPath): DetachedField;
//# sourceMappingURL=pathTree.d.ts.map