/* Generated from Java with JSweet 2.3.7 - http://www.jsweet.org */
import { Aai20Document } from './asyncapi/v2/models/Aai20Document';
import { JsonCompat } from './compat/JsonCompat';
import { Constants } from './core/Constants';
import { DocumentFactory } from './core/factories/DocumentFactory';
import { VisitorFactory } from './core/factories/VisitorFactory';
import { DocumentType } from './core/models/DocumentType';
import { NodePathUtil } from './core/util/NodePathUtil';
import { ReferenceResolverChain } from './core/util/ReferenceResolverChain';
import { VisitorUtil } from './core/util/VisitorUtil';
import { DefaultSeverityRegistry } from './core/validation/DefaultSeverityRegistry';
import { TraverserDirection } from './core/visitors/TraverserDirection';
import { Oas20Document } from './openapi/v2/models/Oas20Document';
import { Oas30Document } from './openapi/v3/models/Oas30Document';
import { Dereferencer } from './openapi/visitors/dereference/Dereferencer';
import { Oas20to30TransformationVisitor } from './openapi/visitors/transform/Oas20to30TransformationVisitor';
/**
 * The most common entry points into using the data models library.  Provides convenience methods
 * for performing common actions such as i/o, visiting, and validation.
 * @author eric.wittmann@gmail.com
 * @author Jakub Senko <jsenko@redhat.com>
 * @class
 */
