/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
var _a;
import { FieldNodeSchema, FlexTreeEntityKind, boxedIterator, flexTreeMarker, onNextChange, MapNodeSchema, ObjectNodeSchema, } from "../feature-libraries";
import { fail } from "../util";
/** Stores the content of the raw node, i.e. the data that was passed to the factory */
const nodeContent = Symbol();
export function extractRawNodeContent(node) {
    if (node instanceof RawTreeNode) {
        const content = node[nodeContent] ?? fail("Node content may only be extracted once");
        Reflect.deleteProperty(node, nodeContent);
        return content;
    }
    return undefined;
}
export function createRawNode(schema, content) {
    if (schema instanceof ObjectNodeSchema) {
        return new RawObjectNode(schema, content);
    }
    if (schema instanceof MapNodeSchema) {
        return new RawMapNode(schema, content);
    }
    if (schema instanceof FieldNodeSchema) {
        return new RawFieldNode(schema, content);
    }
    fail("Unrecognized schema");
}
/**
 * The base implementation of a node created by {@link createRawNode}.
 */
export class RawTreeNode {
    constructor(schema, content) {
        this.schema = schema;
        this[_a] = FlexTreeEntityKind.Node;
        this.type = schema.name;
        this[nodeContent] = content;
    }
    get context() {
        throw rawError("Getting context");
    }
    get parentField() {
        throw rawError("Accessing parentage");
    }
    is(schema) {
        return schema === this.schema;
    }
    tryGetField(key) {
        throw rawError("Reading fields");
    }
    [(_a = flexTreeMarker, boxedIterator)]() {
        throw rawError("Boxed iteration");
    }
    treeStatus() {
        // TODO: We could add a new TreeStatus for "raw" nodes.
        throw rawError("Status querying");
    }
    on(eventName, listener) {
        throw rawError("Event registration");
    }
    [onNextChange](fn) {
        throw rawError("onNextChange event registration");
    }
}
/**
 * The implementation of an object node created by {@link createRawNode}.
 */
export class RawObjectNode extends RawTreeNode {
    get localNodeKey() {
        throw rawError("Reading local node keys");
    }
}
/**
 * The implementation of a map node created by {@link createRawNode}.
 */
export class RawMapNode extends RawTreeNode {
    get size() {
        return this[nodeContent].size;
    }
    has(key) {
        return this[nodeContent].has(key);
    }
    get(key) {
        return this[nodeContent].get(key);
    }
    getBoxed(key) {
        throw rawError("Reading boxed map values");
    }
    keys() {
        return this[nodeContent].keys();
    }
    values() {
        throw rawError("Iterating map values");
    }
    entries() {
        throw rawError("Iterating map entries");
    }
    forEach(callbackFn, thisArg) {
        throw rawError("Iterating maps with forEach");
    }
    set(key, value) {
        throw rawError("Setting a map entry");
    }
    delete(key) {
        throw rawError("Deleting a map entry");
    }
    get asObject() {
        throw rawError("Converting a map to an object");
    }
    [Symbol.iterator]() {
        return this.entries();
    }
    [boxedIterator]() {
        throw rawError("Boxed iteration");
    }
}
/**
 * The implementation of a field node created by {@link createRawNode}.
 */
export class RawFieldNode extends RawTreeNode {
    get content() {
        throw rawError("Reading content of a list");
    }
    get boxedContent() {
        throw rawError("Reading boxed content of a list");
    }
}
function rawError(message) {
    return new Error(`${message ?? "Operation"} is not supported on content which has not yet been inserted into the tree`);
}
//# sourceMappingURL=rawNode.js.map