"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 (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var defs = require("raml-definition-system");
var hl = require("./highLevelAST");
var ll = require("./lowLevelAST");
var _ = require("underscore");
var proxy = require("./ast.core/LowLevelASTProxy");
var def = defs;
var builder = require("./ast.core/builder");
var search = require("../search/search-interface");
var mutators = require("./ast.core/mutators");
var linter = require("./ast.core/linter");
var expander = require("./ast.core/expanderLL");
var typeBuilder = require("./ast.core/typeBuilder");
var universes = require("./tools/universe");
var jsyaml = require("./jsyaml/jsyaml2lowLevel");
var textutil = require("../util/textutil");
var services = def;
var yaml = require("yaml-ast-parser");
var wrapperHelper = require("./wrapped-ast/wrapperHelper");
var jsonSerializerHL = require("../util/jsonSerializerHL");
var factory10 = require("./artifacts/raml10factory");
var factory08 = require("./artifacts/raml08factory");
var universeHelpers = require("./tools/universeHelpers");
var resourceRegistry = require("./jsyaml/resourceRegistry");
var rTypes = defs.rt;
var path = require("path");
var jsonPath = require("json-path");
var contentprovider = require("../util/contentprovider");
var utils = require("../utils");
var messageRegistry = require("../../resources/errorMessages");
function qName(x, context) {
    //var dr=search.declRoot(context);
    var nm = x.name();
    if (proxy.LowLevelProxyNode.isInstance(context.lowLevel())) {
        if (proxy.LowLevelProxyNode.isInstance(x.lowLevel())) {
            return nm;
        }
        var rootUnit = context.root().lowLevel().unit();
        var resolver = rootUnit.project().namespaceResolver();
        var unit = x.lowLevel().unit();
        var usesInfo = resolver.resolveNamespace(context.lowLevel().unit(), unit);
        if (usesInfo != null) {
            var ns = usesInfo.namespace();
            if (ns != null) {
                return ns + "." + nm;
            }
        }
    }
    if (x.lowLevel().unit() != context.lowLevel().unit()) {
        var root = context;
        while (true) {
            if (root.lowLevel().includePath() || root.parent() == null) {
                if (!root.unitMap) {
                    root.unitMap = {};
                    root.asElement().elements().forEach(function (x) {
                        if (x.definition().key() == universes.Universe10.UsesDeclaration) {
                            var mm = x.attr("value");
                            if (mm) {
                                var u = belongsToFragment(x) ? x.lowLevel().unit() : x.root().lowLevel().unit();
                                var unit = u.resolve(mm.value());
                                if (unit != null) {
                                    var key = x.attr("key");
                                    if (key) {
                                        root.unitMap[unit.absolutePath()] = key.value();
                                    }
                                }
                            }
                        }
                    });
                }
                var prefix = root.unitMap[x.lowLevel().unit().absolutePath()];
                if (prefix) {
                    return prefix + "." + nm;
                }
            }
            if (!root.parent()) {
                break;
            }
            else {
                root = root.parent();
            }
        }
    }
    return nm;
}
exports.qName = qName;
var BasicASTNode = /** @class */ (function () {
    function BasicASTNode(_node, _parent) {
        this._node = _node;
        this._parent = _parent;
        this._implicit = false;
        this.values = {};
        if (_node) {
            _node.setHighLevelParseResult(this);
        }
    }
    BasicASTNode.isInstance = function (instance) {
        return instance != null && instance.getClassIdentifier
            && typeof (instance.getClassIdentifier) == "function"
            && _.contains(instance.getClassIdentifier(), BasicASTNode.CLASS_IDENTIFIER);
    };
    BasicASTNode.prototype.getClassIdentifier = function () {
        var superIdentifiers = [];
        return superIdentifiers.concat(BasicASTNode.CLASS_IDENTIFIER);
    };
    BasicASTNode.prototype.getKind = function () {
        return hl.NodeKind.BASIC;
    };
    BasicASTNode.prototype.asAttr = function () {
        return null;
    };
    BasicASTNode.prototype.asElement = function () {
        return null;
    };
    BasicASTNode.prototype.hashkey = function () {
        if (!this._hashkey)
            this._hashkey = this.parent() ? this.parent().hashkey() + "/" + this.name() : this.name();
        return this._hashkey;
    };
    BasicASTNode.prototype.root = function () {
        if (this.parent()) {
            return this.parent().root();
        }
        return this;
    };
    BasicASTNode.prototype.version = function () {
        return "";
    };
    BasicASTNode.prototype.getLowLevelStart = function () {
        if (this.lowLevel().kind() === jsyaml.Kind.SCALAR) {
            return this.lowLevel().start();
        }
        return this.lowLevel().keyStart();
    };
    BasicASTNode.prototype.getLowLevelEnd = function () {
        if (this.lowLevel().kind() === jsyaml.Kind.SCALAR) {
            return this.lowLevel().end();
        }
        return this.lowLevel().keyEnd();
    };
    BasicASTNode.prototype.isSameNode = function (n) {
        if (n) {
            if (n.lowLevel().actual() == this.lowLevel().actual()) {
                return true;
            }
        }
        return false;
    };
    BasicASTNode.prototype.checkContextValue = function (name, value, thisObj) {
        var vl = this.computedValue(name);
        if (vl && vl.indexOf(value) != -1) {
            return true; //FIXME
        }
        return value == vl || value == 'false';
    };
    BasicASTNode.prototype.printDetails = function (indent) {
        return (indent ? indent : "") + "Unkown\n";
    };
    /**
     * Used for test comparison of two trees. Touching this will require AST tests update.
     * @param indent
     * @returns {string}
     */
    BasicASTNode.prototype.testSerialize = function (indent) {
        return (indent ? indent : "") + "Unkown\n";
    };
    BasicASTNode.prototype.errors = function () {
        var errors = [];
        var q = createBasicValidationAcceptor(errors, this);
        this.validate(q);
        return errors;
    };
    BasicASTNode.prototype.markCh = function () {
        var n = this.lowLevel();
        while (proxy.LowLevelProxyNode.isInstance(n)) {
            n = n.originalNode();
        }
        n = n._node ? n._node : n;
        if (n['markCh']) {
            return true;
        }
        n['markCh'] = 1;
    };
    BasicASTNode.prototype.unmarkCh = function () {
        var n = this.lowLevel();
        while (proxy.LowLevelProxyNode.isInstance(n)) {
            n = n.originalNode();
        }
        n = n._node ? n._node : n;
        delete n['markCh'];
    };
    BasicASTNode.prototype.validate = function (v) {
        linter.validate(this, v);
        for (var _i = 0, _a = applyNodeValidationPlugins(this); _i < _a.length; _i++) {
            var pluginIssue = _a[_i];
            v.accept(pluginIssue);
        }
        for (var _b = 0, _c = applyNodeAnnotationValidationPlugins(this); _b < _c.length; _b++) {
            var pluginIssue = _c[_b];
            v.accept(pluginIssue);
        }
    };
    BasicASTNode.prototype.allowRecursive = function () {
        return false;
    };
    BasicASTNode.prototype.setComputed = function (name, v) {
        this.values[name] = v;
    };
    BasicASTNode.prototype.setValueSource = function (n) {
        this._valueSource = n;
    };
    BasicASTNode.prototype.computedValue = function (name) {
        var vl = this.values[name];
        if (!vl) {
            if (this.parent()) {
                return this.parent().computedValue(name);
            }
            else if (this._valueSource) {
                return this._valueSource.computedValue(name);
            }
            else if (this.isElement()) {
                var master = this.asElement().getMaster();
                if (master) {
                    return master.computedValue(name);
                }
            }
        }
        return vl;
    };
    BasicASTNode.prototype.lowLevel = function () {
        return this._node;
    };
    BasicASTNode.prototype.name = function () {
        var c = this.lowLevel().key();
        if (!c) {
            return "";
        }
        return c;
    };
    BasicASTNode.prototype.optional = function () {
        var llNode = this.lowLevel();
        var ownValue = llNode.optional();
        if (llNode.key() != null) {
            return ownValue;
        }
        var p = this.property();
        if (!p || !p.isMultiValue()) {
            return ownValue;
        }
        var llParent = llNode.parent();
        while (llParent && llParent.highLevelNode() == null) {
            if (llParent.kind() == yaml.Kind.MAPPING) {
                return llParent.optional();
            }
            llParent = llParent.parent();
        }
        return ownValue;
    };
    BasicASTNode.prototype.parent = function () {
        return this._parent;
    };
    BasicASTNode.prototype.setParent = function (parent) {
        this._parent = parent;
    };
    BasicASTNode.prototype.isElement = function () {
        return false;
    };
    BasicASTNode.prototype.directChildren = function () {
        return this.children();
    };
    BasicASTNode.prototype.children = function () {
        return [];
    };
    BasicASTNode.prototype.isAttached = function () {
        return this.parent() != null;
    };
    BasicASTNode.prototype.isImplicit = function () {
        return this._implicit;
    };
    BasicASTNode.prototype.isAttr = function () {
        return false;
    };
    BasicASTNode.prototype.isUnknown = function () {
        return true;
    };
    BasicASTNode.prototype.id = function () {
        var _this = this;
        if (this.cachedId) {
            return this.cachedId;
        }
        if (this._parent) {
            var parentId = this.parent().id();
            parentId += "." + this.name();
            var sameName = this.parent().directChildren().filter(function (x) { return x.name() == _this.name(); });
            if (sameName.length > 1) {
                var ind = sameName.indexOf(this);
                parentId += "[" + ind + "]";
            }
            this.cachedId = parentId;
            return parentId;
        }
        this.cachedId = "";
        return this.cachedId;
    };
    BasicASTNode.prototype.localId = function () {
        return this.name();
    };
    BasicASTNode.prototype.resetIDs = function () {
        this.cachedId = null;
        this.cachedFullId = null;
    };
    BasicASTNode.prototype.fullLocalId = function () {
        var _this = this;
        if (this.cachedFullId) {
            return this.cachedFullId;
        }
        if (this._parent) {
            var result = ".";
            if (this.property() != null && universeHelpers.isAnnotationsProperty(this.property())) {
                result += this.lowLevel().key();
            }
            else {
                result += this.name();
            }
            var sameName = this.parent().directChildren().filter(function (x) { return x.name() == _this.name(); });
            if (sameName.length > 1) {
                var ind = sameName.indexOf(this);
                result += "[" + ind + "]";
            }
            this.cachedFullId = result;
            return result;
        }
        this.cachedFullId = this.localId();
        return this.cachedFullId;
    };
    BasicASTNode.prototype.property = function () {
        return null;
    };
    BasicASTNode.prototype.reuseMode = function () {
        return this._reuseMode;
    };
    BasicASTNode.prototype.setReuseMode = function (val) {
        this._reuseMode = val;
    };
    BasicASTNode.prototype.isReused = function () {
        return this._isReused;
    };
    BasicASTNode.prototype.setReused = function (val) {
        this._isReused = val;
        this.children().forEach(function (x) { return x.setReused(val); });
    };
    BasicASTNode.prototype.setJSON = function (val) {
        this._jsonCache = val;
    };
    BasicASTNode.prototype.getJSON = function () {
        return this._jsonCache;
    };
    BasicASTNode.CLASS_IDENTIFIER = "highLevelImpl.BasicASTNode";
    return BasicASTNode;
}());
exports.BasicASTNode = BasicASTNode;
var StructuredValue = /** @class */ (function () {
    function StructuredValue(node, _parent, _pr, kv) {
        if (kv === void 0) { kv = null; }
        this.node = node;
        this._parent = _parent;
        this.kv = kv;
        this._pr = _pr;
    }
    StructuredValue.isInstance = function (instance) {
        return instance != null && instance.getClassIdentifier
            && typeof (instance.getClassIdentifier) == "function"
            && _.contains(instance.getClassIdentifier(), StructuredValue.CLASS_IDENTIFIER);
    };
    StructuredValue.prototype.getClassIdentifier = function () {
        var superIdentifiers = [];
        return superIdentifiers.concat(StructuredValue.CLASS_IDENTIFIER);
    };
    StructuredValue.prototype.valueName = function () {
        var res = null;
        if (this.kv) {
            res = this.kv;
        }
        res = this.node.key();
        if (this._pr && this._pr.isAnnotation()) {
            if (res && res.charAt(0) == '(') {
                res = res.substring(1, res.length - 1);
            }
        }
        return res;
    };
    StructuredValue.prototype.children = function () {
        return this.node.children().map(function (x) { return new StructuredValue(x, null, null); });
    };
    StructuredValue.prototype.lowLevel = function () {
        return this.node;
    };
    StructuredValue.prototype.toHighLevel = function (parent) {
        if (!parent && this._parent)
            parent = this._parent;
        if (this._hl) {
            return this._hl;
        }
        var vn = this.valueName();
        var p = parent;
        if (proxy.LowLevelProxyNode.isInstance(this.node)) {
            var uSeq = this.node.definingUnitSequence();
            var p1 = uSeq && uSeq[0] && uSeq[0].highLevel().asElement();
            var path1 = p1 && p1.lowLevel().unit().absolutePath();
            if (path1 == parent.lowLevel().unit().absolutePath()) {
                p1 = parent;
            }
            else if (path1 == parent.root().lowLevel().unit().absolutePath()) {
                p1 = parent.root();
            }
            p = p1 || p;
        }
        var cands = search.referenceTargets(this._pr, p).filter(function (x) { return qName(x, p) == vn; });
        if (cands && cands[0]) {
            var tp = cands[0].localType();
            var node = new ASTNodeImpl(this.node, parent, tp, this._pr);
            if (this._pr) {
                this._pr.childRestrictions().forEach(function (y) {
                    node.setComputed(y.name, y.value);
                });
            }
            this._hl = node;
            return node;
        }
        //if (this._pr.range()){
        //    var node=new ASTNodeImpl(parent.lowLevel(),parent,this._pr.range(),this._pr);
        //    if (this._pr){
        //        this._pr.childRestrictions().forEach(y=>{
        //            node.setComputed(y.name,y.value)
        //        })
        //    }
        //    return node;
        //}
        return null;
    };
    StructuredValue.prototype.toHighLevel2 = function (parent) {
        if (!parent && this._parent)
            parent = this._parent;
        var vn = this.valueName();
        var cands = search.referenceTargets(this._pr, parent).filter(function (x) { return qName(x, parent) == vn; });
        if (cands && cands[0]) {
            var tp = cands[0].localType();
            var node = new ASTNodeImpl(this.node, parent, tp, this._pr);
            if (this._pr) {
                this._pr.childRestrictions().forEach(function (y) {
                    node.setComputed(y.name, y.value);
                });
            }
            return node;
        }
        if (this._pr.range()) {
            var node = new ASTNodeImpl(this.node.parent(), parent, this._pr.range(), this._pr);
            if (this._pr) {
                this._pr.childRestrictions().forEach(function (y) {
                    node.setComputed(y.name, y.value);
                });
            }
            return node;
        }
        return null;
    };
    StructuredValue.prototype.resetHighLevelNode = function () {
        this._hl = null;
    };
    StructuredValue.CLASS_IDENTIFIER = "highLevelImpl.StructuredValue";
    return StructuredValue;
}());
exports.StructuredValue = StructuredValue;
/**
 * Instanceof for StructuredValue class
 * @param node
 * @returns
 */
