"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.compareFieldUpPaths = exports.compareUpPaths = exports.topDownPath = exports.clonePath = exports.getDepth = void 0;
/**
 * @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.
 */
function getDepth(path) {
    let depth = 0;
    let next = path.parent;
    while (next !== undefined) {
        depth += 1;
        next = next.parent;
    }
    return depth;
}
exports.getDepth = getDepth;
function clonePath(path) {
    if (path === undefined) {
        return undefined;
    }
    return {
        parent: clonePath(path.parent),
        parentField: path.parentField,
        parentIndex: path.parentIndex,
    };
}
exports.clonePath = clonePath;
/**
 * @returns The elements of the given `path`, ordered from root-most to child-most.
 * These elements are unchanged and therefore still point "up".
 */
function topDownPath(path) {
    const out = [];
    let curr = path;
    while (curr !== undefined) {
        out.push(curr);
        curr = curr.parent;
    }
    out.reverse();
    return out;
}
exports.topDownPath = topDownPath;
/**
 * @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.
 */
function compareUpPaths(a, b) {
    if (a === b) {
        // This handles the both `undefined` case, as well as provides an early out if a shared node is encountered.
        return true;
    }
    if (a === undefined || b === undefined) {
        return false;
    }
    if (a.parentField !== b.parentField || a.parentIndex !== b.parentIndex) {
        return false;
    }
    return compareUpPaths(a.parent, b.parent);
}
exports.compareUpPaths = compareUpPaths;
/**
 * @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.
 */
function compareFieldUpPaths(a, b) {
    if (a.field !== b.field) {
        return false;
    }
    return compareUpPaths(a.parent, b.parent);
}
exports.compareFieldUpPaths = compareFieldUpPaths;
//# sourceMappingURL=pathTree.js.map