import { EasySAXParser } from '../js-libs/easysax/easysax.js';
/**
 * Specifies the type of parser event.
 */
export class ParserEventType {
}
/**
 * Specifies the StartElement event type.
 */
ParserEventType.StartElement = 'StartElement';
/**
 * Specifies the EndElement event type.
 */
ParserEventType.EndElement = 'EndElement';
/**
 * Specifies the Text event type.
 */
ParserEventType.Text = 'Text';
/**
 * Specifies the CDATA event type.
 */
ParserEventType.CDATA = 'CDATA';
/**
 * Specifies the Comment event type.
 */
ParserEventType.Comment = 'Comment';
/**
 * Provides information for a parser event.
 */
export class ParserEvent {
    constructor(eventType, position, prefix, namespace, elementName, attributes, data) {
        this._eventType = eventType;
        this._position = position;
        this._prefix = prefix;
        this._namespace = namespace;
        this._elementName = elementName;
        this._attributes = attributes;
        this._data = data;
    }
    /**
     * Returns a JSON string representation of this instance.
     */
    toString() {
        return JSON.stringify({
            eventType: this.eventType,
            position: this.position,
            prefix: this.prefix,
            namespace: this.namespace,
            elementName: this.elementName,
            attributes: this.attributes,
            data: this.data,
        });
    }
    /**
     * Returns the type of the parser event. This is one of the ParserEventType static members.
     */
    get eventType() {
        return this._eventType;
    }
    /**
     * Get the position in the xml string where the event was generated.
     */
    get position() {
        return this._position;
    }
    /**
     * If namespace processing is enabled, returns the prefix of the element in case the eventType is ParserEventType.StartElement or ParserEventType.EndElement.
     */
    get prefix() {
        return this._prefix;
    }
    /**
     *  If namespace processing is enabled, returns the namespace of the element in case the eventType is ParserEventType.StartElement or ParserEventType.EndElement.
     */
    get namespace() {
        return this._namespace;
    }
    /**
     * Returns the name of the element in case the eventType is ParserEventType.StartElement or ParserEventType.EndElement.
     */
    get elementName() {
        return this._elementName;
    }
    /**
     * Returns a JSON object with the attributes of an element in case the eventType is ParserEventType.StartElement.
     */
    get attributes() {
        return this._attributes;
    }
    /**
     * Returns the relevant data in case the eventType is ParserEventType.Text, ParserEventType.CDATA or ParserEventType.Comment.
     */
    get data() {
        return this._data;
    }
}
let _ampCodes;
const _entitySearchRegEx = /&#(\d+);|&#x([0123456789abcdef]+);|&(\w+);/gi;
function _generateAmpMap() {
    const objCodes = {
        Tab: 9,
        NewLine: 10,
        excl: 33,
        quot: 34,
        QUOT: 34,
        num: 35,
        dollar: 36,
        percent: 37,
        amp: 38,
        AMP: 38,
        apos: 39,
        lpar: 40,
        rpar: 41,
        ast: 42,
        midast: 42,
        plus: 43,
        comma: 44,
        period: 46,
        sol: 47,
        colon: 58,
        semi: 59,
        lt: 60,
        LT: 60,
        equals: 61,
        gt: 62,
        GT: 62,
        quest: 63,
        commat: 64,
        lsqb: 91,
        lbrack: 91,
        bsol: 92,
        rsqb: 92,
        rbrack: 92,
        Hat: 94,
        lowbar: 95,
        grave: 96,
        DiacriticalGrave: 96,
        lcub: 123,
        lbrace: 123,
        verbar: 124,
        vert: 124,
        VerticalLine: 124,
        rcub: 125,
        rbrace: 125,
        nbsp: 160,
        iexcl: 161,
        cent: 162,
        pound: 163,
        curren: 164,
        yen: 165,
        brvbar: 166,
        brkbar: 166,
        sect: 167,
        uml: 168,
        copy: 169,
        ordf: 170,
        laquo: 171,
        not: 172,
        shy: 173,
        reg: 174,
        macr: 175,
        hibar: 175,
        deg: 176,
        plusmn: 177,
        sup2: 178,
        sup3: 179,
        acute: 180,
        micro: 181,
        para: 182,
        middot: 183,
        cedil: 184,
        sup1: 185,
        ordm: 186,
        raquo: 187,
        frac14: 188,
        frac12: 189,
        frac34: 190,
        iquest: 191,
        Agrave: 192,
        Aacute: 193,
        Acirc: 194,
        Atilde: 195,
        Auml: 196,
        Aring: 197,
        AElig: 198,
        Ccedil: 199,
        Egrave: 200,
        Eacute: 201,
        Ecirc: 202,
        Euml: 203,
        Igrave: 204,
        Iacute: 205,
        Icirc: 206,
        Iuml: 207,
        ETH: 208,
        Dstrok: 208,
        Ntilde: 209,
        Ograve: 210,
        Oacute: 211,
        Ocirc: 212,
        Otilde: 213,
        Ouml: 214,
        times: 215,
        Oslash: 216,
        Ugrave: 217,
        Uacute: 218,
        Ucirc: 219,
        Uuml: 220,
        Yacute: 221,
        THORN: 222,
        szlig: 223,
        agrave: 224,
        aacute: 225,
        acirc: 226,
        atilde: 227,
        auml: 228,
        aring: 229,
        aelig: 230,
        ccedil: 231,
        egrave: 232,
        eacute: 233,
        ecirc: 234,
        euml: 235,
        igrave: 236,
        iacute: 237,
        icirc: 238,
        iuml: 239,
        eth: 240,
        ntilde: 241,
        ograve: 242,
        oacute: 243,
        ocirc: 244,
        otilde: 245,
        ouml: 246,
        divide: 247,
        oslash: 248,
        ugrave: 249,
        uacute: 250,
        ucirc: 251,
        uuml: 252,
        yacute: 253,
        thorn: 254,
        yuml: 255,
        fnof: 402,
        imped: 437,
        gacute: 501,
        jmath: 567,
        circ: 710,
        caron: 711,
        Hacek: 711,
        breve: 728,
        Breve: 728,
        dot: 729,
        DiacriticalDot: 729,
        ring: 730,
        ogon: 731,
        tilde: 732,
        DiacriticalTilde: 732,
        dblac: 733,
        DiacriticalDoubleAcute: 733,
        DownBreve: 785,
        UnderBar: 818,
        Alpha: 913,
        Beta: 914,
        Gamma: 915,
        Delta: 916,
        Epsilon: 917,
        Zeta: 918,
        Eta: 919,
        Theta: 920,
        Iota: 921,
        Kappa: 922,
        Lambda: 923,
        Mu: 924,
        Nu: 925,
        Xi: 926,
        Omicron: 927,
        Pi: 928,
        Rho: 929 /* 930 is not real */,
        Sigma: 931,
        Tau: 932,
        Upsilon: 933,
        Phi: 934,
        Chi: 935,
        Psi: 936,
        Omega: 937,
        alpha: 945,
        beta: 946,
        gamma: 947,
        delta: 948,
        epsilon: 949,
        epsiv: 949,
        varepsilon: 949,
        zeta: 950,
        eta: 951,
        theta: 952,
        iota: 953,
        kappa: 954,
        lambda: 955,
        mu: 956,
        nu: 957,
        xi: 958,
        omicron: 959,
        pi: 960,
        rho: 961,
        sigmaf: 962,
        sigmav: 962,
        varsigma: 962,
        sigma: 963,
        tau: 964,
        upsilon: 965,
        phi: 966,
        chi: 967,
        psi: 968,
        omega: 969,
        thetav: 977,
        vartheta: 977,
        thetasym: 977,
        Upsi: 978,
        upsih: 978,
        straightphi: 981,
        piv: 982,
        varpi: 982,
        Gammad: 988,
        gammad: 989,
        digamma: 989,
        kappav: 1008,
        varkappa: 1008,
        rhov: 1009,
        varrho: 1009,
        epsi: 1013,
        straightepsilon: 1013,
        bepsi: 1014,
        backepsilon: 1014,
        /* Skipped Codes 1015 - 1119 */ euro: 8364,
        trade: 8482,
        TRADE: 8482,
        forall: 8704,
        part: 8706,
        larr: 8592,
        rarr: 8593,
        hyphen: 8208,
        dash: 8208,
        ndash: 8211,
        mdash: 8212,
        horbar: 8213,
        Vert: 8214,
        Verbar: 8214,
        lsquo: 8216,
        OpenCurlyQuote: 8216,
        rsquo: 8217,
        rsquor: 8217,
        CloseCurlyQuote: 8217,
        lsquor: 8218,
        sbquo: 8218,
        ldquo: 8220,
        OpenCurlyDoubleQuote: 8220,
        rdquo: 8221,
        rdquor: 8221,
        CloseCurlyDoubleQuote: 8221,
        ldquor: 8222,
        bdquo: 8222,
        dagger: 8224,
        Dagger: 8225,
        ddagger: 8225,
        bull: 8226,
        bullet: 8226,
        nldr: 8229,
        hellip: 8230,
        mldr: 8230,
        hybull: 8259,
        tdot: 8411,
        TripleDot: 8411,
        DotDot: 8412,
        star: 9734,
        phone: 9742,
        spades: 9824,
        clubs: 9827,
        hearts: 9829,
        diams: 9830,
        female: 9792,
        male: 9794,
        check: 10003,
        checkmark: 10003,
        cross: 10007,
        VerticalSeparator: 10072,
        EmptySmallSquare: 9723,
        FilledSmallSquare: 9724,
        starf: 9733,
        bigstar: 9733,
        square: 9633,
        squ: 9633,
        Square: 9633,
    };
    const ampCodes = new Map();
    for (const key in objCodes) {
        if (objCodes.hasOwnProperty(key)) {
            ampCodes.set(key, objCodes[key]);
        }
    }
    return ampCodes;
}
// android-specific implementation, which pre-populates the map to get it saved into the heap blob
if (global.__snapshot) {
    _ampCodes = _generateAmpMap();
}
function _HandleAmpEntities(found, decimalValue, hexValue, wordValue) {
    if (wordValue) {
        if (!_ampCodes) {
            _ampCodes = _generateAmpMap();
        }
        const res = _ampCodes.get(wordValue);
        if (res) {
            return String.fromCodePoint(res);
        }
        // Invalid word; so we just return it
        return found;
    }
    if (decimalValue) {
        return String.fromCodePoint(parseInt(decimalValue, 10));
    }
    return String.fromCodePoint(parseInt(hexValue, 16));
}
/**
 * A simple non-validating SAX parser based on https://github.com/vflash/easysax version 0.1.14
 */
