"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("./typesystem");
exports.tsInterfaces = require("./typesystem-interfaces");
var tc = require("./parse");
var fr = require("./facetRegistry");
var restrictions_1 = require("./restrictions");
var metainfo_1 = require("./metainfo");
var metainfo_2 = require("./metainfo");
var metainfo_3 = require("./metainfo");
var nm = require("./nominals");
exports.nominalTypes = require("./nominal-types");
exports.nominalInterfaces = require("./nominal-interfaces");
exports.typeExpressions = require("./typeExpressionUtil");
var schemaUtil = require("./schemaUtil");
exports.TOP_LEVEL_EXTRA = exports.tsInterfaces.TOP_LEVEL_EXTRA;
exports.DEFINED_IN_TYPES_EXTRA = exports.tsInterfaces.DEFINED_IN_TYPES_EXTRA;
exports.USER_DEFINED_EXTRA = exports.tsInterfaces.USER_DEFINED_EXTRA;
exports.SOURCE_EXTRA = exports.tsInterfaces.SOURCE_EXTRA;
// export function instanceOfHasExtra(instance : nominalTypes.ITypeDefinition) : instance is IHasExtra {
//     returninstance instanceof ts.AbstractType || instance instanceof nominalTypes.AbstractType;
// }
function getSchemaUtils() {
    return schemaUtil;
}
exports.getSchemaUtils = getSchemaUtils;
function isParsedType(object) {
    return object instanceof ts.AbstractType;
}
exports.isParsedType = isParsedType;
/**
 * loads type collection from JSON type definition
 * @param data
 * @param registry - optional registry of types which ar already known (does not modified during parse)
 * @returns {TypeCollection} returns a new instance of type collection with a parsed types
 */
function loadTypeCollection(data, registry) {
    if (registry === void 0) { registry = ts.builtInRegistry(); }
    return tc.parseJSONTypeCollection(data, registry);
}
exports.loadTypeCollection = loadTypeCollection;
/**
 * loads type  from JSON type definition
 * @param data
 * @returns {ts.AbstractType}
 */
function loadType(data) {
    return tc.parseJSON(null, data, ts.builtInRegistry());
}
exports.loadType = loadType;
/**
 * parses a type or type collection definition from a JSON structure
 * @param data
 * @returns {any}
 */
function parse(data) {
    if (data['types'] || data['annotationTypes']) {
        return tc.parseJSONTypeCollection(data);
    }
    else {
        return tc.parseJSON(null, data);
    }
}
exports.parse = parse;
/**
 * parses a type  from a JSON structure, uses second argument to resolve types
 * @param data
 * @returns {any}
 */
function parseType(data, collection) {
    return tc.parseJSON(null, data, collection ? collection.getTypeRegistry() : ts.builtInRegistry());
}
exports.parseType = parseType;
/**
 * kind of the node
 */
var NodeKind;
(function (NodeKind) {
    NodeKind[NodeKind["SCALAR"] = 0] = "SCALAR";
    NodeKind[NodeKind["ARRAY"] = 1] = "ARRAY";
    NodeKind[NodeKind["MAP"] = 2] = "MAP";
})(NodeKind = exports.NodeKind || (exports.NodeKind = {}));
/**
 * parses type collection definition from a JSON structure
 * @param data
 * @returns {any}
 */
function parseFromAST(data) {
    return tc.parseTypeCollection(data, ts.builtInRegistry());
}
exports.parseFromAST = parseFromAST;
/**
 * parses type collection definition from a JSON structure
 * @param data
 * @returns {any}
 */
function parseTypeFromAST(name, data, collection, defaultsToAny, annotation, global, ignoreTypeAttr) {
    if (defaultsToAny === void 0) { defaultsToAny = false; }
    if (annotation === void 0) { annotation = false; }
    if (global === void 0) { global = true; }
    if (ignoreTypeAttr === void 0) { ignoreTypeAttr = false; }
    if (global) {
        var t;
        if (annotation) {
            t = collection.getAnnotationType(name);
        }
        else {
            t = collection.getType(name);
        }
        if (t != null) {
            return t;
        }
    }
    return tc.parse(name, data, collection ? collection.getTypeRegistry() : ts.builtInRegistry(), defaultsToAny, annotation, global, ignoreTypeAttr);
}
exports.parseTypeFromAST = parseTypeFromAST;
/**
 * dumps type or type collection to JSON
 * @param ts
 * @returns {IType|ITypeCollection}
 */
