massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-json / node_modules / vscode-nls / lib / main.js
1 /* --------------------------------------------------------------------------------------------\r
2  * Copyright (c) Microsoft Corporation. All rights reserved.\r
3  * Licensed under the MIT License. See License.txt in the project root for license information.\r
4  * ------------------------------------------------------------------------------------------ */\r
5 'use strict';\r
6 Object.defineProperty(exports, "__esModule", { value: true });\r
7 var path = require("path");\r
8 var fs = require("fs");\r
9 var toString = Object.prototype.toString;\r
10 function isDefined(value) {\r
11     return typeof value !== 'undefined';\r
12 }\r
13 function isNumber(value) {\r
14     return toString.call(value) === '[object Number]';\r
15 }\r
16 function isString(value) {\r
17     return toString.call(value) === '[object String]';\r
18 }\r
19 function isBoolean(value) {\r
20     return value === true || value === false;\r
21 }\r
22 function readJsonFileSync(filename) {\r
23     return JSON.parse(fs.readFileSync(filename, 'utf8'));\r
24 }\r
25 var MessageFormat;\r
26 (function (MessageFormat) {\r
27     MessageFormat["file"] = "file";\r
28     MessageFormat["bundle"] = "bundle";\r
29     MessageFormat["both"] = "both";\r
30 })(MessageFormat = exports.MessageFormat || (exports.MessageFormat = {}));\r
31 var BundleFormat;\r
32 (function (BundleFormat) {\r
33     // the nls.bundle format\r
34     BundleFormat["standalone"] = "standalone";\r
35     BundleFormat["languagePack"] = "languagePack";\r
36 })(BundleFormat = exports.BundleFormat || (exports.BundleFormat = {}));\r
37 var LocalizeInfo;\r
38 (function (LocalizeInfo) {\r
39     function is(value) {\r
40         var candidate = value;\r
41         return candidate && isDefined(candidate.key) && isDefined(candidate.comment);\r
42     }\r
43     LocalizeInfo.is = is;\r
44 })(LocalizeInfo || (LocalizeInfo = {}));\r
45 var resolvedLanguage;\r
46 var resolvedBundles;\r
47 var options;\r
48 var isPseudo;\r
49 function initializeSettings() {\r
50     options = { locale: undefined, language: undefined, languagePackSupport: false, cacheLanguageResolution: true, messageFormat: MessageFormat.bundle };\r
51     if (isString(process.env.VSCODE_NLS_CONFIG)) {\r
52         try {\r
53             var vscodeOptions_1 = JSON.parse(process.env.VSCODE_NLS_CONFIG);\r
54             var language = void 0;\r
55             var locale = void 0;\r
56             if (vscodeOptions_1.availableLanguages) {\r
57                 var value = vscodeOptions_1.availableLanguages['*'];\r
58                 if (isString(value)) {\r
59                     language = value;\r
60                 }\r
61             }\r
62             if (isString(vscodeOptions_1.locale)) {\r
63                 options.locale = vscodeOptions_1.locale.toLowerCase();\r
64             }\r
65             if (language === undefined) {\r
66                 options.language = options.locale;\r
67             }\r
68             else if (language !== 'en') {\r
69                 options.language = language;\r
70             }\r
71             if (isBoolean(vscodeOptions_1._languagePackSupport)) {\r
72                 options.languagePackSupport = vscodeOptions_1._languagePackSupport;\r
73             }\r
74             if (isString(vscodeOptions_1._cacheRoot)) {\r
75                 options.cacheRoot = vscodeOptions_1._cacheRoot;\r
76             }\r
77             if (isString(vscodeOptions_1._languagePackId)) {\r
78                 options.languagePackId = vscodeOptions_1._languagePackId;\r
79             }\r
80             if (isString(vscodeOptions_1._translationsConfigFile)) {\r
81                 options.translationsConfigFile = vscodeOptions_1._translationsConfigFile;\r
82                 try {\r
83                     options.translationsConfig = readJsonFileSync(options.translationsConfigFile);\r
84                 }\r
85                 catch (error) {\r
86                     // We can't read the translation config file. Mark the cache as corrupted.\r
87                     if (vscodeOptions_1._corruptedFile) {\r
88                         var dirname = path.dirname(vscodeOptions_1._corruptedFile);\r
89                         fs.exists(dirname, function (exists) {\r
90                             if (exists) {\r
91                                 fs.writeFile(vscodeOptions_1._corruptedFile, 'corrupted', 'utf8', function (err) {\r
92                                     console.error(err);\r
93                                 });\r
94                             }\r
95                         });\r
96                     }\r
97                 }\r
98             }\r
99         }\r
100         catch (_a) {\r
101             // Do nothing.\r
102         }\r
103     }\r
104     isPseudo = options.locale === 'pseudo';\r
105     resolvedLanguage = undefined;\r
106     resolvedBundles = Object.create(null);\r
107 }\r
108 initializeSettings();\r
109 function supportsLanguagePack() {\r
110     return options.languagePackSupport === true && options.cacheRoot !== undefined && options.languagePackId !== undefined && options.translationsConfigFile !== undefined\r
111         && options.translationsConfig !== undefined;\r
112 }\r
113 function format(message, args) {\r
114     var result;\r
115     if (isPseudo) {\r
116         // FF3B and FF3D is the Unicode zenkaku representation for [ and ]\r
117         message = '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';\r
118     }\r
119     if (args.length === 0) {\r
120         result = message;\r
121     }\r
122     else {\r
123         result = message.replace(/\{(\d+)\}/g, function (match, rest) {\r
124             var index = rest[0];\r
125             var arg = args[index];\r
126             var replacement = match;\r
127             if (typeof arg === 'string') {\r
128                 replacement = arg;\r
129             }\r
130             else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) {\r
131                 replacement = String(arg);\r
132             }\r
133             return replacement;\r
134         });\r
135     }\r
136     return result;\r
137 }\r
138 function createScopedLocalizeFunction(messages) {\r
139     return function (key, message) {\r
140         var args = [];\r
141         for (var _i = 2; _i < arguments.length; _i++) {\r
142             args[_i - 2] = arguments[_i];\r
143         }\r
144         if (isNumber(key)) {\r
145             if (key >= messages.length) {\r
146                 console.error("Broken localize call found. Index out of bounds. Stacktrace is\n: " + new Error('').stack);\r
147                 return;\r
148             }\r
149             return format(messages[key], args);\r
150         }\r
151         else {\r
152             if (isString(message)) {\r
153                 console.warn("Message " + message + " didn't get externalized correctly.");\r
154                 return format(message, args);\r
155             }\r
156             else {\r
157                 console.error("Broken localize call found. Stacktrace is\n: " + new Error('').stack);\r
158             }\r
159         }\r
160     };\r
161 }\r
162 function localize(key, message) {\r
163     var args = [];\r
164     for (var _i = 2; _i < arguments.length; _i++) {\r
165         args[_i - 2] = arguments[_i];\r
166     }\r
167     return format(message, args);\r
168 }\r
169 function resolveLanguage(file) {\r
170     var resolvedLanguage;\r
171     if (options.cacheLanguageResolution && resolvedLanguage) {\r
172         resolvedLanguage = resolvedLanguage;\r
173     }\r
174     else {\r
175         if (isPseudo || !options.language) {\r
176             resolvedLanguage = '.nls.json';\r
177         }\r
178         else {\r
179             var locale = options.language;\r
180             while (locale) {\r
181                 var candidate = '.nls.' + locale + '.json';\r
182                 if (fs.existsSync(file + candidate)) {\r
183                     resolvedLanguage = candidate;\r
184                     break;\r
185                 }\r
186                 else {\r
187                     var index = locale.lastIndexOf('-');\r
188                     if (index > 0) {\r
189                         locale = locale.substring(0, index);\r
190                     }\r
191                     else {\r
192                         resolvedLanguage = '.nls.json';\r
193                         locale = null;\r
194                     }\r
195                 }\r
196             }\r
197         }\r
198         if (options.cacheLanguageResolution) {\r
199             resolvedLanguage = resolvedLanguage;\r
200         }\r
201     }\r
202     return file + resolvedLanguage;\r
203 }\r
204 function findInTheBoxBundle(root) {\r
205     var language = options.language;\r
206     while (language) {\r
207         var candidate = path.join(root, "nls.bundle." + language + ".json");\r
208         if (fs.existsSync(candidate)) {\r
209             return candidate;\r
210         }\r
211         else {\r
212             var index = language.lastIndexOf('-');\r
213             if (index > 0) {\r
214                 language = language.substring(0, index);\r
215             }\r
216             else {\r
217                 language = undefined;\r
218             }\r
219         }\r
220     }\r
221     // Test if we can reslove the default bundle.\r
222     if (language === undefined) {\r
223         var candidate = path.join(root, 'nls.bundle.json');\r
224         if (fs.existsSync(candidate)) {\r
225             return candidate;\r
226         }\r
227     }\r
228     return undefined;\r
229 }\r
230 function mkdir(directory) {\r
231     try {\r
232         fs.mkdirSync(directory);\r
233     }\r
234     catch (err) {\r
235         if (err.code === 'EEXIST') {\r
236             return;\r
237         }\r
238         else if (err.code === 'ENOENT') {\r
239             var parent = path.dirname(directory);\r
240             if (parent !== directory) {\r
241                 mkdir(parent);\r
242                 fs.mkdirSync(directory);\r
243             }\r
244         }\r
245         else {\r
246             throw err;\r
247         }\r
248     }\r
249 }\r
250 function createDefaultNlsBundle(folder) {\r
251     var metaData = readJsonFileSync(path.join(folder, 'nls.metadata.json'));\r
252     var result = Object.create(null);\r
253     for (var module_1 in metaData) {\r
254         var entry = metaData[module_1];\r
255         result[module_1] = entry.messages;\r
256     }\r
257     return result;\r
258 }\r
259 function createNLSBundle(header, metaDataPath) {\r
260     var languagePackLocation = options.translationsConfig[header.id];\r
261     if (!languagePackLocation) {\r
262         return undefined;\r
263     }\r
264     var languagePack = readJsonFileSync(languagePackLocation).contents;\r
265     var metaData = readJsonFileSync(path.join(metaDataPath, 'nls.metadata.json'));\r
266     var result = Object.create(null);\r
267     for (var module_2 in metaData) {\r
268         var entry = metaData[module_2];\r
269         var translations = languagePack[header.outDir + "/" + module_2];\r
270         if (translations) {\r
271             var resultMessages = [];\r
272             for (var i = 0; i < entry.keys.length; i++) {\r
273                 var messageKey = entry.keys[i];\r
274                 var key = isString(messageKey) ? messageKey : messageKey.key;\r
275                 var translatedMessage = translations[key];\r
276                 if (translatedMessage === undefined) {\r
277                     translatedMessage = entry.messages[i];\r
278                 }\r
279                 resultMessages.push(translatedMessage);\r
280             }\r
281             result[module_2] = resultMessages;\r
282         }\r
283         else {\r
284             result[module_2] = entry.messages;\r
285         }\r
286     }\r
287     return result;\r
288 }\r
289 function touch(file) {\r
290     var d = new Date();\r
291     fs.utimes(file, d, d, function () {\r
292         // Do nothing. Ignore\r
293     });\r
294 }\r
295 function cacheBundle(key, bundle) {\r
296     resolvedBundles[key] = bundle;\r
297     return bundle;\r
298 }\r
299 function loadNlsBundleOrCreateFromI18n(header, bundlePath) {\r
300     var result;\r
301     var bundle = path.join(options.cacheRoot, header.id + "-" + header.hash + ".json");\r
302     var useMemoryOnly = false;\r
303     var writeBundle = false;\r
304     try {\r
305         result = JSON.parse(fs.readFileSync(bundle, { encoding: 'utf8', flag: 'r' }));\r
306         touch(bundle);\r
307         return result;\r
308     }\r
309     catch (err) {\r
310         if (err.code === 'ENOENT') {\r
311             writeBundle = true;\r
312         }\r
313         else if (err instanceof SyntaxError) {\r
314             // We have a syntax error. So no valid JSON. Use\r
315             console.log("Syntax error parsing message bundle: " + err.message + ".");\r
316             fs.unlink(bundle, function (err) {\r
317                 if (err) {\r
318                     console.error("Deleting corrupted bundle " + bundle + " failed.");\r
319                 }\r
320             });\r
321             useMemoryOnly = true;\r
322         }\r
323         else {\r
324             throw err;\r
325         }\r
326     }\r
327     result = createNLSBundle(header, bundlePath);\r
328     if (!result || useMemoryOnly) {\r
329         return result;\r
330     }\r
331     if (writeBundle) {\r
332         try {\r
333             fs.writeFileSync(bundle, JSON.stringify(result), { encoding: 'utf8', flag: 'wx' });\r
334         }\r
335         catch (err) {\r
336             if (err.code === 'EEXIST') {\r
337                 return result;\r
338             }\r
339             throw err;\r
340         }\r
341     }\r
342     return result;\r
343 }\r
344 function loadDefaultNlsBundle(bundlePath) {\r
345     try {\r
346         return createDefaultNlsBundle(bundlePath);\r
347     }\r
348     catch (err) {\r
349         console.log("Generating default bundle from meta data failed.", err);\r
350         return undefined;\r
351     }\r
352 }\r
353 function loadNlsBundle(header, bundlePath) {\r
354     var result;\r
355     // Core decided to use a language pack. Do the same in the extension\r
356     if (supportsLanguagePack()) {\r
357         try {\r
358             result = loadNlsBundleOrCreateFromI18n(header, bundlePath);\r
359         }\r
360         catch (err) {\r
361             console.log("Load or create bundle failed ", err);\r
362         }\r
363     }\r
364     if (!result) {\r
365         // No language pack found, but core is running in language pack mode\r
366         // Don't try to use old in the box bundles since the might be stale\r
367         // Fall right back to the default bundle.\r
368         if (options.languagePackSupport) {\r
369             return loadDefaultNlsBundle(bundlePath);\r
370         }\r
371         var candidate = findInTheBoxBundle(bundlePath);\r
372         if (candidate) {\r
373             try {\r
374                 return readJsonFileSync(candidate);\r
375             }\r
376             catch (err) {\r
377                 console.log("Loading in the box message bundle failed.", err);\r
378             }\r
379         }\r
380         result = loadDefaultNlsBundle(bundlePath);\r
381     }\r
382     return result;\r
383 }\r
384 function tryFindMetaDataHeaderFile(file) {\r
385     var result;\r
386     var dirname = path.dirname(file);\r
387     while (true) {\r
388         result = path.join(dirname, 'nls.metadata.header.json');\r
389         if (fs.existsSync(result)) {\r
390             break;\r
391         }\r
392         var parent = path.dirname(dirname);\r
393         if (parent === dirname) {\r
394             result = undefined;\r
395             break;\r
396         }\r
397         else {\r
398             dirname = parent;\r
399         }\r
400     }\r
401     return result;\r
402 }\r
403 function loadMessageBundle(file) {\r
404     if (!file) {\r
405         // No file. We are in dev mode. Return the default\r
406         // localize function.\r
407         return localize;\r
408     }\r
409     // Remove extension since we load json files.\r
410     var ext = path.extname(file);\r
411     if (ext) {\r
412         file = file.substr(0, file.length - ext.length);\r
413     }\r
414     if (options.messageFormat === MessageFormat.both || options.messageFormat === MessageFormat.bundle) {\r
415         var headerFile = tryFindMetaDataHeaderFile(file);\r
416         if (headerFile) {\r
417             var bundlePath = path.dirname(headerFile);\r
418             var bundle = resolvedBundles[bundlePath];\r
419             if (bundle === undefined) {\r
420                 try {\r
421                     var header = JSON.parse(fs.readFileSync(headerFile, 'utf8'));\r
422                     try {\r
423                         var nlsBundle = loadNlsBundle(header, bundlePath);\r
424                         bundle = cacheBundle(bundlePath, nlsBundle ? { header: header, nlsBundle: nlsBundle } : null);\r
425                     }\r
426                     catch (err) {\r
427                         console.error('Failed to load nls bundle', err);\r
428                         bundle = cacheBundle(bundlePath, null);\r
429                     }\r
430                 }\r
431                 catch (err) {\r
432                     console.error('Failed to read header file', err);\r
433                     bundle = cacheBundle(bundlePath, null);\r
434                 }\r
435             }\r
436             if (bundle) {\r
437                 var module_3 = file.substr(bundlePath.length + 1).replace(/\\/g, '/');\r
438                 var messages = bundle.nlsBundle[module_3];\r
439                 if (messages === undefined) {\r
440                     console.error("Messages for file " + file + " not found. See console for details.");\r
441                     return function () {\r
442                         return 'Messages not found.';\r
443                     };\r
444                 }\r
445                 return createScopedLocalizeFunction(messages);\r
446             }\r
447         }\r
448     }\r
449     if (options.messageFormat === MessageFormat.both || options.messageFormat === MessageFormat.file) {\r
450         // Try to load a single file bundle\r
451         try {\r
452             var json = readJsonFileSync(resolveLanguage(file));\r
453             if (Array.isArray(json)) {\r
454                 return createScopedLocalizeFunction(json);\r
455             }\r
456             else {\r
457                 if (isDefined(json.messages) && isDefined(json.keys)) {\r
458                     return createScopedLocalizeFunction(json.messages);\r
459                 }\r
460                 else {\r
461                     console.error("String bundle '" + file + "' uses an unsupported format.");\r
462                     return function () {\r
463                         return 'File bundle has unsupported format. See console for details';\r
464                     };\r
465                 }\r
466             }\r
467         }\r
468         catch (err) {\r
469             if (err.code !== 'ENOENT') {\r
470                 console.error('Failed to load single file bundle', err);\r
471             }\r
472         }\r
473     }\r
474     console.error("Failed to load message bundle for file " + file);\r
475     return function () {\r
476         return 'Failed to load message bundle. See console for details.';\r
477     };\r
478 }\r
479 exports.loadMessageBundle = loadMessageBundle;\r
480 function config(opts) {\r
481     if (opts) {\r
482         if (isString(opts.locale)) {\r
483             options.locale = opts.locale.toLowerCase();\r
484             options.language = options.locale;\r
485             resolvedLanguage = undefined;\r
486             resolvedBundles = Object.create(null);\r
487         }\r
488         if (opts.messageFormat !== undefined) {\r
489             options.messageFormat = opts.messageFormat;\r
490         }\r
491         if (opts.bundleFormat === BundleFormat.standalone && options.languagePackSupport === true) {\r
492             options.languagePackSupport = false;\r
493         }\r
494     }\r
495     isPseudo = options.locale === 'pseudo';\r
496     return loadMessageBundle;\r
497 }\r
498 exports.config = config;\r
499 //# sourceMappingURL=main.js.map