export class XmlParser {
    /**
     * Creates a new instance of the XmlParser class.
     * @param onEvent The callback to execute when a parser event occurs. The 'event' parameter contains information about the event.
     * @param onError The callback to execute when a parser error occurs. The 'error' parameter contains the error.
     * @param processNamespaces Specifies whether namespaces should be processed.
     */
    constructor(onEvent, onError, processNamespaces) {
        this._processNamespaces = processNamespaces;
        this._parser = new EasySAXParser();
        const that = this;
        this._parser.on('startNode', function (elem, attr, uq, tagend, str, pos) {
            let attributes = attr();
            if (attributes === true) {
                //HACK: For some reason easysax returns the true literal when an element has no attributes.
                attributes = undefined;
            }
            if (attributes) {
                for (const key in attributes) {
                    if (attributes.hasOwnProperty(key)) {
                        // Convert entities such as &gt; to >
                        attributes[key] = XmlParser._dereferenceEntities(attributes[key]);
                    }
                }
            }
            let prefix = undefined;
            let namespace = undefined;
            let name = elem;
            if (that._processNamespaces) {
                const stackEntry = XmlParser._getNamespacesStackEntry(attributes);
                that._namespaceStack.push(stackEntry);
                const resolved = that._resolveNamespace(name);
                prefix = resolved.prefix;
                namespace = resolved.namespace;
                name = resolved.name;
            }
            onEvent(new ParserEvent(ParserEventType.StartElement, pos(), prefix, namespace, name, attributes, undefined));
        });
        this._parser.on('textNode', function (text, uq, pos) {
            const data = uq(XmlParser._dereferenceEntities(text)); // Decode entity references such as &lt; and &gt;
            onEvent(new ParserEvent(ParserEventType.Text, pos(), undefined, undefined, undefined, undefined, data));
        });
        this._parser.on('endNode', function (elem, uq, tagstart, str, pos) {
            let prefix = undefined;
            let namespace = undefined;
            let name = elem;
            if (that._processNamespaces) {
                const resolved = that._resolveNamespace(name);
                prefix = resolved.prefix;
                namespace = resolved.namespace;
                name = resolved.name;
            }
            onEvent(new ParserEvent(ParserEventType.EndElement, pos(), prefix, namespace, name, undefined, undefined));
            if (that._processNamespaces) {
                that._namespaceStack.pop();
            }
        });
        this._parser.on('cdata', function (data, res, pos) {
            onEvent(new ParserEvent(ParserEventType.CDATA, pos(), undefined, undefined, undefined, undefined, data));
        });
        this._parser.on('comment', function (text, uq, pos) {
            onEvent(new ParserEvent(ParserEventType.Comment, pos(), undefined, undefined, undefined, undefined, text));
        });
        if (onError) {
            this._parser.on('error', function (msg, pos) {
                onError(new Error(msg), pos());
            });
        }
    }
    get angularSyntax() {
        return this._parser.angularSyntax;
    }
    set angularSyntax(value) {
        this._parser.angularSyntax = value;
    }
    /**
     * Parses the supplied xml string.
     * @param xmlString The string containing the xml to parse.
     */
    parse(xmlString) {
        if (this._processNamespaces) {
            this._namespaceStack = [];
        }
        this._parser.parse(xmlString);
    }
    static _getNamespacesStackEntry(attributes) {
        const stackEntry = {};
        if (!attributes) {
            return stackEntry;
        }
        let attributeName;
        let namespacePrefix;
        for (const key in attributes) {
            if (!attributes.hasOwnProperty(key)) {
                continue;
            }
            attributeName = key;
            if (attributeName.indexOf('xmlns') !== 0) {
                // This is a normal attribute, so go on.
                continue;
            }
            namespacePrefix = '';
            if (attributeName.indexOf(':') !== -1) {
                namespacePrefix = attributeName.split(':')[1];
            }
            stackEntry[namespacePrefix] = attributes[key];
        }
        return stackEntry;
    }
    _resolveNamespace(fullName) {
        const result = {
            prefix: undefined,
            namespace: undefined,
            name: undefined,
        };
        result.prefix = '';
        if (fullName.indexOf(':') !== -1) {
            const split = fullName.split(':');
            result.prefix = split[0];
            result.name = split[1];
        }
        else {
            result.name = fullName;
        }
        let stackEntry;
        for (let i = this._namespaceStack.length - 1; i >= 0; i--) {
            stackEntry = this._namespaceStack[i];
            for (const key in stackEntry) {
                if (!stackEntry.hasOwnProperty(key)) {
                    continue;
                }
                if (result.prefix === key) {
                    result.namespace = stackEntry[key];
                    return result;
                }
            }
        }
        return result;
    }
    static _dereferenceEntities(s) {
        s = String(s);
        if (s.length > 3 && s.indexOf('&') !== -1) {
            s = s.replace(_entitySearchRegEx, _HandleAmpEntities);
        }
        return s;
    }
}
//# sourceMappingURL=index.js.map