(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "jsonc-parser", "../utils/json", "vscode-languageserver-types", "vscode-nls"], factory);
    }
})(function (require, exports) {
    /*---------------------------------------------------------------------------------------------
     *  Copyright (c) Microsoft Corporation. All rights reserved.
     *  Licensed under the MIT License. See License.txt in the project root for license information.
     *--------------------------------------------------------------------------------------------*/
    'use strict';
    var Json = require("jsonc-parser");
    var json_1 = require("../utils/json");
    var vscode_languageserver_types_1 = require("vscode-languageserver-types");
    var nls = require("vscode-nls");
    var localize = nls.loadMessageBundle();
    var JSONCompletion = (function () {
        function JSONCompletion(schemaService, contributions, promiseConstructor) {
            if (contributions === void 0) { contributions = []; }
            this.templateVarIdCounter = 0;
            this.schemaService = schemaService;
            this.contributions = contributions;
            this.promise = promiseConstructor || Promise;
        }
        JSONCompletion.prototype.doResolve = function (item) {
            for (var i = this.contributions.length - 1; i >= 0; i--) {
                if (this.contributions[i].resolveCompletion) {
                    var resolver = this.contributions[i].resolveCompletion(item);
                    if (resolver) {
                        return resolver;
                    }
                }
            }
            return this.promise.resolve(item);
        };
        JSONCompletion.prototype.doComplete = function (document, position, doc) {
            var _this = this;
            var result = {
                items: [],
                isIncomplete: false
            };
            var offset = document.offsetAt(position);
            var node = doc.getNodeFromOffsetEndInclusive(offset);
            if (this.isInComment(document, node ? node.start : 0, offset)) {
                return Promise.resolve(result);
            }
            var currentWord = this.getCurrentWord(document, offset);
            var overwriteRange = null;
            if (node && (node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) {
                overwriteRange = vscode_languageserver_types_1.Range.create(document.positionAt(node.start), document.positionAt(node.end));
            }
            else {
                var overwriteStart = offset - currentWord.length;
                if (overwriteStart > 0 && document.getText()[overwriteStart - 1] === '"') {
                    overwriteStart--;
                }
                overwriteRange = vscode_languageserver_types_1.Range.create(document.positionAt(overwriteStart), position);
            }
            var proposed = {};
            var collector = {
                add: function (suggestion) {
                    var existing = proposed[suggestion.label];
                    if (!existing) {
                        proposed[suggestion.label] = suggestion;
                        if (overwriteRange) {
                            suggestion.textEdit = vscode_languageserver_types_1.TextEdit.replace(overwriteRange, suggestion.insertText);
                        }
                        result.items.push(suggestion);
                    }
                    else if (!existing.documentation) {
                        existing.documentation = suggestion.documentation;
                    }
                },
                setAsIncomplete: function () {
                    result.isIncomplete = true;
                },
                error: function (message) {
                    console.error(message);
                },
                log: function (message) {
                    console.log(message);
                },
                getNumberOfProposals: function () {
                    return result.items.length;
                }
            };
            return this.schemaService.getSchemaForResource(document.uri, doc).then(function (schema) {
                var collectionPromises = [];
                var addValue = true;
                var currentKey = '';
                var currentProperty = null;
                if (node) {
                    if (node.type === 'string') {
                        var stringNode = node;
                        if (stringNode.isKey) {
                            addValue = !(node.parent && (node.parent.value));
                            currentProperty = node.parent ? node.parent : null;
                            currentKey = document.getText().substring(node.start + 1, node.end - 1);
                            if (node.parent) {
                                node = node.parent.parent;
                            }
                        }
                    }
                }
                // proposals for properties
                if (node && node.type === 'object') {
                    // don't suggest keys when the cursor is just before the opening curly brace
                    if (node.start === offset) {
                        return result;
                    }
                    // don't suggest properties that are already present
                    var properties = node.properties;
                    properties.forEach(function (p) {
                        if (!currentProperty || currentProperty !== p) {
                            proposed[p.key.value] = vscode_languageserver_types_1.CompletionItem.create('__');
                        }
                    });
                    var separatorAfter_1 = '';
                    if (addValue) {
                        separatorAfter_1 = _this.evaluateSeparatorAfter(document, document.offsetAt(overwriteRange.end));
                    }
                    if (schema) {
                        // property proposals with schema
                        _this.getPropertyCompletions(schema, doc, node, addValue, separatorAfter_1, collector);
                    }
                    else {
                        // property proposals without schema
                        _this.getSchemaLessPropertyCompletions(doc, node, currentKey, collector);
                    }
                    var location_1 = node.getPath();
                    _this.contributions.forEach(function (contribution) {
                        var collectPromise = contribution.collectPropertyCompletions(document.uri, location_1, currentWord, addValue, separatorAfter_1 === '', collector);
                        if (collectPromise) {
                            collectionPromises.push(collectPromise);
                        }
                    });
                    if ((!schema && currentWord.length > 0 && document.getText().charAt(offset - currentWord.length - 1) !== '"')) {
                        collector.add({
                            kind: vscode_languageserver_types_1.CompletionItemKind.Property,
                            label: _this.getLabelForValue(currentWord),
                            insertText: _this.getInsertTextForProperty(currentWord, null, false, separatorAfter_1),
                            insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet, documentation: ''
                        });
                    }
                }
                // proposals for values
                var offsetForSeparator = offset;
                if (node && (node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) {
                    offsetForSeparator = node.end;
                    node = node.parent;
                }
                var separatorAfter = '';
                if (node) {
                    separatorAfter = _this.evaluateSeparatorAfter(document, offsetForSeparator);
                }
                var types = {};
                if (schema) {
                    // value proposals with schema
                    _this.getValueCompletions(schema, doc, node, offset, separatorAfter, collector, types);
                }
                else {
                    // value proposals without schema
                    _this.getSchemaLessValueCompletions(doc, node, offset, separatorAfter, document, collector);
                }
                if (!node) {
                    _this.contributions.forEach(function (contribution) {
                        var collectPromise = contribution.collectDefaultCompletions(document.uri, collector);
                        if (collectPromise) {
                            collectionPromises.push(collectPromise);
                        }
                    });
                }
                else {
                    if ((node.type === 'property') && offset > node.colonOffset) {
                        var parentKey_1 = node.key.value;
                        var valueNode = node.value;
                        if (!valueNode || offset <= valueNode.end) {
                            var location_2 = node.parent.getPath();
                            _this.contributions.forEach(function (contribution) {
                                var collectPromise = contribution.collectValueCompletions(document.uri, location_2, parentKey_1, collector);
                                if (collectPromise) {
                                    collectionPromises.push(collectPromise);
                                }
                            });
                        }
                    }
                }
                return _this.promise.all(collectionPromises).then(function () {
                    if (collector.getNumberOfProposals() === 0) {
                        _this.addFillerValueCompletions(types, separatorAfter, collector);
                    }
                    return result;
                });
            });
        };
        JSONCompletion.prototype.getPropertyCompletions = function (schema, doc, node, addValue, separatorAfter, collector) {
            var _this = this;
            var matchingSchemas = [];
            doc.validate(schema.schema, matchingSchemas, node.start);
            matchingSchemas.forEach(function (s) {
                if (s.node === node && !s.inverted) {
                    var schemaProperties_1 = s.schema.properties;
                    if (schemaProperties_1) {
                        Object.keys(schemaProperties_1).forEach(function (key) {
                            var propertySchema = schemaProperties_1[key];
                            if (!propertySchema.deprecationMessage) {
                                collector.add({
                                    kind: vscode_languageserver_types_1.CompletionItemKind.Property,
                                    label: key,
                                    insertText: _this.getInsertTextForProperty(key, propertySchema, addValue, separatorAfter),
                                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                                    filterText: _this.getFilterTextForValue(key),
                                    documentation: propertySchema.description || ''
                                });
                            }
                        });
                    }
                }
            });
        };
        JSONCompletion.prototype.getSchemaLessPropertyCompletions = function (doc, node, currentKey, collector) {
            var _this = this;
            var collectCompletionsForSimilarObject = function (obj) {
                obj.properties.forEach(function (p) {
                    var key = p.key.value;
                    collector.add({
                        kind: vscode_languageserver_types_1.CompletionItemKind.Property,
                        label: key,
                        insertText: _this.getInsertTextForValue(key, ''),
                        insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                        filterText: _this.getFilterTextForValue(key),
                        documentation: ''
                    });
                });
            };
            if (node.parent) {
                if (node.parent.type === 'property') {
                    // if the object is a property value, check the tree for other objects that hang under a property of the same name
                    var parentKey_2 = node.parent.key.value;
                    doc.visit(function (n) {
                        var p = n;
                        if (n.type === 'property' && n !== node.parent && p.key.value === parentKey_2 && p.value && p.value.type === 'object') {
                            collectCompletionsForSimilarObject(p.value);
                        }
                        return true;
                    });
                }
                else if (node.parent.type === 'array') {
                    // if the object is in an array, use all other array elements as similar objects
                    node.parent.items.forEach(function (n) {
                        if (n.type === 'object' && n !== node) {
                            collectCompletionsForSimilarObject(n);
                        }
                    });
                }
            }
            else if (node.type === 'object') {
                collector.add({
                    kind: vscode_languageserver_types_1.CompletionItemKind.Property,
                    label: '$schema',
                    insertText: this.getInsertTextForProperty('$schema', null, true, ''),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet, documentation: '',
                    filterText: this.getFilterTextForValue("$schema")
                });
            }
        };
        JSONCompletion.prototype.getSchemaLessValueCompletions = function (doc, node, offset, separatorAfter, document, collector) {
            var _this = this;
            var collectSuggestionsForValues = function (value) {
                if (!value.parent.contains(offset, true)) {
                    collector.add({
                        kind: _this.getSuggestionKind(value.type),
                        label: _this.getLabelTextForMatchingNode(value, document),
                        insertText: _this.getInsertTextForMatchingNode(value, document, separatorAfter),
                        insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet, documentation: ''
                    });
                }
                if (value.type === 'boolean') {
                    _this.addBooleanValueCompletion(!value.getValue(), separatorAfter, collector);
                }
            };
            if (!node) {
                collector.add({
                    kind: this.getSuggestionKind('object'),
                    label: 'Empty object',
                    insertText: this.getInsertTextForValue({}, ''),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    documentation: ''
                });
                collector.add({
                    kind: this.getSuggestionKind('array'),
                    label: 'Empty array',
                    insertText: this.getInsertTextForValue([], ''),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    documentation: ''
                });
            }
            else {
                if (node.type === 'property') {
                    var propertyNode = node;
                    if (offset > propertyNode.colonOffset) {
                        var valueNode = propertyNode.value;
                        if (valueNode && (offset > valueNode.end || valueNode.type === 'object' || valueNode.type === 'array')) {
                            return;
                        }
                        // suggest values at the same key
                        var parentKey_3 = propertyNode.key.value;
                        doc.visit(function (n) {
                            var p = n;
                            if (n.type === 'property' && p.key.value === parentKey_3 && p.value) {
                                collectSuggestionsForValues(p.value);
                            }
                            return true;
                        });
                        if (parentKey_3 === '$schema' && node.parent && !node.parent.parent) {
                            this.addDollarSchemaCompletions(separatorAfter, collector);
                        }
                    }
                }
                if (node.type === 'array') {
                    if (node.parent && node.parent.type === 'property') {
                        // suggest items of an array at the same key
                        var parentKey_4 = node.parent.key.value;
                        doc.visit(function (n) {
                            var p = n;
                            if (n.type === 'property' && p.key.value === parentKey_4 && p.value && p.value.type === 'array') {
                                (p.value.items).forEach(function (n) {
                                    collectSuggestionsForValues(n);
                                });
                            }
                            return true;
                        });
                    }
                    else {
                        // suggest items in the same array
                        node.items.forEach(function (n) {
                            collectSuggestionsForValues(n);
                        });
                    }
                }
            }
        };
        JSONCompletion.prototype.getValueCompletions = function (schema, doc, node, offset, separatorAfter, collector, types) {
            var _this = this;
            if (!node) {
                this.addSchemaValueCompletions(schema.schema, '', collector, types);
            }
            else {
                var parentKey_5 = null;
                if ((node.type === 'property') && offset > node.colonOffset) {
                    var valueNode = node.value;
                    if (valueNode && offset > valueNode.end) {
                        return; // we are past the value node
                    }
                    parentKey_5 = node.key.value;
                    node = node.parent;
                }
                if (node && (parentKey_5 !== null || node.type === 'array')) {
                    var matchingSchemas = [];
                    doc.validate(schema.schema, matchingSchemas, node.start);
                    matchingSchemas.forEach(function (s) {
                        if (s.node === node && !s.inverted && s.schema) {
                            if (s.schema.items) {
                                _this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
                            }
                            if (s.schema.properties) {
                                var propertySchema = s.schema.properties[parentKey_5];
                                if (propertySchema) {
                                    _this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
                                }
                            }
                        }
                    });
                    if (parentKey_5 === '$schema' && !node.parent) {
                        this.addDollarSchemaCompletions(separatorAfter, collector);
                    }
                    if (types['boolean']) {
                        this.addBooleanValueCompletion(true, separatorAfter, collector);
                        this.addBooleanValueCompletion(false, separatorAfter, collector);
                    }
                    if (types['null']) {
                        this.addNullValueCompletion(separatorAfter, collector);
                    }
                }
            }
        };
        JSONCompletion.prototype.addSchemaValueCompletions = function (schema, separatorAfter, collector, types) {
            var _this = this;
            this.addDefaultValueCompletions(schema, separatorAfter, collector);
            this.addEnumValueCompletions(schema, separatorAfter, collector);
            this.collectTypes(schema, types);
            if (Array.isArray(schema.allOf)) {
                schema.allOf.forEach(function (s) { return _this.addSchemaValueCompletions(s, separatorAfter, collector, types); });
            }
            if (Array.isArray(schema.anyOf)) {
                schema.anyOf.forEach(function (s) { return _this.addSchemaValueCompletions(s, separatorAfter, collector, types); });
            }
            if (Array.isArray(schema.oneOf)) {
                schema.oneOf.forEach(function (s) { return _this.addSchemaValueCompletions(s, separatorAfter, collector, types); });
            }
        };
        JSONCompletion.prototype.addDefaultValueCompletions = function (schema, separatorAfter, collector, arrayDepth) {
            var _this = this;
            if (arrayDepth === void 0) { arrayDepth = 0; }
            var hasProposals = false;
            if (schema.default) {
                var type = schema.type;
                var value = schema.default;
                for (var i = arrayDepth; i > 0; i--) {
                    value = [value];
                    type = 'array';
                }
                collector.add({
                    kind: this.getSuggestionKind(type),
                    label: this.getLabelForValue(value),
                    insertText: this.getInsertTextForValue(value, separatorAfter),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    detail: localize('json.suggest.default', 'Default value'),
                });
                hasProposals = true;
            }
            if (Array.isArray(schema.defaultSnippets)) {
                schema.defaultSnippets.forEach(function (s) {
                    var type = schema.type;
                    var value = s.body;
                    var label = s.label;
                    var insertText;
                    if (value) {
                        var type_1 = schema.type;
                        for (var i = arrayDepth; i > 0; i--) {
                            value = [value];
                            type_1 = 'array';
                        }
                        insertText = _this.getInsertTextForSnippetValue(value, separatorAfter);
                        label = label || _this.getLabelForSnippetValue(value);
                    }
                    else if (s.bodyText) {
                        var prefix = '', suffix = '', indent = '';
                        for (var i = arrayDepth; i > 0; i--) {
                            prefix = prefix + indent + '[\n';
                            suffix = suffix + '\n' + indent + ']';
                            indent += '\t';
                            type = 'array';
                        }
                        insertText = prefix + indent + s.bodyText.split('\n').join('\n' + indent) + suffix + separatorAfter;
                        label = label || insertText;
                    }
                    collector.add({
                        kind: _this.getSuggestionKind(type),
                        label: label,
                        documentation: s.description,
                        insertText: insertText,
                        insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                        filterText: insertText,
                    });
                    hasProposals = true;
                });
            }
            if (!hasProposals && schema.items && !Array.isArray(schema.items)) {
                this.addDefaultValueCompletions(schema.items, separatorAfter, collector, arrayDepth + 1);
            }
        };
        JSONCompletion.prototype.addEnumValueCompletions = function (schema, separatorAfter, collector) {
            if (Array.isArray(schema.enum)) {
                for (var i = 0, length = schema.enum.length; i < length; i++) {
                    var enm = schema.enum[i];
                    var documentation = schema.description;
                    if (schema.enumDescriptions && i < schema.enumDescriptions.length) {
                        documentation = schema.enumDescriptions[i];
                    }
                    collector.add({
                        kind: this.getSuggestionKind(schema.type),
                        label: this.getLabelForValue(enm),
                        insertText: this.getInsertTextForValue(enm, separatorAfter),
                        insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                        documentation: documentation
                    });
                }
            }
        };
        JSONCompletion.prototype.collectTypes = function (schema, types) {
            var type = schema.type;
            if (Array.isArray(type)) {
                type.forEach(function (t) { return types[t] = true; });
            }
            else {
                types[type] = true;
            }
        };
        JSONCompletion.prototype.addFillerValueCompletions = function (types, separatorAfter, collector) {
            if (types['object']) {
                collector.add({
                    kind: this.getSuggestionKind('object'),
                    label: '{}',
                    insertText: this.getInsertTextForGuessedValue({}, separatorAfter),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    detail: localize('defaults.object', 'New object'),
                    documentation: ''
                });
            }
            if (types['array']) {
                collector.add({
                    kind: this.getSuggestionKind('array'),
                    label: '[]',
                    insertText: this.getInsertTextForGuessedValue([], separatorAfter),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    detail: localize('defaults.array', 'New array'),
                    documentation: ''
                });
            }
        };
        JSONCompletion.prototype.addBooleanValueCompletion = function (value, separatorAfter, collector) {
            collector.add({
                kind: this.getSuggestionKind('boolean'),
                label: value ? 'true' : 'false',
                insertText: this.getInsertTextForValue(value, separatorAfter),
                insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                documentation: ''
            });
        };
        JSONCompletion.prototype.addNullValueCompletion = function (separatorAfter, collector) {
            collector.add({
                kind: this.getSuggestionKind('null'),
                label: 'null',
                insertText: 'null' + separatorAfter,
                insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                documentation: ''
            });
        };
        JSONCompletion.prototype.addDollarSchemaCompletions = function (separatorAfter, collector) {
            var _this = this;
            var schemaIds = this.schemaService.getRegisteredSchemaIds(function (schema) { return schema === 'http' || schema === 'https'; });
            schemaIds.forEach(function (schemaId) { return collector.add({
                kind: vscode_languageserver_types_1.CompletionItemKind.Module,
                label: _this.getLabelForValue(schemaId),
                filterText: JSON.stringify(schemaId),
                insertText: _this.getInsertTextForValue(schemaId, separatorAfter),
                insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet, documentation: ''
            }); });
        };
        JSONCompletion.prototype.getLabelForValue = function (value) {
            var label = JSON.stringify(value);
            if (label.length > 57) {
                return label.substr(0, 57).trim() + '...';
            }
            return label;
        };
        JSONCompletion.prototype.getFilterTextForValue = function (value) {
            return JSON.stringify(value);
        };
        JSONCompletion.prototype.getLabelForSnippetValue = function (value) {
            var label = JSON.stringify(value);
            label = label.replace(/\$\{\d+:([^}]+)\}|\$\d+/g, '$1');
            if (label.length > 57) {
                return label.substr(0, 57).trim() + '...';
            }
            return label;
        };
        JSONCompletion.prototype.getInsertTextForPlainText = function (text) {
            return text.replace(/[\\\$\}]/g, '\\$&'); // escape $, \ and } 
        };
        JSONCompletion.prototype.getInsertTextForValue = function (value, separatorAfter) {
            var text = JSON.stringify(value, null, '\t');
            if (text === '{}') {
                return '{\n\t$1\n}' + separatorAfter;
            }
            else if (text === '[]') {
                return '[\n\t$1\n]' + separatorAfter;
            }
            return this.getInsertTextForPlainText(text + separatorAfter);
        };
        JSONCompletion.prototype.getInsertTextForSnippetValue = function (value, separatorAfter) {
            var replacer = function (value) {
                if (typeof value === 'string') {
                    if (value[0] === '^') {
                        return value.substr(1);
                    }
                }
                return JSON.stringify(value);
            };
            return json_1.stringifyObject(value, '', replacer) + separatorAfter;
        };
        JSONCompletion.prototype.getInsertTextForGuessedValue = function (value, separatorAfter) {
            switch (typeof value) {
                case 'object':
                    if (value === null) {
                        return '${1:null}' + separatorAfter;
                    }
                    return this.getInsertTextForValue(value, separatorAfter);
                case 'string':
                    var snippetValue = JSON.stringify(value);
                    snippetValue = snippetValue.substr(1, snippetValue.length - 2); // remove quotes
                    snippetValue = this.getInsertTextForPlainText(snippetValue); // escape \ and }
                    return '"${1:' + snippetValue + '}"' + separatorAfter;
                case 'number':
                case 'boolean':
                    return '${1:' + JSON.stringify(value) + '}' + separatorAfter;
            }
            return this.getInsertTextForValue(value, separatorAfter);
        };
        JSONCompletion.prototype.getSuggestionKind = function (type) {
            if (Array.isArray(type)) {
                var array = type;
                type = array.length > 0 ? array[0] : null;
            }
            if (!type) {
                return vscode_languageserver_types_1.CompletionItemKind.Value;
            }
            switch (type) {
                case 'string': return vscode_languageserver_types_1.CompletionItemKind.Value;
                case 'object': return vscode_languageserver_types_1.CompletionItemKind.Module;
                case 'property': return vscode_languageserver_types_1.CompletionItemKind.Property;
                default: return vscode_languageserver_types_1.CompletionItemKind.Value;
            }
        };
        JSONCompletion.prototype.getLabelTextForMatchingNode = function (node, document) {
            switch (node.type) {
                case 'array':
                    return '[]';
                case 'object':
                    return '{}';
                default:
                    var content = document.getText().substr(node.start, node.end - node.start);
                    return content;
            }
        };
        JSONCompletion.prototype.getInsertTextForMatchingNode = function (node, document, separatorAfter) {
            switch (node.type) {
                case 'array':
                    return this.getInsertTextForValue([], separatorAfter);
                case 'object':
                    return this.getInsertTextForValue({}, separatorAfter);
                default:
                    var content = document.getText().substr(node.start, node.end - node.start) + separatorAfter;
                    return this.getInsertTextForPlainText(content);
            }
        };
        JSONCompletion.prototype.getInsertTextForProperty = function (key, propertySchema, addValue, separatorAfter) {
            var propertyText = this.getInsertTextForValue(key, '');
            if (!addValue) {
                return propertyText;
            }
            var resultText = propertyText + ': ';
            if (propertySchema) {
                var defaultVal = propertySchema.default;
                if (typeof defaultVal !== 'undefined') {
                    resultText += this.getInsertTextForGuessedValue(defaultVal, '');
                }
                else if (propertySchema.enum && propertySchema.enum.length > 0) {
                    resultText += this.getInsertTextForGuessedValue(propertySchema.enum[0], '');
                }
                else {
                    var type = Array.isArray(propertySchema.type) ? propertySchema.type[0] : propertySchema.type;
                    if (!type) {
                        if (propertySchema.properties) {
                            type = 'object';
                        }
                        else if (propertySchema.items) {
                            type = 'array';
                        }
                    }
                    switch (type) {
                        case 'boolean':
                            resultText += '${1:false}';
                            break;
                        case 'string':
                            resultText += '"$1"';
                            break;
                        case 'object':
                            resultText += '{\n\t$1\n}';
                            break;
                        case 'array':
                            resultText += '[\n\t$1\n]';
                            break;
                        case 'number':
                        case 'integer':
                            resultText += '${1:0}';
                            break;
                        case 'null':
                            resultText += '${1:null}';
                            break;
                        default:
                            return propertyText;
                    }
                }
            }
            else {
                resultText += '$1';
            }
            resultText += separatorAfter;
            return resultText;
        };
        JSONCompletion.prototype.getCurrentWord = function (document, offset) {
            var i = offset - 1;
            var text = document.getText();
            while (i >= 0 && ' \t\n\r\v":{[,]}'.indexOf(text.charAt(i)) === -1) {
                i--;
            }
            return text.substring(i + 1, offset);
        };
        JSONCompletion.prototype.evaluateSeparatorAfter = function (document, offset) {
            var scanner = Json.createScanner(document.getText(), true);
            scanner.setPosition(offset);
            var token = scanner.scan();
            switch (token) {
                case Json.SyntaxKind.CommaToken:
                case Json.SyntaxKind.CloseBraceToken:
                case Json.SyntaxKind.CloseBracketToken:
                case Json.SyntaxKind.EOF:
                    return '';
                default:
                    return ',';
            }
        };
        JSONCompletion.prototype.isInComment = function (document, start, offset) {
            var scanner = Json.createScanner(document.getText(), false);
            scanner.setPosition(start);
            var token = scanner.scan();
            while (token !== Json.SyntaxKind.EOF && (scanner.getTokenOffset() + scanner.getTokenLength() < offset)) {
                token = scanner.scan();
            }
            return (token === Json.SyntaxKind.LineCommentTrivia || token === Json.SyntaxKind.BlockCommentTrivia) && scanner.getTokenOffset() <= offset;
        };
        return JSONCompletion;
    }());
    exports.JSONCompletion = JSONCompletion;
});
//# sourceMappingURL=jsonCompletion.js.map