"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertDataListIfAny = exports.isInstruction = exports.isMichelsonType = exports.isMichelsonCode = exports.isMichelsonData = exports.isMichelsonScript = exports.assertMichelsonContract = exports.assertMichelsonData = exports.assertMichelsonType = exports.assertMichelsonBigMapStorableType = exports.assertMichelsonPassableType = exports.assertMichelsonStorableType = exports.assertMichelsonPushableType = exports.assertMichelsonPackableType = exports.assertMichelsonComparableType = exports.assertMichelsonInstruction = exports.MichelsonValidationError = exports.instructionIDs = void 0;
var utils_1 = require("./utils");
// Michelson validator
var noArgInstructionIDs = {
    "ABS": true, "ADD": true, "ADDRESS": true, "AMOUNT": true, "AND": true, "APPLY": true, "BALANCE": true,
    "BLAKE2B": true, "CAR": true, "CDR": true, "CHAIN_ID": true, "CHECK_SIGNATURE": true, "COMPARE": true, "CONCAT": true, "CONS": true, "EDIV": true,
    "EQ": true, "EXEC": true, "FAILWITH": true, "GE": true, "GET_AND_UPDATE": true, "GT": true, "HASH_KEY": true, "IMPLICIT_ACCOUNT": true,
    "INT": true, "ISNAT": true, "JOIN_TICKETS": true, "KECCAK": true, "LE": true, "LEVEL": true, "LSL": true, "LSR": true, "LT": true, "MEM": true, "MUL": true,
    "NEG": true, "NEQ": true, "NEVER": true, "NOT": true, "NOW": true, "OR": true, "PACK": true, "PAIRING_CHECK": true, "READ_TICKET": true,
    "SAPLING_VERIFY_UPDATE": true, "SELF": true, "SELF_ADDRESS": true, "SENDER": true, "SET_DELEGATE": true, "SHA256": true, "SHA3": true,
    "SHA512": true, "SIZE": true, "SLICE": true, "SOME": true, "SOURCE": true, "SPLIT_TICKET": true, "SUB": true, "SWAP": true, "TICKET": true,
    "TOTAL_VOTING_POWER": true, "TRANSFER_TOKENS": true, "UNIT": true, "VOTING_POWER": true, "XOR": true, "RENAME": true,
};
exports.instructionIDs = Object.assign({}, noArgInstructionIDs, {
    "CONTRACT": true, "CREATE_CONTRACT": true, "DIG": true, "DIP": true, "DROP": true,
    "DUG": true, "DUP": true, "EMPTY_BIG_MAP": true, "EMPTY_MAP": true, "EMPTY_SET": true, "GET": true, "IF": true, "IF_CONS": true, "IF_LEFT": true,
    "IF_NONE": true, "ITER": true, "LAMBDA": true, "LEFT": true, "LOOP": true, "LOOP_LEFT": true, "MAP": true, "NIL": true, "NONE": true, "PAIR": true,
    "PUSH": true, "RIGHT": true, "SAPLING_EMPTY_STATE": true, "UNPACK": true, "UNPAIR": true, "UPDATE": true, "CAST": true,
});
var simpleComparableTypeIDs = {
    "unit": true, "never": true, "bool": true, "int": true, "nat": true, "string": true,
    "chain_id": true, "bytes": true, "mutez": true, "key_hash": true, "key": true,
    "signature": true, "timestamp": true, "address": true,
};
var typeIDs = Object.assign({}, simpleComparableTypeIDs, {
    "or": true, "pair": true, "set": true, "big_map": true, "contract": true, "lambda": true,
    "list": true, "map": true, "operation": true, "option": true, "bls12_381_g1": true,
    "bls12_381_g2": true, "bls12_381_fr": true, "sapling_transaction": true, "sapling_state": true, "ticket": true,
});
var MichelsonValidationError = /** @class */ (function (_super) {
    __extends(MichelsonValidationError, _super);
    /**
     * @param val Value of a node caused the error
     * @param message An error message
     */
    function MichelsonValidationError(val, message) {
        var _this = _super.call(this, val, message) || this;
        _this.val = val;
        Object.setPrototypeOf(_this, MichelsonValidationError.prototype);
        return _this;
    }
    return MichelsonValidationError;
}(utils_1.MichelsonError));
exports.MichelsonValidationError = MichelsonValidationError;
function isPrim(ex) {
    return "prim" in ex;
}
function isPrimOrSeq(ex) {
    return Array.isArray(ex) || "prim" in ex;
}
function assertPrim(ex) {
    if (isPrim(ex)) {
        return true;
    }
    throw new MichelsonValidationError(ex, "prim expression expected");
}
function assertSeq(ex) {
    if (Array.isArray(ex)) {
        return true;
    }
    throw new MichelsonValidationError(ex, "sequence expression expected");
}
function assertPrimOrSeq(ex) {
    if (isPrimOrSeq(ex)) {
        return true;
    }
    throw new MichelsonValidationError(ex, "prim or sequence expression expected");
}
function assertNatural(i) {
    if (i.int[0] === "-") {
        throw new MichelsonValidationError(i, "natural number expected");
    }
}
function assertIntLiteral(ex) {
    if ("int" in ex) {
        return true;
    }
    throw new MichelsonValidationError(ex, "int literal expected");
}
function assertArgs(ex, n) {
    var _a;
    if ((n === 0 && ex.args === undefined) || ((_a = ex.args) === null || _a === void 0 ? void 0 : _a.length) === n) {
        return true;
    }
    throw new MichelsonValidationError(ex, n + " arguments expected");
}
/**
 * Checks if the node is a valid Michelson code (sequence of instructions).
 * This is a type guard function which either returns true of throws an exception.
 * @param ex An AST node
 */
