import { assert } from "../support/Support.js";
const indexBits = 26;
const indexMask = (1 << indexBits) - 1;
const serialBits = 31 - indexBits;
const serialMask = (1 << serialBits) - 1;
export function isTypeRef(x) {
    return typeof x === "number";
}
export function makeTypeRef(graph, index) {
    assert(index <= indexMask, "Too many types in graph");
    return ((graph.serial & serialMask) << indexBits) | index;
}
export function typeRefIndex(tref) {
    return tref & indexMask;
}
export function assertTypeRefGraph(tref, graph) {
    assert(((tref >> indexBits) & serialMask) === (graph.serial & serialMask), "Mixing the wrong type reference and graph");
}
function getGraph(graphOrBuilder) {
    if ("originalGraph" in graphOrBuilder) {
        return graphOrBuilder.originalGraph;
    }
    // do not use `graphOrBuilder instanceof TypeGraph` to check if is TypeGraph to prevent import cycle
    return graphOrBuilder;
}
export function derefTypeRef(tref, graphOrBuilder) {
    const graph = getGraph(graphOrBuilder);
    assertTypeRefGraph(tref, graph);
    return graph.typeAtIndex(typeRefIndex(tref));
}
export function attributesForTypeRef(tref, graphOrBuilder) {
    const graph = getGraph(graphOrBuilder);
    assertTypeRefGraph(tref, graph);
    return graph.atIndex(typeRefIndex(tref))[1];
}
export function typeAndAttributesForTypeRef(tref, graphOrBuilder) {
    const graph = getGraph(graphOrBuilder);
    assertTypeRefGraph(tref, graph);
    return graph.atIndex(typeRefIndex(tref));
}