var Library = /** @class */ (function () {
    function Library() {
    }
    /**
     * Adds a reference resolver to the library.  The resolver will be used whenever the library
     * needs to resolve a $ref reference.
     * @param {*} resolver
     */
    Library.addReferenceResolver = function (resolver) {
        ReferenceResolverChain.getInstance().addResolver(resolver);
    };
    Library.removeReferenceResolver = function (resolver) {
        ReferenceResolverChain.getInstance().removeResolver(resolver);
    };
    /**
     * Creates a new, empty document of the given type.
     * @param {DocumentType} type
     * @return {Document}
     */
    Library.createDocument = function (type) {
        switch ((type)) {
            case DocumentType.asyncapi2:
                return new Aai20Document();
            case DocumentType.openapi2:
                return new Oas20Document();
            case DocumentType.openapi3:
                return new Oas30Document();
            default:
                throw Object.defineProperty(new Error("Unknown document type: " + type), '__classes', { configurable: true, value: ['java.lang.Throwable', 'java.lang.Object', 'java.lang.RuntimeException', 'java.lang.Exception'] });
        }
    };
    /**
     * Called to create a node path for a given data model node.
     * @param {Node} node
     * @return {NodePath}
     */
    Library.createNodePath = function (node) {
        return NodePathUtil.createNodePath(node);
    };
    /**
     * Convenience method for visiting a single data model nodel.
     * @param {Node} node
     * @param {*} visitor
     */
    Library.visitNode = function (node, visitor) {
        VisitorUtil.visitNode(node, visitor);
    };
    /**
     * Convenience method for visiting a data model tree.  Supports traversing the data model either
     * up or down the tree.
     * @param {Node} node
     * @param {*} visitor
     * @param {TraverserDirection} direction
     */
    Library.visitTree = function (node, visitor, direction) {
        VisitorUtil.visitTree(node, visitor, direction);
    };
    /**
     * Called to validate a data model node.  All validation rules will be evaluated and reported.  The list
     * of validation problems found during validation is returned.  In addition, validation problems will be
     * reported on the individual nodes themselves.  Validation problem severity is determined by checking
     * with the included severity registry.  If the severity registry is null, a default registry is used.
     * @param {Node} node
     * @param {*} severityRegistry
     * @return {ValidationProblem[]}
     */
    Library.validate = function (node, severityRegistry) {
        if (severityRegistry == null) {
            severityRegistry = new DefaultSeverityRegistry();
        }
        var resetter = VisitorFactory.createValidationProblemsResetVisitor(node.ownerDocument());
        Library.visitTree(node, resetter, TraverserDirection.down);
        var validator = VisitorFactory.createValidationVisitor(node.ownerDocument());
        validator.setSeverityRegistry(severityRegistry);
        Library.visitTree(node, validator, TraverserDirection.down);
        return validator.getValidationProblems();
    };
    /**
     * Reads an entire document from JSON data.  The JSON data (already parsed, not in string format) is
     * read as a data model {@link Document} and returned.
     * @param {*} json
     * @return {Document}
     */
    Library.readDocument = function (json) {
        var clonedJson = JsonCompat.clone(json);
        var type = Library.discoverDocumentType(clonedJson);
        var reader = VisitorFactory.createDataModelReader(type);
        var document = DocumentFactory.create(type);
        reader.readDocument(clonedJson, document);
        return document;
    };
    /**
     * Reads an entire document from a JSON formatted string.  This will parse the given string into
     * JSON data and then call Library.readDocument.
     * @param {string} jsonString
     * @return {Document}
     */
    Library.readDocumentFromJSONString = function (jsonString) {
        var json = JsonCompat.parseJSON(jsonString);
        return Library.readDocument(json);
    };
    /**
     * Call this to do a "partial read" on a given node.  You must pass the JSON data for the node
     * type and an empty instance of the property node class.  For example, you could read just an
     * Operation by passing the JSON data for the operation along with an instance of e.g.
     * {@link Oas30Operation} and this will read the data and store it in the instance.
     * @param {*} json
     * @param {Node} node
     * @return {Node}
     */
    Library.readNode = function (json, node) {
        var clonedJson = JsonCompat.clone(json);
        var type = node.ownerDocument().getDocumentType();
        var reader = VisitorFactory.createDataModelReader(type);
        var dispatcher = VisitorFactory.createDataModelReaderDispatcher(type, clonedJson, reader);
        Library.visitNode(node, dispatcher);
        return node;
    };
    /**
     * Called to serialize a given data model node to a JSON object.
     * @param {Node} node
     * @return {*}
     */
    Library.writeNode = function (node) {
        var writer = VisitorFactory.createDataModelWriter(node.ownerDocument());
        Library.visitTree(node, writer, TraverserDirection.down);
        return writer.getResult();
    };
    /**
     * Called to serialize a given data model to a JSON formatted string.
     * @param {Document} document
     * @return {string}
     */
    Library.writeDocumentToJSONString = function (document) {
        var json = Library.writeNode(document);
        return JsonCompat.stringify(json);
    };
    /**
     * Called to discover what type of document the given JSON data represents.  This method
     * interrogates the following appropriate top level properties:
     *
     * - asyncapi
     * - openapi
     * - swagger
     *
     * Based on which property is defined, and the value of that property, the correct document
     * type is determined and returned.
     *
     * @param {*} json
     * @return {DocumentType}
     */
    Library.discoverDocumentType = function (json) {
        var asyncapi = JsonCompat.getPropertyString(json, Constants.PROP_ASYNCAPI);
        var openapi = JsonCompat.getPropertyString(json, Constants.PROP_OPENAPI);
        var swagger = JsonCompat.getPropertyString(json, Constants.PROP_SWAGGER);
        if (asyncapi != null && /* startsWith */ (function (str, searchString, position) {
            if (position === void 0) { position = 0; }
            return str.substr(position, searchString.length) === searchString;
        })(asyncapi, "2.")) {
            return DocumentType.asyncapi2;
        }
        if (openapi != null) {
            if ( /* startsWith */(function (str, searchString, position) {
                if (position === void 0) { position = 0; }
                return str.substr(position, searchString.length) === searchString;
            })(openapi, "2.")) {
                return DocumentType.openapi2;
            }
            if ( /* startsWith */(function (str, searchString, position) {
                if (position === void 0) { position = 0; }
                return str.substr(position, searchString.length) === searchString;
            })(openapi, "3.0")) {
                return DocumentType.openapi3;
            }
        }
        if (swagger != null) {
            if ( /* startsWith */(function (str, searchString, position) {
                if (position === void 0) { position = 0; }
                return str.substr(position, searchString.length) === searchString;
            })(swagger, "2.")) {
                return DocumentType.openapi2;
            }
        }
        throw Object.defineProperty(new Error("Unknown data model type or version."), '__classes', { configurable: true, value: ['java.lang.Throwable', 'java.lang.Object', 'java.lang.RuntimeException', 'java.lang.Exception'] });
    };
    /**
     * Clones the given document by serializing it to a JS object, and then re-parsing it.
     * @param {Document} source
     * @return {Document}
     */
    Library.cloneDocument = function (source) {
        var jsObj = Library.writeNode(source);
        return Library.readDocument(jsObj);
    };
    /**
     * Transforms from an OpenAPI 2.0 document into a 3.0 document.
     * @param {Oas20Document} source
     * @return {Oas30Document}
     */
    Library.transformDocument = function (source) {
        var clone = Library.cloneDocument(source);
        var transformer = new Oas20to30TransformationVisitor();
        VisitorUtil.visitTree(clone, transformer, TraverserDirection.down);
        return transformer.getResult();
    };
    /**
     * Dereferences a document - this will take all external references ($ref) found in
     * the document and pull them into this document.  It will then update any external
     * reference to instead point to the local copy.  The result is a functionally
     * equivalent document with no external references.
     *
     * @param {Document} source
     * @return {Document}
     */
    Library.dereferenceDocument = function (source) {
        var rl = new Dereferencer(source);
        return rl.dereference();
    };
    return Library;
}());
export { Library };
Library["__class"] = "io.apicurio.datamodels.Library";
//# sourceMappingURL=Library.js.map