function isStructuredValue(node) {
    var anyNode = node;
    return anyNode && anyNode.valueName && anyNode.toHighLevel && anyNode.toHighLevel2;
}
exports.isStructuredValue = isStructuredValue;
var ASTPropImpl = /** @class */ (function (_super) {
    __extends(ASTPropImpl, _super);
    function ASTPropImpl(node, parent, _def, _prop, fromKey) {
        if (fromKey === void 0) { fromKey = false; }
        var _this = _super.call(this, node, parent) || this;
        _this._def = _def;
        _this._prop = _prop;
        _this.fromKey = fromKey;
        return _this;
    }
    ASTPropImpl.isInstance = function (instance) {
        return instance != null && instance.getClassIdentifier
            && typeof (instance.getClassIdentifier) == "function"
            && _.contains(instance.getClassIdentifier(), ASTPropImpl.CLASS_IDENTIFIER_ASTPropImpl);
    };
    ASTPropImpl.prototype.getClassIdentifier = function () {
        var superIdentifiers = _super.prototype.getClassIdentifier.call(this);
        return superIdentifiers.concat(ASTPropImpl.CLASS_IDENTIFIER_ASTPropImpl);
    };
    ASTPropImpl.prototype.definition = function () {
        return this._def;
    };
    ASTPropImpl.prototype.asAttr = function () {
        return this;
    };
    ASTPropImpl.prototype.errors = function () {
        var errors = [];
        var q = createBasicValidationAcceptor(errors, this);
        this.parent().validate(q);
        return errors;
    };
    ASTPropImpl.prototype.isString = function () {
        if (this._def) {
            if (this._def.key() === universes.Universe08.StringType || this._def.key() == universes.Universe10.StringType) {
                return true;
            }
        }
        return false;
    };
    ASTPropImpl.prototype.isAnnotatedScalar = function () {
        if (!this.property().isAnnotation() && !this.property().isKey()) {
            return this.lowLevel().isAnnotatedScalar();
        }
        return false;
    };
    ASTPropImpl.prototype.annotations = function () {
        var ch = this.lowLevel().children();
        var annotations = [];
        var u = this.definition().universe().type(universes.Universe10.Annotable.name);
        if (!u) {
            return annotations;
        }
        var pr = u.property("annotations");
        for (var i = 0; i < ch.length; i++) {
            var child = ch[i];
            var key = child.key();
            if (key != null && key[0] == ("(") && key[key.length - 1] == (")")) {
                var attr = new ASTPropImpl(child, this.parent(), pr.range(), pr);
                annotations.push(attr);
            }
        }
        return annotations;
    };
    ASTPropImpl.prototype.getKind = function () {
        return hl.NodeKind.ATTRIBUTE;
    };
    ASTPropImpl.prototype.owningWrapper = function () {
        return {
            node: this.parent().wrapperNode(),
            property: this.name()
        };
    };
    ASTPropImpl.prototype.patchType = function (t) {
        this._def = t;
    };
    ASTPropImpl.prototype.findReferenceDeclaration = function () {
        var _this = this;
        var targets = search.referenceTargets(this.property(), this.parent());
        var vl = this.value();
        if (StructuredValue.isInstance(vl)) {
            var st = vl;
            var nm = st.valueName();
        }
        else {
            var nm = "" + vl;
        }
        var t = _.find(targets, function (x) { return qName(x, _this.parent()) == nm; });
        return t;
    };
    ASTPropImpl.prototype.findReferencedValue = function () {
        var c = this.findReferenceDeclaration();
        if (c) {
            var vl = c.attr("value");
            var ck = c.definition().key();
            if (ck === universes.Universe08.GlobalSchema) {
                if (vl) {
                    var actualValue = vl.value();
                    if (actualValue) {
                        var rf = linter.isValid(this._def, this.parent(), actualValue, vl.property(), vl);
                        return rf;
                    }
                }
                return null;
            }
        }
        return c;
    };
    ASTPropImpl.prototype.isElement = function () {
        return false;
    };
    ASTPropImpl.prototype.property = function () {
        return this._prop;
    };
    ASTPropImpl.prototype.convertMultivalueToString = function (value) {
        //|\n  xxx\n  yyy\n  zzz
        var gap = 0;
        var pos = 2;
        while (value[pos] == ' ') {
            gap++;
            pos++;
        }
        //console.log('gap: ' + gap);
        var lines = textutil.splitOnLines(value);
        lines = lines.map(function (line) {
            //console.log('line: ' + line);
            return line.substring(gap, line.length);
        });
        return lines.join('');
    };
    ASTPropImpl.prototype.overrideValue = function (value) {
        this._value = value;
    };
    ASTPropImpl.prototype.value = function () {
        if (this._value != null) {
            return this._value;
        }
        this._value = this.calcValue();
        return this._value;
    };
    ASTPropImpl.prototype.plainValue = function () {
        var _this = this;
        var val = this.value();
        if (StructuredValue.isInstance(val)) {
            var sVal = val;
            var llNode = sVal.lowLevel();
            val = llNode ? llNode.dumpToObject() : null;
            var prop = this.property();
            var rangeType = prop.range();
            var isTypeProp = universeHelpers.isTypeProperty(prop)
                || universeHelpers.isSchemaProperty(prop)
                || universeHelpers.isItemsProperty(prop);
            if (rangeType.isAssignableFrom("Reference")) {
                var key = Object.keys(val)[0];
                var name_1 = sVal.valueName();
                var refVal = val[key];
                if (refVal === undefined) {
                    refVal = null;
                }
                val = {
                    name: name_1,
                    value: refVal
                };
            }
            else if (isTypeProp) {
                var llNode_1 = this.lowLevel();
                var tdl = null;
                var td = def.getUniverse("RAML10").type(universes.Universe10.TypeDeclaration.name);
                var hasType = def.getUniverse("RAML10").type(universes.Universe10.LibraryBase.name);
                var tNode = new ASTNodeImpl(llNode_1, this.parent(), td, prop);
                tNode.patchType(builder.doDescrimination(tNode));
                tNode.patchProp(this.property());
                val = tNode;
            }
            else if (universeHelpers.isItemsProperty(prop) && typeof val === "object") {
                var isArr = Array.isArray(val);
                var isObj = !isArr;
                if (isArr) {
                    isObj = _.find(val, function (x) { return typeof (x) == "object"; }) != null;
                }
                if (isObj) {
                    val = null;
                    var a = this.parent().lowLevel();
                    var tdl = null;
                    a.children().forEach(function (x) {
                        if (x.key() == "items") {
                            var td = def.getUniverse("RAML10").type(universes.Universe10.TypeDeclaration.name);
                            var hasType = def.getUniverse("RAML10").type(universes.Universe10.LibraryBase.name);
                            var tNode = new ASTNodeImpl(x, _this.parent(), td, hasType.property(universes.Universe10.LibraryBase.properties.types.name));
                            tNode.patchType(builder.doDescrimination(tNode));
                            val = tNode;
                        }
                    });
                }
            }
        }
        return val;
    };
    ASTPropImpl.prototype.calcValue = function () {
        if (this._computed) {
            return this.computedValue(this.property().nameId());
        }
        if (this.fromKey) {
            var parent = this.parent();
            var definition = parent.definition();
            if (definition.universe().version() == "RAML08") {
                return this._node.key();
            }
            if (universeHelpers.isNameProperty(this.property())) {
                if (definition.isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
                    var requiredAttr = parent.attr("required");
                    if (requiredAttr && requiredAttr.value() != null) {
                        return this._node.optional() ? this._node.key() + "?" : this._node.key();
                    }
                }
            }
            return this._node.key();
        }
        if (this.property().isAnnotation() && this._node.key() && this._node.key() != 'annotations') {
            return new StructuredValue(this._node, this.parent(), this._prop);
        }
        var isString = valueMustBeString(this);
        var actualValue = this._node.value(isString); //TODO FIXME
        if (this.property().isSelfNode()) {
            if (!actualValue || jsyaml.ASTNode.isInstance(actualValue)) {
                actualValue = this._node;
                if (actualValue.children().length == 0) {
                    actualValue = null;
                }
            }
        }
        if (jsyaml.ASTNode.isInstance(actualValue) || proxy.LowLevelProxyNode.isInstance(actualValue)) {
            var isAnnotatedScalar = false;
            if (!this.property().range().hasStructure()) {
                if (this._node.isAnnotatedScalar()) {
                    this._node.children().forEach(function (x) {
                        if (x.key() === "value") {
                            actualValue = x.value(isString);
                            isAnnotatedScalar = true;
                        }
                    });
                }
            }
            if (!isAnnotatedScalar) {
                if (this._sval) {
                    return this._sval;
                }
                this._sval = new StructuredValue(actualValue, this.parent(), this._prop);
                return this._sval;
            }
        }
        if (typeof (actualValue) == 'string' && textutil.isMultiLineValue(actualValue)) {
            var res = this.convertMultivalueToString(actualValue);
            //console.log('converted: [' + textutil.replaceNewlines(res) + ']');
            return res;
        }
        if (actualValue == null && this._node.children().length > 0
            && this.property() && (universeHelpers.isTypeOrSchemaProperty(this.property()) || universeHelpers.isItemsProperty(this.property()))
            && this.parent() && universeHelpers.isTypeDeclarationDescendant(this.parent().definition())) {
            return new StructuredValue(this._node, this.parent(), this._prop);
        }
        if (this.property() && (universeHelpers.isTypeOrSchemaProperty(this.property()) || universeHelpers.isItemsProperty(this.property()))
            && this.parent() && universeHelpers.isTypeDeclarationDescendant(this.parent().definition())) {
            if (typeof (actualValue) === "string" && this.lowLevel().valueKind() == yaml.Kind.INCLUDE_REF) {
                var resolvedSchema = resolveSchemaFragment(this, actualValue);
                if (resolvedSchema) {
                    actualValue = resolvedSchema;
                }
            }
        }
        return actualValue;
    };
    ASTPropImpl.prototype.name = function () {
        return this._prop.nameId();
    };
    ASTPropImpl.prototype.printDetails = function (indent) {
        var className = this.definition().nameId();
        var definitionClassName = this.property().range().nameId();
        var result = (indent ? indent : "") +
            (this.name() + " : " + className
                + "[" + definitionClassName + "]"
                + "  =  " + this.value()) + (this.property().isKey() && this.optional() ? "?" : "")
            + "\n";
        if (StructuredValue.isInstance(this.value())) {
            var structuredHighLevel = this.value().toHighLevel();
            if (structuredHighLevel && structuredHighLevel.printDetails) {
                result += structuredHighLevel.printDetails(indent + "\t");
            }
        }
        return result;
    };
    /**
     * Used for test comparison of two trees. Touching this will require AST tests update.
     * @param indent
     * @returns {string}
     */
    ASTPropImpl.prototype.testSerialize = function (indent) {
        var className = this.definition().nameId();
        var result = (indent ? indent : "") +
            (this.name() + " : " + className
                + "  =  " + this.value()) +
            "\n";
        if (StructuredValue.isInstance(this.value())) {
            var structuredHighLevel = this.value().toHighLevel();
            if (structuredHighLevel && structuredHighLevel.testSerialize) {
                result += structuredHighLevel.testSerialize((indent ? indent : "") + "  ");
            }
            else {
                var lowLevel = this.value().lowLevel();
                var dumpObject = lowLevel.dumpToObject();
                var dump = JSON.stringify(dumpObject);
                var indentedDump = "";
                var dumpLines = dump.split("\n");
                dumpLines.forEach(function (dumpLine) { return indentedDump += ((indent ? indent : "") + "  " + dumpLine + "\n"); });
                result += indentedDump + "\n";
            }
        }
        return result;
    };
    ASTPropImpl.prototype.isAttr = function () {
        return true;
    };
    ASTPropImpl.prototype.isUnknown = function () {
        return false;
    };
    ASTPropImpl.prototype.setValue = function (value) {
        mutators.setValue(this, value);
        this._value = null;
    };
    ASTPropImpl.prototype.setKey = function (value) {
        mutators.setKey(this, value);
        this._value = null;
    };
    ASTPropImpl.prototype.children = function () {
        return [];
    };
    ASTPropImpl.prototype.addStringValue = function (value) {
        mutators.addStringValue(this, value);
        this._value = null;
    };
    ASTPropImpl.prototype.addStructuredValue = function (sv) {
        mutators.addStructuredValue(this, sv);
        this._value = null;
    };
    ASTPropImpl.prototype.addValue = function (value) {
        if (!this.property().isMultiValue())
            throw new Error(messageRegistry.SETVALUE_ONLY_MULTI_VALUES_PROPERTIES.message);
        if (typeof value == 'string') {
            this.addStringValue(value);
        }
        else {
            this.addStructuredValue(value);
        }
        this._value = null;
    };
    ASTPropImpl.prototype.isEmbedded = function () {
        var keyname = this.lowLevel().asMapping().key.value;
        //console.log('propery: ' + this.property().name());
        //console.log('mapping: ' + keyname);
        return this.property().canBeValue() && keyname != this.property().nameId();
    };
    ASTPropImpl.prototype.remove = function () {
        mutators.removeAttr(this);
    };
    ASTPropImpl.prototype.setValues = function (values) {
        mutators.setValues(this, values);
        this._value = null;
    };
    ASTPropImpl.prototype.isEmpty = function () {
        if (!this.property().isMultiValue())
            throw new Error(messageRegistry.ISEMPTY_ONLY_MULTI_VALUES_ATTRIBUTES.message);
        //console.log('remove: ' + this.name());
        var node = this.parent();
        var llnode = node.lowLevel();
        //node.lowLevel().show('Parent:');
        var attrs = node.attributes(this.name());
        //console.log('attributes: ' + attrs.length);
        if (attrs.length == 0) {
            return true;
        }
        else if (attrs.length == 1) {
            var anode = attrs[0].lowLevel();
            //console.log('attribute : ' + anode.kindName());
            //anode.show("ATTR:");
            if (anode.isMapping() && anode.value() == null) {
                // that's crazy but it means zero length array indeed )
                return true;
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    };
    ASTPropImpl.prototype.isFromKey = function () {
        return this.fromKey;
    };
    ASTPropImpl.CLASS_IDENTIFIER_ASTPropImpl = "highLevelImpl.ASTPropImpl";
    return ASTPropImpl;
}(BasicASTNode));
exports.ASTPropImpl = ASTPropImpl;
function valueMustBeString(attr) {
    var prop = attr.property();
    if (!prop) {
        return false;
    }
    var parent = attr.parent();
    var parentDef = parent && parent.definition();
    if (!parentDef) {
        return false;
    }
    if (parentDef.universe().version() == "RAML08") {
        if (universeHelpers.isStringTypeDeclarationDescendant(parentDef)) {
            if (universeHelpers.isExampleProperty(prop)
                || universeHelpers.isDefaultValue(prop)
                || universeHelpers.isEnumProperty(prop)) {
                return true;
            }
        }
    }
    else {
        if (universeHelpers.isTypeOrSchemaProperty(prop)
            && universeHelpers.isTypeDeclarationDescendant(parentDef)) {
            return false;
        }
    }
    if (!universeHelpers.isStringTypeType(prop.range())) {
        return false;
    }
    return true;
}
;
/**
 * Instanceof for ASTPropImpl class
 * @param node
 * @returns
 */
function isASTPropImpl(node) {
    var anyNode = node;
    return anyNode && anyNode.isString && anyNode.isFromKey && anyNode.isEmbedded;
}
exports.isASTPropImpl = isASTPropImpl;
var nodeBuilder = new builder.BasicNodeBuilder();
var OverlayMergeMode;
(function (OverlayMergeMode) {
    OverlayMergeMode[OverlayMergeMode["MERGE"] = 0] = "MERGE";
    OverlayMergeMode[OverlayMergeMode["AGGREGATE"] = 1] = "AGGREGATE";
})(OverlayMergeMode = exports.OverlayMergeMode || (exports.OverlayMergeMode = {}));
var LowLevelWrapperForTypeSystem = /** @class */ (function (_super) {
    __extends(LowLevelWrapperForTypeSystem, _super);
    function LowLevelWrapperForTypeSystem(_node, _highLevelRoot) {
        var _this = _super.call(this) || this;
        _this._node = _node;
        _this._highLevelRoot = _highLevelRoot;
        var v = _highLevelRoot.root();
        var mst = v.getMaster();
        if (mst && _this._node === _highLevelRoot.lowLevel()) {
            var master = _highLevelRoot.getMasterCounterPart();
            if (master) {
                _this._toMerge = new LowLevelWrapperForTypeSystem(master.lowLevel(), master);
            }
        }
        return _this;
    }
    LowLevelWrapperForTypeSystem.isInstance = function (instance) {
        return instance != null && instance.getClassIdentifier
            && typeof (instance.getClassIdentifier) == "function"
            && _.contains(instance.getClassIdentifier(), LowLevelWrapperForTypeSystem.CLASS_IDENTIFIER_LowLevelWrapperForTypeSystem);
    };
    LowLevelWrapperForTypeSystem.prototype.getClassIdentifier = function () {
        var superIdentifiers = _super.prototype.getClassIdentifier.call(this);
        return superIdentifiers.concat(LowLevelWrapperForTypeSystem.CLASS_IDENTIFIER_LowLevelWrapperForTypeSystem);
    };
    LowLevelWrapperForTypeSystem.prototype.contentProvider = function () {
        var root = this._node && this._node.includeBaseUnit() && ((this._node.includePath && this._node.includePath()) ? this._node.includeBaseUnit().resolve(this._node.includePath()) : this._node.includeBaseUnit());
        return new contentprovider.ContentProvider(root);
    };
    LowLevelWrapperForTypeSystem.prototype.path = function () {
        return this._node.unit() && this._node.unit().absolutePath();
    };
    LowLevelWrapperForTypeSystem.prototype.key = function () {
        var vl = this._node.key();
        if (this._node.optional()) {
            vl = vl + "?";
        }
        return vl;
    };
    LowLevelWrapperForTypeSystem.prototype.value = function () {
        var vk = this._node.resolvedValueKind();
        if (vk === yaml.Kind.SEQ) {
            return this.children().map(function (x) { return x.value(); });
        }
        else if (vk === yaml.Kind.MAP) {
            var vl = this._node.dumpToObject(false);
            return vl[this.key()];
        }
        else if (this._node.kind() == yaml.Kind.MAP) {
            var vl = this._node.dumpToObject(false);
            return vl;
        }
        var val = this._node.value();
        // if(val==null){
        //     val = this._node.value(true);
        // }
        return val;
    };
    LowLevelWrapperForTypeSystem.prototype.children = function () {
        var _this = this;
        if (this._children) {
            return this._children;
        }
        var isUses = this.key() == "uses";
        if (isUses) {
            var parent_1 = this._node.parent();
            var grandParent = parent_1.parent();
            if (grandParent != null) {
                if (this._node.unit().absolutePath() == grandParent.unit().absolutePath()) {
                    isUses = false;
                }
            }
        }
        if (isUses) {
            this._children = this._node.children().map(function (x) { return new UsesNodeWrapperFoTypeSystem(x, _this._highLevelRoot); });
        }
        else {
            this._children = this._node.children().map(function (x) { return new LowLevelWrapperForTypeSystem(x, _this._highLevelRoot); });
        }
        this.childByKey = {};
        for (var i = 0; i < this._children.length; i++) {
            var c = this._children[i];
            this.childByKey[c.key()] = c;
        }
        if (this._toMerge) {
            var mrg = this._toMerge.children();
            for (var i = 0; i < mrg.length; i++) {
                var c = mrg[i];
                var existing = this.childByKey[c.key()];
                if (existing) {
                    existing._toMerge = c;
                }
                else {
                    this._children.push(c);
                    this.childByKey[c.key()] = c;
                }
            }
        }
        return this._children;
    };
    LowLevelWrapperForTypeSystem.prototype.childWithKey = function (k) {
        if (!this._children) {
            this.children();
        }
        return this.childByKey[k];
    };
    LowLevelWrapperForTypeSystem.prototype.kind = function () {
        var vk = this._node.valueKind();
        if (vk == yaml.Kind.MAPPING || vk === null) {
            return rTypes.NodeKind.MAP;
        }
        if (vk == yaml.Kind.MAP) {
            return rTypes.NodeKind.MAP;
        }
        var knd = this._node.kind();
        if (knd == yaml.Kind.MAP) {
            return rTypes.NodeKind.MAP;
        }
        if (vk == yaml.Kind.SEQ) {
            return rTypes.NodeKind.ARRAY;
        }
        if (vk == yaml.Kind.INCLUDE_REF || vk == yaml.Kind.ANCHOR_REF) {
            if (this._node.children().length > 0) {
                //we can safely assume that it is map in the type system in this case
                return rTypes.NodeKind.MAP;
            }
        }
        return rTypes.NodeKind.SCALAR;
    };
    LowLevelWrapperForTypeSystem.prototype.getSource = function () {
        if (!this._node)
            return null;
        var highLevelNode = this._node.highLevelNode();
        if (!highLevelNode) {
            var position = this._node.start();
            var result = search.deepFindNode(this._highLevelRoot, position, position, true, false);
            if (result) {
                this._node.setHighLevelParseResult(result);
                if (ASTNodeImpl.isInstance(result)) {
                    this._node.setHighLevelNode(result);
                }
            }
            return result;
        }
        return highLevelNode;
    };
    LowLevelWrapperForTypeSystem.prototype.node = function () {
        return this._node;
    };
    LowLevelWrapperForTypeSystem.prototype.getMeta = function (key) {
        if (this.ownMeta && this.ownMeta.hasOwnProperty(key)) {
            return this.ownMeta[key];
        }
        return proxy.LowLevelProxyNode.isInstance(this._node)
            && this._node.getMeta(key);
    };
    LowLevelWrapperForTypeSystem.prototype.addMeta = function (key, value) {
        if (!this.ownMeta) {
            this.ownMeta = {};
        }
        this.ownMeta[key] = value;
    };
    LowLevelWrapperForTypeSystem.CLASS_IDENTIFIER_LowLevelWrapperForTypeSystem = "highLevelImpl.LowLevelWrapperForTypeSystem";
    return LowLevelWrapperForTypeSystem;
}(defs.SourceProvider));
exports.LowLevelWrapperForTypeSystem = LowLevelWrapperForTypeSystem;
var UsesNodeWrapperFoTypeSystem = /** @class */ (function (_super) {
    __extends(UsesNodeWrapperFoTypeSystem, _super);
    function UsesNodeWrapperFoTypeSystem() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    UsesNodeWrapperFoTypeSystem.prototype.children = function () {
        var s = this._node.unit().resolve(this.value());
        if (s && s.isRAMLUnit() && s.contents().trim().length > 0) {
            return new LowLevelWrapperForTypeSystem(s.ast(), this._highLevelRoot).children();
        }
        return [];
    };
    UsesNodeWrapperFoTypeSystem.prototype.path = function () {
        var s = this._node.unit() && this._node.unit().resolve(this.value());
        return s && s.absolutePath();
    };
    UsesNodeWrapperFoTypeSystem.prototype.anchor = function () {
        return this._node.actual();
    };
    UsesNodeWrapperFoTypeSystem.prototype.childWithKey = function (k) {
        var mm = this.children();
        for (var i = 0; i < mm.length; i++) {
            if (mm[i].key() == k) {
                return mm[i];
            }
        }
        return null;
    };
    return UsesNodeWrapperFoTypeSystem;
}(LowLevelWrapperForTypeSystem));
exports.UsesNodeWrapperFoTypeSystem = UsesNodeWrapperFoTypeSystem;
function auxiliaryTypeForExample(node) {
    var typeYamlNode = yaml.newMap([yaml.newMapping(yaml.newScalar("example"), node.lowLevel().actual())]);
    var typesNode = yaml.newMapping(yaml.newScalar("types"), yaml.newMap([yaml.newMapping(yaml.newScalar("__AUX_TYPE__"), typeYamlNode)]));
    var yamlNode = yaml.newMap([typesNode]);
    var llNode = new jsyaml.ASTNode(yamlNode, node.lowLevel().unit(), null, null, null);
    var types = rTypes.parseFromAST(new LowLevelWrapperForTypeSystem(llNode, node));
    var nominal = rTypes.toNominal(types.types()[0], function (x) { return null; });
    return nominal;
}
exports.auxiliaryTypeForExample = auxiliaryTypeForExample;
;
var ASTNodeImpl = /** @class */ (function (_super) {
    __extends(ASTNodeImpl, _super);
    function ASTNodeImpl(node, parent, _def, _prop) {
        var _this = _super.call(this, node, parent) || this;
        _this._def = _def;
        _this._prop = _prop;
        _this._expanded = false;
        _this._allowQuestion = false;
        _this._subTypesCache = null;
        _this._auxChecked = false;
        /**
         * Depending on the merge mode, overlays and extensions are either merged with the master, or their trees are joined via aggregation
         * @type {OverlayMergeMode}
         */
        _this.overlayMergeMode = OverlayMergeMode.MERGE;
        if (node) {
            node.setHighLevelNode(_this);
        }
        if (proxy.LowLevelProxyNode.isInstance(node)) {
            _this._expanded = true;
        }
        return _this;
    }
    ASTNodeImpl.isInstance = function (instance) {
        return instance != null && instance.getClassIdentifier
            && typeof (instance.getClassIdentifier) == "function"
            && _.contains(instance.getClassIdentifier(), ASTNodeImpl.CLASS_IDENTIFIER_ASTNodeImpl);
    };
    ASTNodeImpl.prototype.getClassIdentifier = function () {
        var superIdentifiers = _super.prototype.getClassIdentifier.call(this);
        return superIdentifiers.concat(ASTNodeImpl.CLASS_IDENTIFIER_ASTNodeImpl);
    };
    ASTNodeImpl.prototype.createIssue = function (error) {
        return linter.toIssue(error, this);
    };
    ASTNodeImpl.prototype.validate = function (v) {
        var k = this.definition().key();
        if (k == universes.Universe10.Api || k == universes.Universe08.Api || k == universes.Universe10.Extension) {
            if (!this.isExpanded()) {
                var nm = expander.expandTraitsAndResourceTypes(this.wrapperNode(), true);
                var hlnode = nm.highLevel();
                hlnode.resetChildren();
                hlnode.children();
                hlnode._expanded = true;
                hlnode.clearTypesCache();
                hlnode.validate(v);
                return;
            }
        }
        if (k == universes.Universe10.Overlay || k == universes.Universe10.Extension) {
            this.clearTypesCache();
        }
        _super.prototype.validate.call(this, v);
    };
    ASTNodeImpl.prototype.clearTypesCache = function () {
        this._types = null;
        if (!this.lowLevel()) {
            return;
        }
        var c = this.lowLevel().actual();
        c.types = null;
    };
    ASTNodeImpl.prototype.types = function (requestedByFragmentOrLibrary) {
        var _this = this;
        if (requestedByFragmentOrLibrary === void 0) { requestedByFragmentOrLibrary = false; }
        if (!this._types) {
            var isInLibExpandMode = (this.root().lowLevel().actual().libExpanded === true);
            var unit = this.lowLevel().unit();
            var isLibrary = this.definition().key() === universes.Universe10.Library;
            if (unit && this.parent() && this.definition() && !isLibrary) {
                var parentUnit = this.parent().lowLevel().unit();
                var parentPath = parentUnit.absolutePath();
                var thisPath = unit.absolutePath();
                var includePath_1 = this.lowLevel().includePath();
                var included = !isInLibExpandMode && includePath_1 != null;
                var parent_2 = this.parent();
                var parentPatch = false;
                var isRAML10 = this.definition().universe().version() == "RAML10";
                if (isRAML10 && includePath_1 && !isInLibExpandMode && proxy.LowLevelCompositeNode.isInstance(this.lowLevel()) && (universeHelpers.isMethodType(parent_2.definition()) || universeHelpers.isResourceType(parent_2.definition()))) {
                    var aNodes = this.lowLevel().adoptedNodes();
                    var includer = aNodes.find(function (x) { return x.includePath() == includePath_1; });
                    if (includer) {
                        var includedUnit = includer.unit().resolve(includePath_1);
                        if (includedUnit && isFragment(includedUnit)) {
                            var includedRoot = includedUnit.highLevel();
                            var newParent = includedRoot.isElement() ? includedRoot.asElement() : parent_2;
                            parent_2 = newParent;
                            parentPatch = true;
                        }
                    }
                }
                var parentTypes = parent_2.types();
                var thisDef = this.definition();
                if (!included || !thisDef) {
                    return parentTypes;
                }
                var inncluder = unit;
                if (proxy.LowLevelCompositeNode.isInstance(this.lowLevel())) {
                    var actualIncluder = this.lowLevel().adoptedNodes().find(function (x) { return x.includePath() != null; });
                    if (actualIncluder) {
                        inncluder = actualIncluder.unit();
                    }
                }
                var iUnit = inncluder.resolve(includePath_1);
                if (!iUnit || !iUnit.isRAMLUnit()) {
                    return parentTypes;
                }
                var thisTypes = iUnit.highLevel().asElement().types();
                mergeLibs(parentTypes, thisTypes);
                if (parentPatch) {
                    var originalParentTypes = unit.highLevel().asElement().types();
                    mergeLibs(originalParentTypes, thisTypes);
                }
                this._types = thisTypes;
                return thisTypes;
            }
            var c = this.lowLevel().actual();
            if (c.types) {
                return c.types;
            }
            if (unit) {
                var project = unit.project();
                if (!isInLibExpandMode && unit.absolutePath() != project.getMainUnitPath()) {
                    var mainUnit = project.getMainUnit();
                    if (mainUnit) {
                        var nsr = project.namespaceResolver();
                        var eSet = nsr.unitModel(mainUnit).extensionSet();
                        if (!eSet[unit.absolutePath()]) {
                            var mainTypes = mainUnit.highLevel().types(true);
                            if (mainTypes) {
                                var usesInfo = nsr.resolveNamespace(mainUnit, unit);
                                if (usesInfo) {
                                    var segments = usesInfo.namespaceSegments;
                                    var col = mainTypes;
                                    for (var ind = 0; ind < segments.length;) {
                                        var lib = void 0;
                                        for (var i = ind; i < segments.length; i++) {
                                            var ns = segments.slice(ind, i + 1).join(".");
                                            lib = col.library(ns);
                                            if (lib) {
                                                ind = i + 1;
                                                col = lib;
                                            }
                                        }
                                        if (lib == null) {
                                            col = null;
                                            break;
                                        }
                                    }
                                    if (col) {
                                        this._types = col;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (!this._types) {
                var ignoreUses = isInLibExpandMode;
                this._types = rTypes.parseFromAST(new LowLevelWrapperForTypeSystem(this.lowLevel(), this), ignoreUses);
                this._types.types().forEach(function (x) {
                    var convertedType = typeBuilder.convertType(_this, x);
                    convertedType.putExtra(defs.USER_DEFINED_EXTRA, true);
                });
            }
            if (this.lowLevel().actual().libExpanded) {
                this._types["uses"] = {};
            }
            if (!requestedByFragmentOrLibrary) {
                c.types = this._types;
            }
        }
        return this._types;
    };
    ASTNodeImpl.prototype.setTypes = function (t) {
        this._types = t;
    };
    ASTNodeImpl.prototype.parsedType = function () {
        var _this = this;
        if (!this._ptype) {
            var root = this.root();
            var isApi = root.definition() && universeHelpers.isApiSibling(root.definition());
            var isInLibExpandModel = this.root().lowLevel().actual().libExpanded === true;
            if ((!isApi || isInLibExpandModel) && this.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
                var parent_3 = this.parent();
                if (parent_3 && parent_3.definition().isAssignableFrom(universes.Universe10.TypeDeclaration.name)) {
                    var parentType = parent_3.parsedType();
                    if (parentType != null) {
                        if (universeHelpers.isPropertiesProperty(this.property())) {
                            var name_2 = this.name();
                            var prop = parentType.properties().find(function (p) { return p.name() == name_2; });
                            if (prop) {
                                var range = prop.range();
                                if (range) {
                                    return range;
                                }
                            }
                        }
                        else if (universeHelpers.isItemsProperty(this.property())) {
                            var ct = parentType.componentType();
                            if (ct) {
                                return ct;
                            }
                        }
                        else if (universeHelpers.isTypeProperty(this.property())) {
                            var superTypes = parentType.superTypes();
                            var ct = superTypes && superTypes.length == 1 && superTypes[0];
                            if (ct) {
                                return ct;
                            }
                        }
                    }
                }
                else if (parent_3 && parent_3.definition().isAssignableFrom(universes.Universe10.LibraryBase.name)) {
                    if (universeHelpers.isAnnotationTypesProperty(this.property())) {
                        var ct = this.types().annotationTypes().find(function (x) { return x.name() == _this.name(); });
                        if (ct) {
                            return ct;
                        }
                    }
                }
            }
            var llWrapper = new LowLevelWrapperForTypeSystem(this.lowLevel(), this);
            if (linter.typeOfContainingTemplate(this)) {
                markTemplateTypes(llWrapper);
            }
            if (this.universe().version() == "RAML08" && universeHelpers.isStringTypeDeclarationDescendant(this.definition())) {
                llWrapper.addMeta("acceptAllScalarsAsStrings", true);
            }
            if (this.property() && this.property().nameId() == universes.Universe10.MethodBase.properties.body.name) {
                var isParametrizedType = this.isParametrizedType();
                this._ptype = rTypes.parseTypeFromAST(this.name(), llWrapper, this.types(), true, false, false, isParametrizedType);
            }
            else {
                var annotation = this.property() && this.property().nameId() == universes.Universe10.LibraryBase.properties.annotationTypes.name;
                var tl = (!this.property()) || (this.property().nameId() == universes.Universe10.LibraryBase.properties.types.name || this.property().nameId() == universes.Universe10.LibraryBase.properties.schemas.name);
                if (!annotation && this.parent() == null) {
                    var localUniverse = this.universe();
                    if (localUniverse && localUniverse.getOriginalTopLevelText()
                        && localUniverse.getOriginalTopLevelText() == "AnnotationTypeDeclaration") {
                        annotation = true;
                    }
                }
                this._ptype = rTypes.parseTypeFromAST(this.name(), llWrapper, this.types(), false, annotation, tl);
            }
            if (this.property() && universeHelpers.isTypesProperty(this.property())
                && this.parent() && universeHelpers.isApiType(this.parent().definition())) {
                //top level types declared via "types"
                // this._ptype.setExtra()
                if (this._ptype.putExtra) {
                    this._ptype.putExtra(defs.DEFINED_IN_TYPES_EXTRA, true);
                }
            }
            var potentialHasExtra = this._ptype;
            potentialHasExtra.putExtra(defs.USER_DEFINED_EXTRA, true);
            this._ptype.putExtra(defs.SOURCE_EXTRA, this);
        }
        return this._ptype;
    };
    ASTNodeImpl.prototype.isParametrizedType = function () {
        var isParametrizedType = false;
        var typeAttr = this.attr(universes.Universe10.TypeDeclaration.properties.type.name);
        if (!typeAttr) {
            typeAttr = this.attr(universes.Universe10.TypeDeclaration.properties.schema.name);
        }
        if (typeAttr) {
            var typeAttrValue = typeAttr.value();
            if (typeof typeAttrValue == "string") {
                if (typeAttrValue.indexOf("<<") >= 0) {
                    var parent = this.parent();
                    while (parent != null) {
                        if (universeHelpers.isResourceTypeType(parent.definition())
                            || universeHelpers.isTraitType(parent.definition())) {
                            isParametrizedType = true;
                            break;
                        }
                        parent = parent.parent();
                    }
                }
            }
        }
        return isParametrizedType;
    };
    ASTNodeImpl.prototype.localType = function () {
        return typeBuilder.typeFromNode(this);
    };
    ASTNodeImpl.prototype.patchProp = function (pr) {
        this._prop = pr;
    };
    ASTNodeImpl.prototype.getKind = function () {
        return hl.NodeKind.NODE;
    };
    ASTNodeImpl.prototype.wrapperNode = function () {
        if (!this._wrapperNode) {
            if (universeHelpers.isExampleSpecType(this.definition())) {
                var nominal = auxiliaryTypeForExample(this);
                var spec = wrapperHelper.examplesFromNominal(nominal, this, true, false);
                return spec[0];
            }
            else {
                //forcing discrimination for fragments only
                var u = this.definition() && this.definition().universe();
                if (u && u.version() == "RAML10") {
                    if (!this.definition() || !this.definition().isAssignableFrom(def.universesInfo.Universe10.LibraryBase.name)) {
                        this.children();
                    }
                }
                else {
                    this.children();
                }
                this._wrapperNode = this.buildWrapperNode();
            }
        }
        return this._wrapperNode;
    };
    ASTNodeImpl.prototype.asElement = function () {
        return this;
    };
    ASTNodeImpl.prototype.buildWrapperNode = function () {
        var ramlVersion = this.definition().universe().version();
        if (ramlVersion == 'RAML10') {
            return factory10.buildWrapperNode(this);
        }
        else if (ramlVersion == 'RAML08') {
            return factory08.buildWrapperNode(this);
        }
        return null;
    };
    ASTNodeImpl.prototype.propertiesAllowedToUse = function () {
        var _this = this;
        return this.definition().allProperties().filter(function (x) { return _this.isAllowedToUse(x); });
    };
    ASTNodeImpl.prototype.isAllowedToUse = function (p) {
        var _this = this;
        var ok = true;
        if (p.getAdapter(services.RAMLPropertyService).isSystem()) {
            return false;
        }
        p.getContextRequirements().forEach(function (y) {
            if (y.name.indexOf('(') != -1) {
                //TODO HANDLE IT LATER
                return true;
            }
            var vl = _this.computedValue(y.name);
            if (vl) {
                ok = ok && (vl == y.value);
            }
            else {
                if (y.value) {
                    ok = false;
                }
            }
        });
        return ok;
    };
    ASTNodeImpl.prototype.allowRecursive = function () {
        if (this.definition().getAdapter(services.RAMLService).isUserDefined()) {
            return true;
        }
        return false;
    };
    ASTNodeImpl.prototype.setWrapperNode = function (node) {
        this._wrapperNode = node;
    };
    ASTNodeImpl.prototype.setAssociatedType = function (d) {
        this._associatedDef = d;
    };
    ASTNodeImpl.prototype.associatedType = function () {
        return this._associatedDef;
    };
    ASTNodeImpl.prototype.knownIds = function () {
        //initializing ids if needed
        //TODO refactor workaround
        this.isAuxilary();
        if (this._knownIds) {
            return this._knownIds;
        }
        else {
            return {};
        }
    };
    ASTNodeImpl.prototype.findById = function (id) {
        var _this = this;
        //we dont need re-indexing each time someone asks
        //node byu ID from a sub-nodes. Root most probably
        //already has everything indexed
        var currentRoot = this.root();
        if (currentRoot != this) {
            return currentRoot.findById(id);
        }
        if (!this._knownIds) {
            this._knownIds = {};
            var all = search.allChildren(this);
            all.forEach(function (x) { return _this._knownIds[x.id()] = x; });
        }
        if (this.isAuxilary()) {
            if (!this._slaveIds) {
                this._slaveIds = {};
                this._slaveIds[this.id()] = this;
                var all = search.allChildren(this);
                all.forEach(function (x) { return _this._slaveIds[x.id()] = x; });
            }
            var nodeIndexedInSlave = this._slaveIds[id];
            if (nodeIndexedInSlave)
                return nodeIndexedInSlave;
        }
        return this._knownIds[id];
    };
    ASTNodeImpl.prototype.isAuxilary = function () {
        if (this._isAux) {
            return true;
        }
        if (this._auxChecked) {
            return false;
        }
        this._auxChecked = true;
        var masterApi = this.getMaster();
        if (masterApi) {
            this._isAux = true;
            this.initilizeKnownIDs(masterApi);
            return true;
        }
        return false;
    };
    ASTNodeImpl.prototype.initilizeKnownIDs = function (api) {
        var _this = this;
        this._knownIds = {};
        var allChildren = search.allChildren(api);
        allChildren.forEach(function (x) { return _this._knownIds[x.id()] = x; });
        this._knownIds[""] = api;
    };
    ASTNodeImpl.prototype.getMaster = function () {
        if (this.masterApi) {
            return this.masterApi;
        }
        var detectedMaster = this.calculateMasterByRef();
        if (detectedMaster) {
            detectedMaster.setSlave(this);
        }
        return detectedMaster;
    };
    /**
     * Forcefully sets a master unit for this API, which may be different from the one, current unit points to
     * via masterRef.
     * @param master
     */
    ASTNodeImpl.prototype.overrideMaster = function (master) {
        this.masterApi = master;
        this.resetAuxilaryState();
        if (master) {
            master.setSlave(this);
        }
    };
    ASTNodeImpl.prototype.setSlave = function (slave) {
        this.slave = slave;
    };
    ASTNodeImpl.prototype.setMergeMode = function (mergeMode) {
        this.overlayMergeMode = mergeMode;
        this.resetAuxilaryState();
    };
    ASTNodeImpl.prototype.getMergeMode = function () {
        return this.overlayMergeMode;
    };
    ASTNodeImpl.prototype.calculateMasterByRef = function () {
        var unit = this.lowLevel().unit();
        if (!unit)
            return null;
        var masterReferenceNode = unit.getMasterReferenceNode();
        if (!masterReferenceNode || !masterReferenceNode.value()) {
            return null;
        }
        var lc = this.lowLevel();
        if (lc.master) {
            return lc.master;
        }
        var masterPath = masterReferenceNode.value();
        var masterUnit = this.lowLevel().unit().project().resolve(this.lowLevel().unit().path(), masterPath);
        if (!masterUnit) {
            return null;
        }
        var result = masterUnit.expandedHighLevel();
        result.setMergeMode(this.overlayMergeMode);
        lc.master = result;
        return result;
    };
    ASTNodeImpl.prototype.resetAuxilaryState = function () {
        this._isAux = false;
        this._auxChecked = false;
        this._knownIds = null;
        this.clearChildrenCache();
    };
    ASTNodeImpl.prototype.printDetails = function (indent) {
        var result = "";
        if (!indent)
            indent = "";
        var classname = this.definition().nameId();
        var definitionClasName = this.property() ? this.property().range().nameId() : "";
        var parentPropertyName = this.property() ? this.property().nameId() : "";
        result += indent + classname + "[" + definitionClasName + "]" + " <--- " + parentPropertyName + "\n";
        this.children().forEach(function (child) {
            result += child.printDetails(indent + "\t");
        });
        return result;
    };
    /**
     * Used for test comparison of two trees. Touching this will require AST tests update.
     * @param indent
     * @returns {string}
     */
    ASTNodeImpl.prototype.testSerialize = function (indent) {
        var result = "";
        if (!indent)
            indent = "";
        var classname = this.definition().nameId();
        var parentPropertyName = this.property() ? this.property().nameId() : "";
        result += indent + classname + " <-- " + parentPropertyName + "\n";
        this.children().forEach(function (child) {
            if (child.testSerialize) {
                result += child.testSerialize(indent + "  ");
            }
        });
        return result;
    };
    ASTNodeImpl.prototype.getExtractedChildren = function () {
        var r = this.root();
        if (r.isAuxilary()) {
            if (r._knownIds) {
                var i = r._knownIds[this.id()];
                if (i) {
                    var v = i.children();
                    return v;
                }
            }
            return [];
        }
        return [];
    };
    ASTNodeImpl.prototype.getMasterCounterPart = function () {
        var r = this.root();
        if (r.isAuxilary()) {
            if (r._knownIds) {
                var i = r._knownIds[this.id()];
                return i;
            }
            return null;
        }
        return null;
    };
    /**
     * Finds slave counterpart of this node.
     * @returns {any}
     */
    ASTNodeImpl.prototype.getSlaveCounterPart = function () {
        var root = this.root();
        if (!root.slave)
            return null;
        return root.slave.findById(this.id());
    };
    /**
     * Finds the slave counterpart of this node. If this slave has another slave in turn, recursivelly,
     * returns the last slave in the dependency sequence.
     */
    ASTNodeImpl.prototype.getLastSlaveCounterPart = function () {
        var root = this.root();
        var currentSlave = root.slave;
        if (currentSlave == null)
            return null;
        while (currentSlave.slave != null) {
            currentSlave = currentSlave.slave;
        }
        if (this.id() == "")
            return currentSlave;
        return currentSlave.findById(this.id());
    };
    ASTNodeImpl.prototype.getExtractedLowLevelChildren = function (n) {
        var r = this.root();
        if (r.isAuxilary()) {
            if (r._knownLowLevelIds) {
                var i = r._knownLowLevelIds[this.id()];
                if (i) {
                    return i.children();
                }
            }
            return [];
        }
        return [];
    };
    ASTNodeImpl.prototype.allowsQuestion = function () {
        return this._allowQuestion || this.definition().getAdapter(services.RAMLService).getAllowQuestion();
    };
    ASTNodeImpl.prototype.findReferences = function () {
        var _this = this;
        var rs = [];
        search.refFinder(this.root(), this, rs);
        //TODO FIX ME
        if (rs.length > 1) {
            rs = rs.filter(function (x) { return x != _this && x.parent() != _this; });
        }
        //filtering out equal results
        var filteredReferences = [];
        rs.forEach(function (ref) {
            if (!_.find(filteredReferences, function (existing) { return existing == ref; })) {
                filteredReferences.push(ref);
            }
        });
        return filteredReferences;
    };
    ASTNodeImpl.prototype.setNamePatch = function (s) {
        this._patchedName = s;
    };
    ASTNodeImpl.prototype.isNamePatch = function () {
        return this._patchedName;
    };
    ASTNodeImpl.prototype.name = function () {
        if (this._patchedName) {
            return this._patchedName;
        }
        var ka = _.find(this.directChildren(), function (x) { return x.property() && x.property().getAdapter(services.RAMLPropertyService).isKey(); });
        if (ka && ASTPropImpl.isInstance(ka)) {
            var c = null;
            var defClass = this.definition();
            var ramlVersion = defClass.universe().version();
            if (defClass && ramlVersion == "RAML10" && ka.isFromKey()) {
                var key = this._computedKey || this._node.key();
                c = this._node.optional() ? key + "?" : key;
            }
            else {
                c = ka.value();
            }
            return c;
        }
        return _super.prototype.name.call(this);
    };
    ASTNodeImpl.prototype.findElementAtOffset = function (n) {
        return this._findNode(this, n, n);
    };
    ASTNodeImpl.prototype.isElement = function () {
        return true;
    };
    ASTNodeImpl.prototype.universe = function () {
        if (this._universe) {
            return this._universe;
        }
        return this.definition().universe();
    };
    ASTNodeImpl.prototype.setUniverse = function (u) {
        this._universe = u;
    };
    ASTNodeImpl.prototype._findNode = function (n, offset, end) {
        var _this = this;
        if (n == null) {
            return null;
        }
        if (n.lowLevel()) {
            //var node:ASTNode=<ASTNode>n;
            if (n.lowLevel().start() <= offset && n.lowLevel().end() >= end) {
                var res = n;
                //TODO INCLUDES
                n.elements().forEach(function (x) {
                    if (x.lowLevel().unit() != n.lowLevel().unit()) {
                        return;
                    }
                    var m = _this._findNode(x, offset, end);
                    if (m) {
                        res = m;
                    }
                });
                return res;
            }
        }
        return null;
    };
    ASTNodeImpl.prototype.isStub = function () {
        return (!this.lowLevel().unit()) || this.lowLevel().unit().isStubUnit();
    };
    ASTNodeImpl.prototype.add = function (node) {
        mutators.addToNode(this, node);
    };
    ASTNodeImpl.prototype.remove = function (node) {
        mutators.removeNodeFrom(this, node);
    };
    ASTNodeImpl.prototype.dump = function (flavor) {
        return this._node.dump();
    };
    ASTNodeImpl.prototype.patchType = function (d) {
        this._def = d;
        var ass = this._associatedDef;
        this._associatedDef = null;
        this._children = null;
        this._mergedChildren = null;
    };
    ASTNodeImpl.prototype.children = function () {
        var lowLevel = this.lowLevel();
        if (lowLevel && lowLevel.isValueInclude && lowLevel.isValueInclude() && resourceRegistry.isWaitingFor(lowLevel.includePath())) {
            this._children = null;
            return [];
        }
        if (this._children) {
            if (this._mergedChildren) {
                return this._mergedChildren;
            }
            this._mergedChildren = this.mergeChildren(this._children, this.getExtractedChildren());
            return this._mergedChildren;
        }
        if (this._node) {
            this._children = nodeBuilder.process(this, this._node.children());
            this._children = this._children.filter(function (x) { return x != null; });
            //FIXME
            return this.mergeChildren(this._children, this.getExtractedChildren());
        }
        return [];
    };
    ASTNodeImpl.prototype.mergeChildren = function (originalChildren, masterChildren) {
        var _this = this;
        var root = this.root();
        if (root.overlayMergeMode == OverlayMergeMode.AGGREGATE) {
            //simply joining the sets
            return originalChildren.concat(masterChildren);
        }
        else if (root.overlayMergeMode == OverlayMergeMode.MERGE) {
            var result = [];
            originalChildren.forEach(function (originalChild) {
                var masterCounterpart = _.find(masterChildren, function (masterChild) { return masterChild.fullLocalId() == originalChild.fullLocalId(); });
                if (!masterCounterpart) {
                    //we dont have a counterpart, so simply adding to result
                    result.push(originalChild);
                }
                else {
                    //there is a counterpart, so deciding what to do:
                    _this.mergeChild(result, originalChild, masterCounterpart);
                }
            });
            masterChildren.forEach(function (masterChild) {
                var originalCounterpart = _.find(originalChildren, function (originalChild) { return masterChild.fullLocalId() == originalChild.fullLocalId(); });
                if (!originalCounterpart) {
                    //we dont have a counterpart, so simply adding to result
                    result.push(masterChild);
                }
            });
            return result;
        }
        return null;
    };
    ASTNodeImpl.prototype.mergeLowLevelChildren = function (originalChildren, masterChildren) {
        var _this = this;
        var root = this.root();
        if (root.overlayMergeMode == OverlayMergeMode.AGGREGATE) {
            //simply joining the sets
            return originalChildren.concat(masterChildren);
        }
        else if (root.overlayMergeMode == OverlayMergeMode.MERGE) {
            var result = [];
            originalChildren.forEach(function (originalChild) {
                var masterCounterpart = _.find(masterChildren, function (masterChild) { return masterChild.key() == originalChild.key(); });
                if (!masterCounterpart) {
                    //we dont have a counterpart, so simply adding to result
                    result.push(originalChild);
                }
                else {
                    //there is a counterpart, so deciding what to do:
                    _this.mergeLowLevelChild(result, originalChild, masterCounterpart);
                }
            });
            masterChildren.forEach(function (masterChild) {
                var originalCounterpart = _.find(originalChildren, function (originalChild) { return masterChild.key() == originalChild.key(); });
                if (!originalCounterpart) {
                    //we dont have a counterpart, so simply adding to result
                    result.push(masterChild);
                }
            });
            return result;
        }
        return null;
    };
    ASTNodeImpl.prototype.mergeLowLevelChild = function (result, originalChild, masterChild) {
        if (originalChild.kind() != masterChild.kind()) {
            //should not happen theoretically
            result.push(originalChild);
            result.push(masterChild);
            return;
        }
        result.push(originalChild);
    };
    ASTNodeImpl.prototype.mergeChild = function (result, originalChild, masterChild) {
        if (originalChild.getKind() != masterChild.getKind()) {
            //should not happen theoretically
            result.push(originalChild);
            result.push(masterChild);
            return;
        }
        if (originalChild.getKind() == hl.NodeKind.NODE) {
            result.push(originalChild);
            return;
        }
        else if (originalChild.getKind() == hl.NodeKind.ATTRIBUTE) {
            //if ((<ASTPropImpl>originalChild).name() == "displayName" ||
            //    (<ASTPropImpl>originalChild).name() == "title") {
            //    console.log("OriginalChildForDisplayName: " + (<ASTPropImpl>originalChild).value())
            //    console.log("MasterChildForDisplayName: " + (<ASTPropImpl>masterChild).value())
            //
            //}
            result.push(originalChild);
            return;
        }
        else if (originalChild.getKind() == hl.NodeKind.BASIC) {
            //we do not know what to do with basic nodes, so adding both.
            result.push(originalChild);
            result.push(masterChild);
            return;
        }
    };
    ASTNodeImpl.prototype.directChildren = function () {
        if (this._children) {
            return this._children;
        }
        if (this._node) {
            this._children = nodeBuilder.process(this, this._node.children());
            this._mergedChildren = null;
            return this._children;
        }
        return [];
    };
    ASTNodeImpl.prototype.resetChildren = function () {
        this._children = null;
        this._mergedChildren = null;
    };
    ASTNodeImpl.prototype.isEmptyRamlFile = function () {
        var llroot = this.lowLevel().root();
        return llroot.isScalar();
    };
    ASTNodeImpl.prototype.initRamlFile = function () {
        mutators.initEmptyRAMLFile(this);
    };
    ASTNodeImpl.prototype.createAttr = function (n, v) {
        mutators.createAttr(this, n, v);
    };
    ASTNodeImpl.prototype.isAttr = function () {
        return false;
    };
    ASTNodeImpl.prototype.isUnknown = function () {
        return false;
    };
    ASTNodeImpl.prototype.value = function () {
        return this._node.value();
    };
    ASTNodeImpl.prototype.valuesOf = function (propName) {
        var pr = this._def.property(propName);
        if (pr != null) {
            return this.elements().filter(function (x) { return x.property() == pr; });
        }
        return [];
    };
    ASTNodeImpl.prototype.attr = function (n) {
        return _.find(this.attrs(), function (y) { return y.name() == n; });
    };
    ASTNodeImpl.prototype.attrOrCreate = function (name) {
        var a = this.attr(name);
        if (!a)
            this.createAttr(name, '');
        return this.attr(name);
    };
    ASTNodeImpl.prototype.attrValue = function (n) {
        var a = this.attr(n);
        return a ? a.value() : null;
    };
    ASTNodeImpl.prototype.attributes = function (n) {
        return _.filter(this.attrs(), function (y) { return y.name() == n; });
    };
    ASTNodeImpl.prototype.attrs = function () {
        var rs = this.children().filter(function (x) { return x.isAttr(); });
        if (this._patchedName) {
            var kp = _.find(this.definition().allProperties(), function (x) { return x.getAdapter(services.RAMLPropertyService).isKey(); });
            if (kp) {
                var mm = new ASTPropImpl(this.lowLevel(), this, kp.range(), kp, true);
                mm._value = this._patchedName;
                return [mm].concat(rs);
            }
        }
        return rs;
    };
    ASTNodeImpl.prototype.elements = function () {
        return this.children()
            .filter(function (x) { return !x.isAttr() && !x.isUnknown(); });
    };
    ASTNodeImpl.prototype.element = function (n) {
        var r = this.elementsOfKind(n);
        if (r.length > 0) {
            return r[0];
        }
        return null;
    };
    ASTNodeImpl.prototype.elementsOfKind = function (n) {
        var r = this.elements().filter(function (x) { return x.property().nameId() == n; });
        return r;
    };
    ASTNodeImpl.prototype.definition = function () {
        return this._def;
    };
    ASTNodeImpl.prototype.property = function () {
        return this._prop;
    };
    ASTNodeImpl.prototype.isExpanded = function () {
        return this._expanded;
    };
    ASTNodeImpl.prototype.copy = function () {
        return new ASTNodeImpl(this.lowLevel().copy(), this.parent(), this.definition(), this.property());
    };
    ASTNodeImpl.prototype.clearChildrenCache = function () {
        this._children = null;
        this._mergedChildren = null;
    };
    ASTNodeImpl.prototype.optionalProperties = function () {
        var def = this.definition();
        if (def == null) {
            return [];
        }
        var result = [];
        var map = {};
        var children = this.lowLevel().children();
        children.forEach(function (x) {
            if (x.optional()) {
                map[x.key()] = true;
            }
        });
        var props = def.allProperties();
        props.forEach(function (x) {
            var prop = x;
            if (map[prop.nameId()]) {
                result.push(prop.nameId());
            }
        });
        return result;
    };
    ASTNodeImpl.prototype.setReuseMode = function (val) {
        this._reuseMode = val;
        if (this._children && this.lowLevel().valueKind() != yaml.Kind.SEQ) {
            this._children.forEach(function (x) { return x.setReuseMode(val); });
        }
    };
    ASTNodeImpl.prototype.reusedNode = function () {
        return this._reusedNode;
    };
    ASTNodeImpl.prototype.setReusedNode = function (n) {
        this._reusedNode = n;
    };
    ASTNodeImpl.prototype.resetRuntimeTypes = function () {
        delete this._associatedDef;
        this.elements().forEach(function (x) { return x.resetRuntimeTypes(); });
    };
    /**
     * Turns high level model node into an object.
     * @param options serialization options
     * @return Stringifyable object representation of the node.
     **/
    ASTNodeImpl.prototype.toJSON = function (options) {
        return new jsonSerializerHL.JsonSerializer(options).dump(this);
    };
    ASTNodeImpl.CLASS_IDENTIFIER_ASTNodeImpl = "highLevelImpl.ASTNodeImpl";
    return ASTNodeImpl;
}(BasicASTNode));
exports.ASTNodeImpl = ASTNodeImpl;
exports.universeProvider = require("./definition-system/universeProvider");
var getDefinitionSystemType = function (contents, ast) {
    var rfl = ramlFirstLine(contents);
    var spec = (rfl && rfl[1]) || "";
    var ptype = fragmentType(contents);
    var originalPType = rfl && rfl.length > 2 && rfl[2];
    var localUniverse = spec == "1.0" ? new def.Universe(null, "RAML10", exports.universeProvider("RAML10"), "RAML10") : new def.Universe(null, "RAML08", exports.universeProvider("RAML08"));
    localUniverse.setOriginalTopLevelText(originalPType);
    localUniverse.setTopLevel(ptype);
    localUniverse.setTypedVersion(spec);
    // localUniverse.setDescription(spec);
    return { ptype: ptype, localUniverse: localUniverse };
};
function fragmentType(content) {
    if (!content.trim().startsWith("#%RAML 1.0")) {
        return null;
    }
    var rfl = ramlFirstLine(content);
    var ptype = (rfl && rfl.length > 2 && rfl[2]) || "Api";
    if (ptype == 'API') {
        ptype = "Api";
    }
    else if (ptype == 'NamedExample') {
        ptype = "ExampleSpec";
    }
    else if (ptype == 'DataType') {
        ptype = "TypeDeclaration";
    }
    else if (ptype == 'SecurityScheme') {
        ptype = "AbstractSecurityScheme";
    }
    else if (ptype == 'AnnotationTypeDeclaration') {
        ptype = "TypeDeclaration";
    }
    return ptype;
}
function isFragment(unit) {
    var rfl = ramlFirstLine(unit.contents());
    var result = rfl && rfl[2];
    return result != null && result.length > 0;
}
function ramlFirstLine(content) {
    return content.match(/^\s*#%RAML\s+(\d\.\d)\s*(\w*)\s*$/m);
}
exports.ramlFirstLine = ramlFirstLine;
function getFragmentDefenitionName(highLevelNode) {
    var contents = highLevelNode.lowLevel() && highLevelNode.lowLevel().unit() && highLevelNode.lowLevel().unit().contents();
    if (contents == null) {
        return null;
    }
    return getDefinitionSystemType(contents, highLevelNode.lowLevel()).ptype;
}
exports.getFragmentDefenitionName = getFragmentDefenitionName;
function fromUnit(l) {
    if (l == null)
        return null;
    var contents = l.contents();
    var ast = l.ast();
    var __ret = getDefinitionSystemType(contents, ast);
    var ptype = __ret.ptype;
    var localUniverse = __ret.localUniverse;
    var apiType = localUniverse.type(ptype);
    if (!apiType)
        apiType = localUniverse.type("Api");
    var api = new ASTNodeImpl(ast, null, apiType, null);
    api.setUniverse(localUniverse);
    //forcing discrimination for fragments only
    var u = apiType && apiType.universe();
    if (u && u.version() == "RAML10") {
        if (!apiType.isAssignableFrom(def.universesInfo.Universe10.LibraryBase.name)) {
            api.children();
        }
    }
    else {
        api.children();
    }
    return api;
}
exports.fromUnit = fromUnit;
/**
 * Creates basic acceptor.
 * If primaryUnitPointerNode is provided, creates PointOfViewValidationAcceptor
 * instance with primary unit taken from the node.
 * @param errors
 * @param primaryUnitPointerNode
 * @returns {hl.ValidationAcceptor}
 */
function createBasicValidationAcceptor(errors, primaryUnitPointerNode) {
    if (primaryUnitPointerNode) {
        var unit = primaryUnitPointerNode.root().lowLevel().unit();
        if (unit) {
            return new utils.PointOfViewValidationAcceptorImpl(errors, primaryUnitPointerNode.root());
        }
        else {
            return {
                accept: function (c) {
                    errors.push(c);
                },
                begin: function () {
                },
                end: function () {
                },
                acceptUnique: function (issue) {
                    for (var _i = 0, errors_1 = errors; _i < errors_1.length; _i++) {
                        var e = errors_1[_i];
                        if (e.start == issue.start && e.message == issue.message) {
                            return;
                        }
                    }
                    this.accept(issue);
                }
            };
        }
    }
}
exports.createBasicValidationAcceptor = createBasicValidationAcceptor;
function isAnnotationTypeFragment(node) {
    if (node.parent() != null) {
        return false;
    }
    var unit = node.lowLevel().unit();
    if (unit == null) {
        return false;
    }
    var content = unit.contents();
    var fLine = ramlFirstLine(content);
    if (fLine.length < 3) {
        return false;
    }
    return fLine[2] == "AnnotationTypeDeclaration";
}
exports.isAnnotationTypeFragment = isAnnotationTypeFragment;
var AnnotatedNode = /** @class */ (function () {
    function AnnotatedNode(_node) {
        this._node = _node;
    }
    ;
    AnnotatedNode.prototype.kind = function () { return "AnnotatedNode"; };
    AnnotatedNode.prototype.annotationsMap = function () {
        var _this = this;
        if (!this._annotationsMap) {
            this._annotationsMap = {};
            this.annotations().forEach(function (x) {
                var n = x.name();
                var ind = n.lastIndexOf(".");
                if (ind >= 0) {
                    n = n.substring(ind + 1);
                }
                _this._annotationsMap[n] = x;
            });
        }
        return this._annotationsMap;
    };
    AnnotatedNode.prototype.annotations = function () {
        if (!this._annotations) {
            var aAttrs = [];
            if (this._node.isElement()) {
                aAttrs = this._node.asElement().attributes(def.universesInfo.Universe10.Annotable.properties.annotations.name);
            }
            else if (this._node.isAttr()) {
                aAttrs = this._node.asAttr().annotations();
            }
            this._annotations = aAttrs.map(function (x) { return new AnnotationInstance(x); });
        }
        return this._annotations;
    };
    AnnotatedNode.prototype.value = function () {
        if (this._node.isElement()) {
            return this._node.asElement().wrapperNode().toJSON();
        }
        else if (this._node.isAttr()) {
            var val = this._node.asAttr().value();
            if (StructuredValue.isInstance(val)) {
                return val.lowLevel().dump();
            }
            return val;
        }
        return this._node.lowLevel().dump();
    };
    AnnotatedNode.prototype.name = function () { return this._node.name(); };
    AnnotatedNode.prototype.entry = function () { return this._node; };
    return AnnotatedNode;
}());
exports.AnnotatedNode = AnnotatedNode;
var AnnotationInstance = /** @class */ (function () {
    function AnnotationInstance(attr) {
        this.attr = attr;
    }
    AnnotationInstance.prototype.name = function () {
        return this.attr.value().valueName();
    };
    /**
     * Annotation value
     */
    AnnotationInstance.prototype.value = function () {
        var val = this.attr.value();
        if (StructuredValue.isInstance(val)) {
            var obj = val.lowLevel().dumpToObject();
            var key = Object.keys(obj)[0];
            return obj[key];
        }
        return val;
    };
    /**
     * Annotation definition type
     */
    AnnotationInstance.prototype.definition = function () {
        var parent = this.attr.parent();
        var vn = this.name();
        var cands = search.referenceTargets(this.attr.property(), parent).filter(function (x) { return qName(x, parent) == vn; });
        if (cands.length == 0) {
            return null;
        }
        return cands[0].parsedType();
    };
    return AnnotationInstance;
}());
exports.AnnotationInstance = AnnotationInstance;
function toValidationIssue(x, pluginId, node) {
    var vi = x.validationIssue;
    if (!vi) {
        var issueCode = x.issueCode || pluginId;
        var node1 = x.node || node;
        var message = x.message || linter.createIssue1(messageRegistry.PLUGIN_REPORTS_AN_ERROR, { pluginId: pluginId }, node1, false).message;
        var isWarning = x.isWarning;
        vi = linter.createIssue(issueCode, message, node1, isWarning);
    }
    return vi;
}
;
/**
 * Apply registered node validation plugins to the type
 * @param node node to be validated
 * @returns an array of {NodeValidationPluginIssue}
 */
function applyNodeValidationPlugins(node) {
    var result = [];
    var plugins = hl.getNodeValidationPlugins();
    for (var _i = 0, plugins_1 = plugins; _i < plugins_1.length; _i++) {
        var tv = plugins_1[_i];
        var issues = tv.process(node);
        if (issues) {
            issues.forEach(function (x) {
                var vi = toValidationIssue(x, tv.id(), node);
                result.push(vi);
            });
        }
    }
    return result;
}
exports.applyNodeValidationPlugins = applyNodeValidationPlugins;
/**
 * Apply registered node annotation validation plugins to the type
 * @param node node to be validated
 * @returns an array of {NodeValidationPluginIssue}
 */
function applyNodeAnnotationValidationPlugins(node) {
    var aEntry = new AnnotatedNode(node);
    var result = [];
    var plugins = hl.getNodeAnnotationValidationPlugins();
    for (var _i = 0, plugins_2 = plugins; _i < plugins_2.length; _i++) {
        var tv = plugins_2[_i];
        var issues = tv.process(aEntry);
        if (issues) {
            issues.forEach(function (x) {
                var vi = toValidationIssue(x, tv.id(), node);
                result.push(vi);
            });
        }
    }
    return result;
}
exports.applyNodeAnnotationValidationPlugins = applyNodeAnnotationValidationPlugins;
function toParserErrors(issues, node) {
    var rawResult = issues.map(function (x) { return basicError(x, node); });
    var result = filterErrors(rawResult);
    return result;
}
exports.toParserErrors = toParserErrors;
function filterErrors(rawErrors) {
    var result = [];
    var errorsMap = {};
    rawErrors.map(function (x) { errorsMap[JSON.stringify(x)] = x; });
    var keys = Object.keys(errorsMap);
    for (var i = 0; i < keys.length; i++) {
        result.push(errorsMap[keys[i]]);
    }
    return result;
}
function basicError(x, node) {
    var lineMapper = (x.node && x.node.lowLevel() && x.node.lowLevel().unit().lineMapper())
        || node.lowLevel().unit().lineMapper();
    var startPoint = null;
    try {
        startPoint = lineMapper.position(x.start);
    }
    catch (e) {
        console.warn(e);
    }
    var endPoint = null;
    try {
        endPoint = lineMapper.position(x.end);
    }
    catch (e) {
        console.warn(e);
    }
    var path;
    if (x.path) {
        path = x.path;
    }
    else if (x.node) {
        path = x.node.lowLevel().unit().path();
    }
    else {
        path = search.declRoot(node).lowLevel().unit().path();
    }
    var eObj = {
        code: x.code,
        message: x.message,
        path: path,
        range: {
            start: startPoint,
            end: endPoint
        },
        isWarning: x.isWarning
    };
    if (x.extras && x.extras.length > 0) {
        eObj.trace = x.extras.map(function (y) { return basicError(y, node); });
    }
    return eObj;
}
function markTemplateTypes(node) {
    if (node.kind() == yaml.Kind.SCALAR) {
        if (checkIfHasTeplateParams(node.value())) {
            node.addMeta("skipValidation", true);
        }
        return;
    }
    var typeNode = node.childWithKey(def.universesInfo.Universe10.TypeDeclaration.properties.type.name);
    var schemaNode = node.childWithKey(def.universesInfo.Universe10.TypeDeclaration.properties.schema.name);
    var typeNodes = [];
    if (typeNode) {
        if (typeNode.kind() == yaml.Kind.SEQ) {
            typeNodes = typeNodes.concat(typeNode.children());
        }
        else {
            typeNodes.push(typeNode);
        }
    }
    if (schemaNode) {
        if (schemaNode && schemaNode.kind() == yaml.Kind.SEQ) {
            typeNodes = typeNodes.concat(schemaNode.children());
        }
        else {
            typeNodes.push(schemaNode);
        }
    }
    var skipValidation = false;
    for (var _i = 0, typeNodes_1 = typeNodes; _i < typeNodes_1.length; _i++) {
        var tn = typeNodes_1[_i];
        if (tn.kind() == yaml.Kind.SCALAR) {
            var val = tn.value();
            skipValidation = skipValidation || checkIfHasTeplateParams(val);
        }
        else if (tn.kind() == yaml.Kind.MAP || tn.kind() == yaml.Kind.MAPPING) {
            markTemplateTypes(tn);
        }
    }
    for (var _a = 0, _b = node.children(); _a < _b.length; _a++) {
        var ch = _b[_a];
        var chKey = ch.key();
        if (checkIfHasTeplateParams(chKey)) {
            ch.addMeta("skipValidation", true);
        }
        else if (typeof ch.value() === "string") {
            if (checkIfHasTeplateParams(ch.value())) {
                ch.addMeta("skipValidation", true);
            }
        }
        else if (chKey && chKey.length > 0
            && chKey.charAt(0) == "(" && chKey.charAt(chKey.length - 1) == ")") {
            if (hasTemplateArgs(ch.node())) {
                ch.addMeta("skipValidation", true);
            }
        }
    }
    if (skipValidation) {
        node.addMeta("skipValidation", true);
    }
    var pNode = node.childWithKey(def.universesInfo.Universe10.ObjectTypeDeclaration.properties.properties.name);
    checkTypePropertiesForTemplateParameters(pNode);
    var fNode = node.childWithKey(def.universesInfo.Universe10.TypeDeclaration.properties.facets.name);
    checkTypePropertiesForTemplateParameters(fNode);
    var iNode = node.childWithKey(def.universesInfo.Universe10.ArrayTypeDeclaration.properties.items.name);
    if (iNode) {
        if (iNode.kind() == yaml.Kind.SCALAR) {
            if (checkIfHasTeplateParams(iNode.value())) {
                iNode.addMeta("skipValidation", true);
            }
        }
        else if (iNode.kind() == yaml.Kind.MAP || iNode.kind() == yaml.Kind.MAPPING) {
            for (var _c = 0, _d = iNode.children(); _c < _d.length; _c++) {
                var p = _d[_c];
                markTemplateTypes(p);
            }
        }
    }
}
function checkTypePropertiesForTemplateParameters(propertiesNode) {
    if (propertiesNode) {
        for (var _i = 0, _a = propertiesNode.children(); _i < _a.length; _i++) {
            var p = _a[_i];
            markTemplateTypes(p);
        }
    }
}
function checkIfHasTeplateParams(value) {
    if (typeof value === "string") {
        var i0 = value.indexOf("<<");
        if (i0 >= 0 && value.indexOf(">>", i0) > 0) {
            return true;
        }
    }
    return false;
}
function hasTemplateArgs(node) {
    var vl = node.value();
    if (typeof vl == "string") {
        if (vl.indexOf("<<") != -1) {
            return true;
        }
    }
    var x = node.children();
    for (var i = 0; i < x.length; i++) {
        if (hasTemplateArgs(x[i])) {
            return true;
        }
    }
    return false;
}
function actualPath(node, checkIfDifferent) {
    if (checkIfDifferent === void 0) { checkIfDifferent = false; }
    var llNode = node.lowLevel();
    var ownPath = llNode.unit().absolutePath();
    var unit = actualUnit(llNode);
    var unitPath;
    if ((llNode.kind() == yaml.Kind.INCLUDE_REF || llNode.valueKind() == yaml.Kind.INCLUDE_REF)
        && unit.absolutePath() == ownPath && llNode.includePath()) {
        unitPath = llNode.includePath();
    }
    else if (unit.isRAMLUnit() && unit.ast()) {
        var iPath = unit.ast().includePath();
        if (iPath) {
            unitPath = iPath;
        }
    }
    if (!unitPath) {
        unitPath = unit.absolutePath();
    }
    if (checkIfDifferent) {
        if (ownPath == unitPath) {
            return null;
        }
    }
    if (!ll.isWebPath(unitPath)) {
        var projectPath = unit.project().getRootPath();
        unitPath = path.relative(projectPath, unitPath).replace(/\\/g, '/');
    }
    return unitPath;
}
exports.actualPath = actualPath;
function actualUnit(llNode) {
    var nodeUnit = llNode.unit();
    var unit = nodeUnit;
    while (llNode.kind() == yaml.Kind.INCLUDE_REF || llNode.valueKind() == yaml.Kind.INCLUDE_REF) {
        var iPath = llNode.includePath();
        var iUnit = unit.resolve(iPath);
        if (iUnit) {
            unit = iUnit;
            if (unit.isRAMLUnit()) {
                llNode = unit.ast();
            }
            else {
                break;
            }
        }
        else {
            break;
        }
    }
    return unit;
}
exports.actualUnit = actualUnit;
function resolveSchemaFragment(node, value) {
    var result = null;
    try {
        var schemaObj = JSON.parse(value);
        if (schemaObj && typeof schemaObj === "object" && Object.keys(schemaObj).length == 1 && schemaObj.hasOwnProperty("$ref")) {
            var ref = schemaObj["$ref"];
            if (typeof ref === "string") {
                var ind = ref.indexOf("#");
                if (ind >= 0) {
                    var unitPath = ref.substring(0, ind);
                    var fragment = ref.substring(ind);
                    if (fragment.length > 1) {
                        var unit = node.lowLevel().unit().resolve(unitPath);
                        if (unit) {
                            var schemaContent = unit.contents();
                            var fullSchemaObj = JSON.parse(schemaContent);
                            var jPath = jsonPath.create(fragment);
                            var res = jPath.resolve(fullSchemaObj, function () { return null; });
                            if (Array.isArray(res) && res.length) {
                                result = JSON.stringify(res[0], null, 2);
                            }
                        }
                    }
                }
            }
        }
    }
    catch (e) { }
    return result;
}
exports.resolveSchemaFragment = resolveSchemaFragment;
function mergeLibs(from, to) {
    if (from.id() && (from.id() == to.id())) {
        return;
    }
    for (var _i = 0, _a = from.types(); _i < _a.length; _i++) {
        var t = _a[_i];
        if (!to.getType(t.name())) {
            to.add(t);
        }
    }
    for (var _b = 0, _c = from.annotationTypes(); _b < _c.length; _b++) {
        var t = _c[_b];
        if (!to.getType(t.name())) {
            to.addAnnotationType(t);
        }
    }
    var libs = from.libraries();
    for (var _d = 0, _e = Object.keys(libs); _d < _e.length; _d++) {
        var ns = _e[_d];
        var lib = libs[ns];
        var toCh = to.library(ns);
        if (toCh) {
            mergeLibs(lib, toCh);
        }
        else {
            to.addLibrary(ns, lib);
        }
    }
}
function belongsToFragment(n) {
    var unit = n.lowLevel().unit();
    var content = unit.contents();
    if (!content.trim().startsWith("#%RAML")) {
        return false;
    }
    var tName = fragmentType(content);
    var node = n.isElement() ? n.asElement() : n.parent();
    var t = node.definition().universe().type(tName);
    if (t == null) {
        return true;
    }
    if (universeHelpers.isLibraryBaseSibling(t)) {
        return false;
    }
    return true;
}
//# sourceMappingURL=highLevelImpl.js.map