function assertMichelsonInstruction(ex) {
    var e_1, _a;
    var _b, _c;
    if (Array.isArray(ex)) {
        try {
            for (var ex_1 = __values(ex), ex_1_1 = ex_1.next(); !ex_1_1.done; ex_1_1 = ex_1.next()) {
                var n = ex_1_1.value;
                if (!Array.isArray(n) && !isPrim(n)) {
                    throw new MichelsonValidationError(ex, "sequence or prim expected");
                }
                assertMichelsonInstruction(n);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (ex_1_1 && !ex_1_1.done && (_a = ex_1.return)) _a.call(ex_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return true;
    }
    if (assertPrim(ex)) {
        if (Object.prototype.hasOwnProperty.call(noArgInstructionIDs, ex.prim)) {
            assertArgs(ex, 0);
            return true;
        }
        switch (ex.prim) {
            case "DROP":
            case "PAIR":
            case "UNPAIR":
            case "DUP":
            case "UPDATE":
            case "GET":
                if (ex.args !== undefined && assertArgs(ex, 1)) {
                    /* istanbul ignore else */
                    if (assertIntLiteral(ex.args[0])) {
                        assertNatural(ex.args[0]);
                    }
                }
                break;
            case "DIG":
            case "DUG":
            case "SAPLING_EMPTY_STATE":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    /* istanbul ignore else */
                    if (assertIntLiteral(ex.args[0])) {
                        assertNatural(ex.args[0]);
                    }
                }
                break;
            case "NONE":
            case "LEFT":
            case "RIGHT":
            case "NIL":
            case "CAST":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonType(ex.args[0]);
                }
                break;
            case "UNPACK":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonPackableType(ex.args[0]);
                }
                break;
            case "CONTRACT":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonPassableType(ex.args[0]);
                }
                break;
            case "IF_NONE":
            case "IF_LEFT":
            case "IF_CONS":
            case "IF":
                /* istanbul ignore else */
                if (assertArgs(ex, 2)) {
                    /* istanbul ignore else */
                    if (assertSeq(ex.args[0])) {
                        assertMichelsonInstruction(ex.args[0]);
                    }
                    /* istanbul ignore else */
                    if (assertSeq(ex.args[1])) {
                        assertMichelsonInstruction(ex.args[1]);
                    }
                }
                break;
            case "MAP":
            case "ITER":
            case "LOOP":
            case "LOOP_LEFT":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonInstruction(ex.args[0]);
                }
                break;
            case "CREATE_CONTRACT":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonContract(ex.args[0]);
                }
                break;
            case "DIP":
                if (((_b = ex.args) === null || _b === void 0 ? void 0 : _b.length) === 2) {
                    /* istanbul ignore else */
                    if (assertIntLiteral(ex.args[0])) {
                        assertNatural(ex.args[0]);
                    }
                    /* istanbul ignore else */
                    if (assertSeq(ex.args[1])) {
                        assertMichelsonInstruction(ex.args[1]);
                    }
                }
                else if (((_c = ex.args) === null || _c === void 0 ? void 0 : _c.length) === 1) {
                    /* istanbul ignore else */
                    if (assertSeq(ex.args[0])) {
                        assertMichelsonInstruction(ex.args[0]);
                    }
                }
                else {
                    throw new MichelsonValidationError(ex, "1 or 2 arguments expected");
                }
                break;
            case "PUSH":
                /* istanbul ignore else */
                if (assertArgs(ex, 2)) {
                    assertMichelsonPushableType(ex.args[0]);
                    assertMichelsonData(ex.args[1]);
                }
                break;
            case "EMPTY_SET":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonComparableType(ex.args[0]);
                }
                break;
            case "EMPTY_MAP":
                /* istanbul ignore else */
                if (assertArgs(ex, 2)) {
                    assertMichelsonComparableType(ex.args[0]);
                    assertMichelsonType(ex.args[1]);
                }
                break;
            case "EMPTY_BIG_MAP":
                /* istanbul ignore else */
                if (assertArgs(ex, 2)) {
                    assertMichelsonComparableType(ex.args[0]);
                    assertMichelsonBigMapStorableType(ex.args[1]);
                }
                break;
            case "LAMBDA":
                /* istanbul ignore else */
                if (assertArgs(ex, 3)) {
                    assertMichelsonType(ex.args[0]);
                    assertMichelsonType(ex.args[1]);
                    /* istanbul ignore else */
                    if (assertSeq(ex.args[2])) {
                        assertMichelsonInstruction(ex.args[2]);
                    }
                }
                break;
            default:
                throw new MichelsonValidationError(ex, "instruction expected");
        }
    }
    return true;
}
exports.assertMichelsonInstruction = assertMichelsonInstruction;
function assertMichelsonComparableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (Array.isArray(ex) || ex.prim === "pair" || ex.prim === "or" || ex.prim === "option") {
            traverseType(ex, function (ex) { return assertMichelsonComparableType(ex); });
        }
        else if (!Object.prototype.hasOwnProperty.call(simpleComparableTypeIDs, ex.prim)) {
            throw new MichelsonValidationError(ex, ex.prim + ": type is not comparable");
        }
    }
    return true;
}
exports.assertMichelsonComparableType = assertMichelsonComparableType;
function assertMichelsonPackableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim) ||
                ex.prim === "big_map" ||
                ex.prim === "operation" ||
                ex.prim === "sapling_state" ||
                ex.prim === "ticket") {
                throw new MichelsonValidationError(ex, ex.prim + ": type can't be used inside PACK/UNPACK instructions");
            }
            traverseType(ex, function (ex) { return assertMichelsonPackableType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonPackableType = assertMichelsonPackableType;
function assertMichelsonPushableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim) ||
                ex.prim === "big_map" ||
                ex.prim === "operation" ||
                ex.prim === "sapling_state" ||
                ex.prim === "ticket" ||
                ex.prim === "contract") {
                throw new MichelsonValidationError(ex, ex.prim + ": type can't be pushed");
            }
            traverseType(ex, function (ex) { return assertMichelsonPushableType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonPushableType = assertMichelsonPushableType;
function assertMichelsonStorableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim) ||
                ex.prim === "operation" ||
                ex.prim === "contract") {
                throw new MichelsonValidationError(ex, ex.prim + ": type can't be used as part of a storage");
            }
            traverseType(ex, function (ex) { return assertMichelsonStorableType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonStorableType = assertMichelsonStorableType;
function assertMichelsonPassableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim) ||
                ex.prim === "operation") {
                throw new MichelsonValidationError(ex, ex.prim + ": type can't be used as part of a parameter");
            }
            traverseType(ex, function (ex) { return assertMichelsonPassableType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonPassableType = assertMichelsonPassableType;
function assertMichelsonBigMapStorableType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim) ||
                ex.prim === "big_map" ||
                ex.prim === "operation" ||
                ex.prim === "sapling_state") {
                throw new MichelsonValidationError(ex, ex.prim + ": type can't be used inside a big_map");
            }
            traverseType(ex, function (ex) { return assertMichelsonBigMapStorableType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonBigMapStorableType = assertMichelsonBigMapStorableType;
/**
 * Checks if the node is a valid Michelson type expression.
 * This is a type guard function which either returns true of throws an exception.
 * @param ex An AST node
 */
function assertMichelsonType(ex) {
    /* istanbul ignore else */
    if (assertPrimOrSeq(ex)) {
        if (isPrim(ex)) {
            if (!Object.prototype.hasOwnProperty.call(typeIDs, ex.prim)) {
                throw new MichelsonValidationError(ex, "type expected");
            }
            traverseType(ex, function (ex) { return assertMichelsonType(ex); });
        }
    }
    return true;
}
exports.assertMichelsonType = assertMichelsonType;
function traverseType(ex, cb) {
    if (Array.isArray(ex) || ex.prim === "pair") {
        var args = Array.isArray(ex) ? ex : ex.args;
        if (args === undefined || args.length < 2) {
            throw new MichelsonValidationError(ex, "at least 2 arguments expected");
        }
        args.forEach(function (a) {
            if (assertPrimOrSeq(a)) {
                cb(a);
            }
        });
        return true;
    }
    switch (ex.prim) {
        case "option":
        case "list":
            /* istanbul ignore else */
            if (assertArgs(ex, 1) && assertPrimOrSeq(ex.args[0])) {
                cb(ex.args[0]);
            }
            break;
        case "contract":
            /* istanbul ignore else */
            if (assertArgs(ex, 1)) {
                assertMichelsonPassableType(ex.args[0]);
            }
            break;
        case "or":
            /* istanbul ignore else */
            if (assertArgs(ex, 2) && assertPrimOrSeq(ex.args[0]) && assertPrimOrSeq(ex.args[1])) {
                cb(ex.args[0]);
                cb(ex.args[1]);
            }
            break;
        case "lambda":
            /* istanbul ignore else */
            if (assertArgs(ex, 2)) {
                assertMichelsonType(ex.args[0]);
                assertMichelsonType(ex.args[1]);
            }
            break;
        case "set":
            /* istanbul ignore else */
            if (assertArgs(ex, 1)) {
                assertMichelsonComparableType(ex.args[0]);
            }
            break;
        case "map":
            /* istanbul ignore else */
            if (assertArgs(ex, 2) && assertPrimOrSeq(ex.args[0]) && assertPrimOrSeq(ex.args[1])) {
                assertMichelsonComparableType(ex.args[0]);
                cb(ex.args[1]);
            }
            break;
        case "big_map":
            /* istanbul ignore else */
            if (assertArgs(ex, 2) && assertPrimOrSeq(ex.args[0]) && assertPrimOrSeq(ex.args[1])) {
                assertMichelsonComparableType(ex.args[0]);
                assertMichelsonBigMapStorableType(ex.args[1]);
                cb(ex.args[1]);
            }
            break;
        case "ticket":
            /* istanbul ignore else */
            if (assertArgs(ex, 1) && assertPrimOrSeq(ex.args[0])) {
                assertMichelsonComparableType(ex.args[0]);
            }
            break;
        case "sapling_state":
        case "sapling_transaction":
            if (assertArgs(ex, 1)) {
                assertIntLiteral(ex.args[0]);
            }
            break;
        default:
            assertArgs(ex, 0);
    }
    return true;
}
/**
 * Checks if the node is a valid Michelson data literal such as `(Pair {Elt "0" 0} 0)`.
 * This is a type guard function which either returns true of throws an exception.
 * @param ex An AST node
 */
function assertMichelsonData(ex) {
    var e_2, _a, e_3, _b;
    if (("int" in ex) || ("string" in ex) || ("bytes" in ex)) {
        return true;
    }
    if (Array.isArray(ex)) {
        var mapElts = 0;
        try {
            for (var ex_2 = __values(ex), ex_2_1 = ex_2.next(); !ex_2_1.done; ex_2_1 = ex_2.next()) {
                var n = ex_2_1.value;
                if (isPrim(n) && n.prim === "Elt") {
                    /* istanbul ignore else */
                    if (assertArgs(n, 2)) {
                        assertMichelsonData(n.args[0]);
                        assertMichelsonData(n.args[1]);
                    }
                    mapElts++;
                }
                else {
                    assertMichelsonData(n);
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (ex_2_1 && !ex_2_1.done && (_a = ex_2.return)) _a.call(ex_2);
            }
            finally { if (e_2) throw e_2.error; }
        }
        if (mapElts !== 0 && mapElts !== ex.length) {
            throw new MichelsonValidationError(ex, "data entries and map elements can't be intermixed");
        }
        return true;
    }
    if (isPrim(ex)) {
        switch (ex.prim) {
            case "Unit":
            case "True":
            case "False":
            case "None":
                assertArgs(ex, 0);
                break;
            case "Pair":
                /* istanbul ignore else */
                if (ex.args === undefined || ex.args.length < 2) {
                    throw new MichelsonValidationError(ex, "at least 2 arguments expected");
                }
                try {
                    for (var _c = __values(ex.args), _d = _c.next(); !_d.done; _d = _c.next()) {
                        var a = _d.value;
                        assertMichelsonData(a);
                    }
                }
                catch (e_3_1) { e_3 = { error: e_3_1 }; }
                finally {
                    try {
                        if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
                    }
                    finally { if (e_3) throw e_3.error; }
                }
                break;
            case "Left":
            case "Right":
            case "Some":
                /* istanbul ignore else */
                if (assertArgs(ex, 1)) {
                    assertMichelsonData(ex.args[0]);
                }
                break;
            default:
                if (Object.prototype.hasOwnProperty.call(exports.instructionIDs, ex.prim)) {
                    assertMichelsonInstruction(ex);
                }
                else {
                    throw new MichelsonValidationError(ex, "data entry or instruction expected");
                }
        }
    }
    else {
        throw new MichelsonValidationError(ex, "data entry expected");
    }
    return true;
}
exports.assertMichelsonData = assertMichelsonData;
/**
 * Checks if the node is a valid Michelson smart contract source containing all required and valid properties such as `parameter`, `storage` and `code`.
 * This is a type guard function which either returns true of throws an exception.
 * @param ex An AST node
 */
function assertMichelsonContract(ex) {
    var e_4, _a;
    /* istanbul ignore else */
    if (assertSeq(ex)) {
        var ent = {};
        try {
            for (var ex_3 = __values(ex), ex_3_1 = ex_3.next(); !ex_3_1.done; ex_3_1 = ex_3.next()) {
                var sec = ex_3_1.value;
                if (assertPrim(sec)) {
                    if (sec.prim !== "code" && sec.prim !== "parameter" && sec.prim !== "storage") {
                        throw new MichelsonValidationError(ex, "unexpected contract section: " + sec.prim);
                    }
                    if (sec.prim in ent) {
                        throw new MichelsonValidationError(ex, "duplicate contract section: " + sec.prim);
                    }
                    ent[sec.prim] = true;
                    /* istanbul ignore else */
                    if (assertArgs(sec, 1)) {
                        switch (sec.prim) {
                            case "code":
                                /* istanbul ignore else */
                                if (assertSeq(sec.args[0])) {
                                    assertMichelsonInstruction(sec.args[0]);
                                }
                                break;
                            case "parameter":
                                assertMichelsonPassableType(sec.args[0]);
                                break;
                            case "storage":
                                assertMichelsonStorableType(sec.args[0]);
                        }
                    }
                }
            }
        }
        catch (e_4_1) { e_4 = { error: e_4_1 }; }
        finally {
            try {
                if (ex_3_1 && !ex_3_1.done && (_a = ex_3.return)) _a.call(ex_3);
            }
            finally { if (e_4) throw e_4.error; }
        }
    }
    return true;
}
exports.assertMichelsonContract = assertMichelsonContract;
/**
 * Checks if the node is a valid Michelson smart contract source containing all required and valid properties such as `parameter`, `storage` and `code`.
 * @param ex An AST node
 */
function isMichelsonScript(ex) {
    try {
        assertMichelsonContract(ex);
        return true;
    }
    catch (_a) {
        return false;
    }
}
exports.isMichelsonScript = isMichelsonScript;
/**
 * Checks if the node is a valid Michelson data literal such as `(Pair {Elt "0" 0} 0)`.
 * @param ex An AST node
 */
function isMichelsonData(ex) {
    try {
        assertMichelsonData(ex);
        return true;
    }
    catch (_a) {
        return false;
    }
}
exports.isMichelsonData = isMichelsonData;
/**
 * Checks if the node is a valid Michelson code (sequence of instructions).
 * @param ex An AST node
 */
function isMichelsonCode(ex) {
    try {
        assertMichelsonInstruction(ex);
        return true;
    }
    catch (_a) {
        return false;
    }
}
exports.isMichelsonCode = isMichelsonCode;
/**
 * Checks if the node is a valid Michelson type expression.
 * @param ex An AST node
 */
function isMichelsonType(ex) {
    try {
        assertMichelsonType(ex);
        return true;
    }
    catch (_a) {
        return false;
    }
}
exports.isMichelsonType = isMichelsonType;
function isInstruction(p) {
    return Object.prototype.hasOwnProperty.call(exports.instructionIDs, p.prim);
}
exports.isInstruction = isInstruction;
function assertDataListIfAny(d) {
    var e_5, _a;
    if (!Array.isArray(d)) {
        return false;
    }
    try {
        for (var d_1 = __values(d), d_1_1 = d_1.next(); !d_1_1.done; d_1_1 = d_1.next()) {
            var v = d_1_1.value;
            if ("prim" in v) {
                if (isInstruction(v)) {
                    throw new utils_1.MichelsonError(d, "Instruction outside of a lambda: " + JSON.stringify(d));
                }
                else if (v.prim === "Elt") {
                    throw new utils_1.MichelsonError(d, "Elt item outside of a map literal: " + JSON.stringify(d));
                }
            }
        }
    }
    catch (e_5_1) { e_5 = { error: e_5_1 }; }
    finally {
        try {
            if (d_1_1 && !d_1_1.done && (_a = d_1.return)) _a.call(d_1);
        }
        finally { if (e_5) throw e_5.error; }
    }
    return true;
}
exports.assertDataListIfAny = assertDataListIfAny;
//# sourceMappingURL=michelson-validator.js.map