function dump(ts) {
    return tc.storeAsJSON(ts);
}
exports.dump = dump;
/**
 * validates intance against the type definition
 * @param i - instance to validate
 * @param t - type definition
 * @returns {IStatus}
 */
function validate(i, t, autoClose) {
    if (autoClose === void 0) { autoClose = false; }
    ts.autoCloseFlag = autoClose;
    try {
        return t.validate(i, autoClose);
    }
    finally {
        ts.autoCloseFlag = false;
    }
}
exports.validate = validate;
/***
 * validates type definition
 * @param t
 * @param collection - collection of the types
 * @returns {IStatus}
 */
function validateTypeDefinition(t, collection) {
    return t.validateType(collection.getAnnotationTypeRegistry());
}
exports.validateTypeDefinition = validateTypeDefinition;
/**
 * performs automatic classification of instance against a given type
 * @param i
 * @param t
 * @returns {IParsedType}
 */
function performAC(i, t) {
    return t.ac(i);
}
exports.performAC = performAC;
/**
 * checks if the given type is suitable for automatic classification
 * @param t
 * @returns {Status}
 */
function checkACStatus(t) {
    return t.canDoAc();
}
exports.checkACStatus = checkACStatus;
/**
 * this function allow you to get a list of all built-in facets
 * @returns {FacetPrototype[]}
 */
function builtInFacets() {
    return fr.getInstance().allPrototypes();
}
exports.builtInFacets = builtInFacets;
/**
 * returns type registry returning all built in types
 * @returns {TypeRegistry}
 */
function builtInTypes() {
    return ts.builtInRegistry();
}
exports.builtInTypes = builtInTypes;
/**
 * creates a new type by deriving it from a list of super types
 * @returns {IParsedType}
 */
function derive(name) {
    var types = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        types[_i - 1] = arguments[_i];
    }
    return ts.derive(name, types);
}
exports.derive = derive;
/**
 * creates a new type by unifying it from a list of possible options
 * @returns {IParsedType}
 */
function unify(name) {
    var types = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        types[_i - 1] = arguments[_i];
    }
    return ts.union(name, types);
}
exports.unify = unify;
var TypeConstructor = /** @class */ (function () {
    function TypeConstructor(target) {
        this.target = target;
    }
    /**
     * adds property declaration to the type
     * @param name
     * @param type
     * @param optional
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.addProperty = function (name, type, optional) {
        this.target.declareProperty(name, type, optional);
        return this;
    };
    /**
     * closes type
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.closeType = function () {
        this.target.addMeta(new restrictions_1.KnownPropertyRestriction(false));
        return this;
    };
    /**
     * adds annotation to the type
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.annotate = function (name, value) {
        this.target.addMeta(new metainfo_1.Annotation(name, value, "(" + value + ")"));
        return this;
    };
    /**
     * adds custom facet to the type
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.customFacet = function (name, value) {
        this.target.addMeta(new metainfo_2.CustomFacet(name, value));
        return this;
    };
    /**
     * adds custom facet declaration to the type
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.customFacetDeclaration = function (name, value, optional) {
        if (optional === void 0) { optional = true; }
        this.target.addMeta(new metainfo_3.FacetDeclaration(name, value, optional));
        return this;
    };
    /**
     * adds a built-in facet with a given name and value
     * @param name
     * @param value
     * @returns {TypeConstructor}
     */
    TypeConstructor.prototype.addSimpleFacet = function (name, value) {
        this.target.addMeta(fr.getInstance().buildFacet(name, value));
        return this;
    };
    /**
     * returns a constructed type instance
     * @returns {IParsedType}
     */
    TypeConstructor.prototype.getResult = function () {
        return this.target;
    };
    return TypeConstructor;
}());
exports.TypeConstructor = TypeConstructor;
function setPropertyConstructor(c) {
    nm.setPropertyConstructor(c);
}
exports.setPropertyConstructor = setPropertyConstructor;
function toNominal(t, bt) {
    return nm.toNominal(t, bt);
}
exports.toNominal = toNominal;
function toValidationPath(p) {
    return ts.toValidationPath(p);
}
exports.toValidationPath = toValidationPath;
//# sourceMappingURL=index.js.map