"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
// https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
function escapeTypescriptPropertyName(str) {
    return isValidTypescriptIdentifier(str) ? str : JSON.stringify(str);
}
exports.escapeTypescriptPropertyName = escapeTypescriptPropertyName;
// TODO: these are made up lists. check the grammar
var tsKeywords = 'type class interface break case catch continue debugger default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with'.split(' ');
var digitCodesL = "0".charCodeAt(0);
var digitCodesR = "9".charCodeAt(0);
var lowerCaseCodesL = "a".charCodeAt(0);
var lowerCaseCodesR = "z".charCodeAt(0);
var upperCaseCodesL = "A".charCodeAt(0);
var upperCaseCodesR = "Z".charCodeAt(0);
var digitChars = {}; //:boolean[] = []
var validChars = {}; //:boolean[] = []
//for(var i = 0 ; i < 128 ; i++){
//    digitCodes.push(false)
//    validCodes.push(false)
//}
for (var i = digitCodesL, end = digitCodesR; i <= end; i++) {
    digitChars[String.fromCharCode(i)] = true;
    validChars[String.fromCharCode(i)] = true;
}
for (var i = lowerCaseCodesL, end = lowerCaseCodesR; i <= end; i++) {
    validChars[String.fromCharCode(i)] = true;
}
for (var i = upperCaseCodesL, end = upperCaseCodesR; i <= end; i++) {
    validChars[String.fromCharCode(i)] = true;
}
"_ $".split(" ").forEach(function (x) { return validChars[x] = true; });
function isValidTypescriptIdentifier(str) {
    str = str.trim();
    if (str.length == 0) {
        return false;
    }
    if (tsKeywords.indexOf(str) >= 0) {
        return false;
    }
    if (digitChars[str.charAt(0)]) {
        return false;
    }
    for (var i = 0; i < str.length; i++) {
        if (!validChars[str.charAt(i)]) {
            return false;
        }
    }
    return true;
}
exports.isValidTypescriptIdentifier = isValidTypescriptIdentifier;
function escapeToIdentifier(str) {
    str = str.trim();
    var result = '';
    if (str.length > 0 && digitChars[str.charAt(0)]) {
        result += '_';
    }
    for (var i = 0; i < str.length; i++) {
        var ch = str.charAt(i);
        if (validChars[ch]) {
            result += ch;
        }
        else {
            result += '_';
        }
    }
    return result;
}
exports.escapeToIdentifier = escapeToIdentifier;
// Note: this uses ts.formatting which is part of the typescript 1.4 package but is not currently
//       exposed in the public typescript.d.ts. The typings should be exposed in the next release.
function format(text) {
    var options = getDefaultOptions();
    // Parse the source text
    var sourceFile = ts.createSourceFile("file.ts", text, ts.ScriptTarget.Latest, true);
    fixupParentReferences(sourceFile);
    // Get the formatting edits on the input sources
    var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(options), options);
    // Apply the edits on the input code
    return applyEdits(text, edits);
    function getRuleProvider(options) {
        // Share this between multiple formatters using the same options.
        // This represents the bulk of the space the formatter uses.
        var ruleProvider = new ts.formatting.RulesProvider();
        ruleProvider.ensureUpToDate(options);
        return ruleProvider;
    }
    function applyEdits(text, edits) {
        // Apply edits in reverse on the existing text
        var result = text;
        for (var i = edits.length - 1; i >= 0; i--) {
            var change = edits[i];
            var head = result.slice(0, change.span.start);
            var tail = result.slice(change.span.start + change.span.length);
            result = head + change.newText + tail;
        }
        return result;
    }
    function getDefaultOptions() {
        return {
            IndentSize: 4,
            TabSize: 4,
            NewLineCharacter: '\n',
            ConvertTabsToSpaces: true,
            InsertSpaceAfterCommaDelimiter: true,
            InsertSpaceAfterSemicolonInForStatements: true,
            InsertSpaceBeforeAndAfterBinaryOperators: true,
            InsertSpaceAfterKeywordsInControlFlowStatements: true,
            InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
            InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
            PlaceOpenBraceOnNewLineForFunctions: false,
            PlaceOpenBraceOnNewLineForControlBlocks: false
        };
    }
    function fixupParentReferences(sourceFile) {
        var parent = sourceFile;
        function walk(n) {
            n.parent = parent;
            var saveParent = parent;
            parent = n;
            ts.forEachChild(n, walk);
            parent = saveParent;
        }
        ts.forEachChild(sourceFile, walk);
    }
}
exports.format = format;
var typeMap = {
    'string': 'string',
    'integer': 'number',
    'number': 'number',
    'boolean': 'boolean',
    'file': 'string',
    'date': 'string',
    'NumberType': 'number'
};
function ramlType2TSType(ramlType) {
    var tsType = typeMap[ramlType];
    if (!tsType) {
        tsType = 'any';
    }
    return tsType;
}
exports.ramlType2TSType = ramlType2TSType;
function escapeToJavaIdentifier(str) {
    str = escapeToIdentifier(str);
    return exports.javaReservedWords[str] ? str + '_' : str;
}
exports.escapeToJavaIdentifier = escapeToJavaIdentifier;
exports.tsToJavaTypeMap = {
    'number': 'Double',
    'string': 'String',
    'boolean': 'Boolean',
    'any': 'Object'
};
exports.javaReservedWords = {
    "abstract": true,
    "continue": true,
    "for": true,
    "new": true,
    "switch": true,
    "assert": true,
    "default": true,
    "goto": true,
    "package": true,
    "synchronized": true,
    "boolean": true,
    "do": true,
    "if": true,
    "private": true,
    "this": true,
    "break": true,
    "double": true,
    "implements": true,
    "protected": true,
    "throw": true,
    "byte": true,
    "else": true,
    "import": true,
    "public": true,
    "throws": true,
    "case": true,
    "enum": true,
    "instanceof": true,
    "return": true,
    "transient": true,
    "catch": true,
    "extends": true,
    "int": true,
    "short": true,
    "try": true,
    "char": true,
    "final": true,
    "interface": true,
    "static": true,
    "void": true,
    "class": true,
    "finally": true,
    "long": true,
    "strictfp": true,
    "volatile": true,
    "const": true,
    "float": true,
    "native": true,
    "super": true,
    "while": true,
};
//# sourceMappingURL=tsutil.js.map