1
0

loader.js 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549
  1. 'use strict';
  2. var common = require('./common');
  3. var YAMLException = require('./exception');
  4. var Mark = require('./mark');
  5. var NIL = common.NIL;
  6. var SAFE_SCHEMA = require('./schema/safe');
  7. var DEFAULT_SCHEMA = require('./schema/default');
  8. var _hasOwnProperty = Object.prototype.hasOwnProperty;
  9. var KIND_STRING = 'string';
  10. var KIND_ARRAY = 'array';
  11. var KIND_OBJECT = 'object';
  12. var CONTEXT_FLOW_IN = 1;
  13. var CONTEXT_FLOW_OUT = 2;
  14. var CONTEXT_BLOCK_IN = 3;
  15. var CONTEXT_BLOCK_OUT = 4;
  16. var CHOMPING_CLIP = 1;
  17. var CHOMPING_STRIP = 2;
  18. var CHOMPING_KEEP = 3;
  19. var CHAR_TAB = 0x09; /* Tab */
  20. var CHAR_LINE_FEED = 0x0A; /* LF */
  21. var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */
  22. var CHAR_SPACE = 0x20; /* Space */
  23. var CHAR_EXCLAMATION = 0x21; /* ! */
  24. var CHAR_DOUBLE_QUOTE = 0x22; /* " */
  25. var CHAR_SHARP = 0x23; /* # */
  26. var CHAR_PERCENT = 0x25; /* % */
  27. var CHAR_AMPERSAND = 0x26; /* & */
  28. var CHAR_SINGLE_QUOTE = 0x27; /* ' */
  29. var CHAR_ASTERISK = 0x2A; /* * */
  30. var CHAR_PLUS = 0x2B; /* + */
  31. var CHAR_COMMA = 0x2C; /* , */
  32. var CHAR_MINUS = 0x2D; /* - */
  33. var CHAR_DOT = 0x2E; /* . */
  34. var CHAR_SLASH = 0x2F; /* / */
  35. var CHAR_DIGIT_ZERO = 0x30; /* 0 */
  36. var CHAR_DIGIT_ONE = 0x31; /* 1 */
  37. var CHAR_DIGIT_NINE = 0x39; /* 9 */
  38. var CHAR_COLON = 0x3A; /* : */
  39. var CHAR_LESS_THAN = 0x3C; /* < */
  40. var CHAR_GREATER_THAN = 0x3E; /* > */
  41. var CHAR_QUESTION = 0x3F; /* ? */
  42. var CHAR_COMMERCIAL_AT = 0x40; /* @ */
  43. var CHAR_CAPITAL_A = 0x41; /* A */
  44. var CHAR_CAPITAL_F = 0x46; /* F */
  45. var CHAR_CAPITAL_L = 0x4C; /* L */
  46. var CHAR_CAPITAL_N = 0x4E; /* N */
  47. var CHAR_CAPITAL_P = 0x50; /* P */
  48. var CHAR_CAPITAL_U = 0x55; /* U */
  49. var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */
  50. var CHAR_BACKSLASH = 0x5C; /* \ */
  51. var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
  52. var CHAR_UNDERSCORE = 0x5F; /* _ */
  53. var CHAR_GRAVE_ACCENT = 0x60; /* ` */
  54. var CHAR_SMALL_A = 0x61; /* a */
  55. var CHAR_SMALL_B = 0x62; /* b */
  56. var CHAR_SMALL_E = 0x65; /* e */
  57. var CHAR_SMALL_F = 0x66; /* f */
  58. var CHAR_SMALL_N = 0x6E; /* n */
  59. var CHAR_SMALL_R = 0x72; /* r */
  60. var CHAR_SMALL_T = 0x74; /* t */
  61. var CHAR_SMALL_U = 0x75; /* u */
  62. var CHAR_SMALL_V = 0x76; /* v */
  63. var CHAR_SMALL_X = 0x78; /* x */
  64. var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */
  65. var CHAR_VERTICAL_LINE = 0x7C; /* | */
  66. var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */
  67. var SIMPLE_ESCAPE_SEQUENCES = {};
  68. SIMPLE_ESCAPE_SEQUENCES[CHAR_DIGIT_ZERO] = '\x00';
  69. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_A] = '\x07';
  70. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_B] = '\x08';
  71. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_T] = '\x09';
  72. SIMPLE_ESCAPE_SEQUENCES[CHAR_TAB] = '\x09';
  73. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_N] = '\x0A';
  74. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_V] = '\x0B';
  75. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_F] = '\x0C';
  76. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_R] = '\x0D';
  77. SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_E] = '\x1B';
  78. SIMPLE_ESCAPE_SEQUENCES[CHAR_SPACE] = ' ';
  79. SIMPLE_ESCAPE_SEQUENCES[CHAR_DOUBLE_QUOTE] = '\x22';
  80. SIMPLE_ESCAPE_SEQUENCES[CHAR_SLASH] = '/';
  81. SIMPLE_ESCAPE_SEQUENCES[CHAR_BACKSLASH] = '\x5C';
  82. SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_N] = '\x85';
  83. SIMPLE_ESCAPE_SEQUENCES[CHAR_UNDERSCORE] = '\xA0';
  84. SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_L] = '\u2028';
  85. SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_P] = '\u2029';
  86. var HEXADECIMAL_ESCAPE_SEQUENCES = {};
  87. HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_X] = 2;
  88. HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_U] = 4;
  89. HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_CAPITAL_U] = 8;
  90. var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/;
  91. var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
  92. var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
  93. var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
  94. var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
  95. function loadAll(input, output, options) {
  96. options = options || {};
  97. var filename = options['filename'] || null,
  98. schema = options['schema'] || DEFAULT_SCHEMA,
  99. resolve = options['resolve'] || true,
  100. validate = options['validate'] || true,
  101. strict = options['strict'] || false,
  102. legacy = options['legacy'] || false,
  103. directiveHandlers = {},
  104. implicitTypes = schema.compiledImplicit,
  105. typeMap = schema.compiledTypeMap,
  106. length = input.length,
  107. position = 0,
  108. line = 0,
  109. lineStart = 0,
  110. lineIndent = 0,
  111. character = input.charCodeAt(position),
  112. version,
  113. checkLineBreaks,
  114. tagMap,
  115. anchorMap,
  116. tag,
  117. anchor,
  118. kind,
  119. result;
  120. function generateError(message) {
  121. return new YAMLException(
  122. message,
  123. new Mark(filename, input, position, line, (position - lineStart)));
  124. }
  125. function throwError(message) {
  126. throw generateError(message);
  127. }
  128. function throwWarning(message) {
  129. var error = generateError(message);
  130. if (strict) {
  131. throw error;
  132. } else {
  133. console.warn(error.toString());
  134. }
  135. }
  136. directiveHandlers['YAML'] = function handleYamlDirective(name, args) {
  137. var match, major, minor;
  138. if (null !== version) {
  139. throwError('duplication of %YAML directive');
  140. }
  141. if (1 !== args.length) {
  142. throwError('YAML directive accepts exactly one argument');
  143. }
  144. match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
  145. if (null === match) {
  146. throwError('ill-formed argument of the YAML directive');
  147. }
  148. major = parseInt(match[1], 10);
  149. minor = parseInt(match[2], 10);
  150. if (1 !== major) {
  151. throwError('unacceptable YAML version of the document');
  152. }
  153. version = args[0];
  154. checkLineBreaks = (minor < 2);
  155. if (1 !== minor && 2 !== minor) {
  156. throwWarning('unsupported YAML version of the document');
  157. }
  158. };
  159. directiveHandlers['TAG'] = function handleTagDirective(name, args) {
  160. var handle, prefix;
  161. if (2 !== args.length) {
  162. throwError('TAG directive accepts exactly two arguments');
  163. }
  164. handle = args[0];
  165. prefix = args[1];
  166. if (!PATTERN_TAG_HANDLE.test(handle)) {
  167. throwError('ill-formed tag handle (first argument) of the TAG directive');
  168. }
  169. if (_hasOwnProperty.call(tagMap, handle)) {
  170. throwError('there is a previously declared suffix for "' + handle + '" tag handle');
  171. }
  172. if (!PATTERN_TAG_URI.test(prefix)) {
  173. throwError('ill-formed tag prefix (second argument) of the TAG directive');
  174. }
  175. tagMap[handle] = prefix;
  176. };
  177. function captureSegment(start, end, checkJson) {
  178. var _position, _length, _character, _result;
  179. if (start < end) {
  180. _result = input.slice(start, end);
  181. if (checkJson && validate) {
  182. for (_position = 0, _length = _result.length;
  183. _position < _length;
  184. _position += 1) {
  185. _character = _result.charCodeAt(_position);
  186. if (!(0x09 === _character ||
  187. 0x20 <= _character && _character <= 0x10FFFF)) {
  188. throwError('expected valid JSON character');
  189. }
  190. }
  191. }
  192. result += _result;
  193. }
  194. }
  195. function mergeMappings(destination, source) {
  196. var sourceKeys, key, index, quantity;
  197. if (!common.isObject(source)) {
  198. throwError('cannot merge mappings; the provided source object is unacceptable');
  199. }
  200. sourceKeys = Object.keys(source);
  201. for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
  202. key = sourceKeys[index];
  203. if (!_hasOwnProperty.call(destination, key)) {
  204. destination[key] = source[key];
  205. }
  206. }
  207. }
  208. function storeMappingPair(_result, keyTag, keyNode, valueNode) {
  209. var index, quantity;
  210. keyNode = String(keyNode);
  211. if (null === _result) {
  212. _result = {};
  213. }
  214. if ('tag:yaml.org,2002:merge' === keyTag) {
  215. if (Array.isArray(valueNode)) {
  216. for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
  217. mergeMappings(_result, valueNode[index]);
  218. }
  219. } else {
  220. mergeMappings(_result, valueNode);
  221. }
  222. } else {
  223. _result[keyNode] = valueNode;
  224. }
  225. return _result;
  226. }
  227. function readLineBreak() {
  228. if (CHAR_LINE_FEED === character) {
  229. position += 1;
  230. } else if (CHAR_CARRIAGE_RETURN === character) {
  231. if (CHAR_LINE_FEED === input.charCodeAt(position + 1)) {
  232. position += 2;
  233. } else {
  234. position += 1;
  235. }
  236. } else {
  237. throwError('a line break is expected');
  238. }
  239. line += 1;
  240. lineStart = position;
  241. character = input.charCodeAt(position);
  242. }
  243. function skipSeparationSpace(allowComments, checkIndent) {
  244. var lineBreaks = 0;
  245. while (position < length) {
  246. while (CHAR_SPACE === character || CHAR_TAB === character) {
  247. character = input.charCodeAt(++position);
  248. }
  249. if (allowComments && CHAR_SHARP === character) {
  250. do { character = input.charCodeAt(++position); }
  251. while (position < length &&
  252. CHAR_LINE_FEED !== character &&
  253. CHAR_CARRIAGE_RETURN !== character);
  254. }
  255. if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
  256. readLineBreak();
  257. lineBreaks += 1;
  258. lineIndent = 0;
  259. while (CHAR_SPACE === character) {
  260. lineIndent += 1;
  261. character = input.charCodeAt(++position);
  262. }
  263. if (lineIndent < checkIndent) {
  264. throwWarning('deficient indentation');
  265. }
  266. } else {
  267. break;
  268. }
  269. }
  270. return lineBreaks;
  271. }
  272. function testDocumentSeparator() {
  273. var _position, _character;
  274. if (position === lineStart &&
  275. (CHAR_MINUS === character || CHAR_DOT === character) &&
  276. input.charCodeAt(position + 1) === character &&
  277. input.charCodeAt(position + 2) === character) {
  278. _position = position + 3;
  279. _character = input.charCodeAt(_position);
  280. if (_position >= length ||
  281. CHAR_SPACE === _character ||
  282. CHAR_TAB === _character ||
  283. CHAR_LINE_FEED === _character ||
  284. CHAR_CARRIAGE_RETURN === _character) {
  285. return true;
  286. }
  287. }
  288. return false;
  289. }
  290. function writeFoldedLines(count) {
  291. if (1 === count) {
  292. result += ' ';
  293. } else if (count > 1) {
  294. result += common.repeat('\n', count - 1);
  295. }
  296. }
  297. function readPlainScalar(nodeIndent, withinFlowCollection) {
  298. var preceding,
  299. following,
  300. captureStart,
  301. captureEnd,
  302. hasPendingContent,
  303. _line,
  304. _lineStart,
  305. _lineIndent,
  306. _kind = kind,
  307. _result = result;
  308. if (CHAR_SPACE === character ||
  309. CHAR_TAB === character ||
  310. CHAR_LINE_FEED === character ||
  311. CHAR_CARRIAGE_RETURN === character ||
  312. CHAR_COMMA === character ||
  313. CHAR_LEFT_SQUARE_BRACKET === character ||
  314. CHAR_RIGHT_SQUARE_BRACKET === character ||
  315. CHAR_LEFT_CURLY_BRACKET === character ||
  316. CHAR_RIGHT_CURLY_BRACKET === character ||
  317. CHAR_SHARP === character ||
  318. CHAR_AMPERSAND === character ||
  319. CHAR_ASTERISK === character ||
  320. CHAR_EXCLAMATION === character ||
  321. CHAR_VERTICAL_LINE === character ||
  322. CHAR_GREATER_THAN === character ||
  323. CHAR_SINGLE_QUOTE === character ||
  324. CHAR_DOUBLE_QUOTE === character ||
  325. CHAR_PERCENT === character ||
  326. CHAR_COMMERCIAL_AT === character ||
  327. CHAR_GRAVE_ACCENT === character) {
  328. return false;
  329. }
  330. if (CHAR_QUESTION === character ||
  331. CHAR_MINUS === character) {
  332. following = input.charCodeAt(position + 1);
  333. if (CHAR_SPACE === following ||
  334. CHAR_TAB === following ||
  335. CHAR_LINE_FEED === following ||
  336. CHAR_CARRIAGE_RETURN === following ||
  337. withinFlowCollection &&
  338. (CHAR_COMMA === following ||
  339. CHAR_LEFT_SQUARE_BRACKET === following ||
  340. CHAR_RIGHT_SQUARE_BRACKET === following ||
  341. CHAR_LEFT_CURLY_BRACKET === following ||
  342. CHAR_RIGHT_CURLY_BRACKET === following)) {
  343. return false;
  344. }
  345. }
  346. kind = KIND_STRING;
  347. result = '';
  348. captureStart = captureEnd = position;
  349. hasPendingContent = false;
  350. while (position < length) {
  351. if (CHAR_COLON === character) {
  352. following = input.charCodeAt(position + 1);
  353. if (CHAR_SPACE === following ||
  354. CHAR_TAB === following ||
  355. CHAR_LINE_FEED === following ||
  356. CHAR_CARRIAGE_RETURN === following ||
  357. withinFlowCollection &&
  358. (CHAR_COMMA === following ||
  359. CHAR_LEFT_SQUARE_BRACKET === following ||
  360. CHAR_RIGHT_SQUARE_BRACKET === following ||
  361. CHAR_LEFT_CURLY_BRACKET === following ||
  362. CHAR_RIGHT_CURLY_BRACKET === following)) {
  363. break;
  364. }
  365. } else if (CHAR_SHARP === character) {
  366. preceding = input.charCodeAt(position - 1);
  367. if (CHAR_SPACE === preceding ||
  368. CHAR_TAB === preceding ||
  369. CHAR_LINE_FEED === preceding ||
  370. CHAR_CARRIAGE_RETURN === preceding) {
  371. break;
  372. }
  373. } else if ((position === lineStart && testDocumentSeparator()) ||
  374. withinFlowCollection &&
  375. (CHAR_COMMA === character ||
  376. CHAR_LEFT_SQUARE_BRACKET === character ||
  377. CHAR_RIGHT_SQUARE_BRACKET === character ||
  378. CHAR_LEFT_CURLY_BRACKET === character ||
  379. CHAR_RIGHT_CURLY_BRACKET === character)) {
  380. break;
  381. } else if (CHAR_LINE_FEED === character ||
  382. CHAR_CARRIAGE_RETURN === character) {
  383. _line = line;
  384. _lineStart = lineStart;
  385. _lineIndent = lineIndent;
  386. skipSeparationSpace(false, -1);
  387. if (lineIndent >= nodeIndent) {
  388. hasPendingContent = true;
  389. continue;
  390. } else {
  391. position = captureEnd;
  392. line = _line;
  393. lineStart = _lineStart;
  394. lineIndent = _lineIndent;
  395. character = input.charCodeAt(position);
  396. break;
  397. }
  398. }
  399. if (hasPendingContent) {
  400. captureSegment(captureStart, captureEnd, false);
  401. writeFoldedLines(line - _line);
  402. captureStart = captureEnd = position;
  403. hasPendingContent = false;
  404. }
  405. if (CHAR_SPACE !== character && CHAR_TAB !== character) {
  406. captureEnd = position + 1;
  407. }
  408. character = input.charCodeAt(++position);
  409. }
  410. captureSegment(captureStart, captureEnd, false);
  411. if (result) {
  412. return true;
  413. } else {
  414. kind = _kind;
  415. result = _result;
  416. return false;
  417. }
  418. }
  419. function readSingleQuotedScalar(nodeIndent) {
  420. var captureStart, captureEnd;
  421. if (CHAR_SINGLE_QUOTE !== character) {
  422. return false;
  423. }
  424. kind = KIND_STRING;
  425. result = '';
  426. character = input.charCodeAt(++position);
  427. captureStart = captureEnd = position;
  428. while (position < length) {
  429. if (CHAR_SINGLE_QUOTE === character) {
  430. captureSegment(captureStart, position, true);
  431. character = input.charCodeAt(++position);
  432. if (CHAR_SINGLE_QUOTE === character) {
  433. captureStart = captureEnd = position;
  434. character = input.charCodeAt(++position);
  435. } else {
  436. return true;
  437. }
  438. } else if (CHAR_LINE_FEED === character ||
  439. CHAR_CARRIAGE_RETURN === character) {
  440. captureSegment(captureStart, captureEnd, true);
  441. writeFoldedLines(skipSeparationSpace(false, nodeIndent));
  442. captureStart = captureEnd = position;
  443. character = input.charCodeAt(position);
  444. } else if (position === lineStart && testDocumentSeparator()) {
  445. throwError('unexpected end of the document within a single quoted scalar');
  446. } else {
  447. character = input.charCodeAt(++position);
  448. captureEnd = position;
  449. }
  450. }
  451. throwError('unexpected end of the stream within a single quoted scalar');
  452. }
  453. function readDoubleQuotedScalar(nodeIndent) {
  454. var captureStart,
  455. captureEnd,
  456. hexLength,
  457. hexIndex,
  458. hexOffset,
  459. hexResult;
  460. if (CHAR_DOUBLE_QUOTE !== character) {
  461. return false;
  462. }
  463. kind = KIND_STRING;
  464. result = '';
  465. character = input.charCodeAt(++position);
  466. captureStart = captureEnd = position;
  467. while (position < length) {
  468. if (CHAR_DOUBLE_QUOTE === character) {
  469. captureSegment(captureStart, position, true);
  470. character = input.charCodeAt(++position);
  471. return true;
  472. } else if (CHAR_BACKSLASH === character) {
  473. captureSegment(captureStart, position, true);
  474. character = input.charCodeAt(++position);
  475. if (CHAR_LINE_FEED === character ||
  476. CHAR_CARRIAGE_RETURN === character) {
  477. skipSeparationSpace(false, nodeIndent);
  478. } else if (SIMPLE_ESCAPE_SEQUENCES[character]) {
  479. result += SIMPLE_ESCAPE_SEQUENCES[character];
  480. character = input.charCodeAt(++position);
  481. } else if (HEXADECIMAL_ESCAPE_SEQUENCES[character]) {
  482. hexLength = HEXADECIMAL_ESCAPE_SEQUENCES[character];
  483. hexResult = 0;
  484. for (hexIndex = 1; hexIndex <= hexLength; hexIndex += 1) {
  485. hexOffset = (hexLength - hexIndex) * 4;
  486. character = input.charCodeAt(++position);
  487. if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) {
  488. hexResult |= (character - CHAR_DIGIT_ZERO) << hexOffset;
  489. } else if (CHAR_CAPITAL_A <= character && character <= CHAR_CAPITAL_F) {
  490. hexResult |= (character - CHAR_CAPITAL_A + 10) << hexOffset;
  491. } else if (CHAR_SMALL_A <= character && character <= CHAR_SMALL_F) {
  492. hexResult |= (character - CHAR_SMALL_A + 10) << hexOffset;
  493. } else {
  494. throwError('expected hexadecimal character');
  495. }
  496. }
  497. result += String.fromCharCode(hexResult);
  498. character = input.charCodeAt(++position);
  499. } else {
  500. throwError('unknown escape sequence');
  501. }
  502. captureStart = captureEnd = position;
  503. } else if (CHAR_LINE_FEED === character ||
  504. CHAR_CARRIAGE_RETURN === character) {
  505. captureSegment(captureStart, captureEnd, true);
  506. writeFoldedLines(skipSeparationSpace(false, nodeIndent));
  507. captureStart = captureEnd = position;
  508. character = input.charCodeAt(position);
  509. } else if (position === lineStart && testDocumentSeparator()) {
  510. throwError('unexpected end of the document within a double quoted scalar');
  511. } else {
  512. character = input.charCodeAt(++position);
  513. captureEnd = position;
  514. }
  515. }
  516. throwError('unexpected end of the stream within a double quoted scalar');
  517. }
  518. function readFlowCollection(nodeIndent) {
  519. var readNext = true,
  520. _line,
  521. _tag = tag,
  522. _result,
  523. following,
  524. terminator,
  525. isPair,
  526. isExplicitPair,
  527. isMapping,
  528. keyNode,
  529. keyTag,
  530. valueNode;
  531. switch (character) {
  532. case CHAR_LEFT_SQUARE_BRACKET:
  533. terminator = CHAR_RIGHT_SQUARE_BRACKET;
  534. isMapping = false;
  535. _result = [];
  536. break;
  537. case CHAR_LEFT_CURLY_BRACKET:
  538. terminator = CHAR_RIGHT_CURLY_BRACKET;
  539. isMapping = true;
  540. _result = {};
  541. break;
  542. default:
  543. return false;
  544. }
  545. if (null !== anchor) {
  546. anchorMap[anchor] = _result;
  547. }
  548. character = input.charCodeAt(++position);
  549. while (position < length) {
  550. skipSeparationSpace(true, nodeIndent);
  551. if (character === terminator) {
  552. character = input.charCodeAt(++position);
  553. tag = _tag;
  554. kind = isMapping ? KIND_OBJECT : KIND_ARRAY;
  555. result = _result;
  556. return true;
  557. } else if (!readNext) {
  558. throwError('missed comma between flow collection entries');
  559. }
  560. keyTag = keyNode = valueNode = null;
  561. isPair = isExplicitPair = false;
  562. if (CHAR_QUESTION === character) {
  563. following = input.charCodeAt(position + 1);
  564. if (CHAR_SPACE === following ||
  565. CHAR_TAB === following ||
  566. CHAR_LINE_FEED === following ||
  567. CHAR_CARRIAGE_RETURN === following) {
  568. isPair = isExplicitPair = true;
  569. position += 1;
  570. character = following;
  571. skipSeparationSpace(true, nodeIndent);
  572. }
  573. }
  574. _line = line;
  575. composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
  576. keyTag = tag;
  577. keyNode = result;
  578. if ((isExplicitPair || line === _line) && CHAR_COLON === character) {
  579. isPair = true;
  580. character = input.charCodeAt(++position);
  581. skipSeparationSpace(true, nodeIndent);
  582. composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true);
  583. valueNode = result;
  584. }
  585. if (isMapping) {
  586. storeMappingPair(_result, keyTag, keyNode, valueNode);
  587. } else if (isPair) {
  588. _result.push(storeMappingPair(null, keyTag, keyNode, valueNode));
  589. } else {
  590. _result.push(keyNode);
  591. }
  592. skipSeparationSpace(true, nodeIndent);
  593. if (CHAR_COMMA === character) {
  594. readNext = true;
  595. character = input.charCodeAt(++position);
  596. } else {
  597. readNext = false;
  598. }
  599. }
  600. throwError('unexpected end of the stream within a flow collection');
  601. }
  602. function readBlockScalar(nodeIndent) {
  603. var captureStart,
  604. folding,
  605. chomping = CHOMPING_CLIP,
  606. detectedIndent = false,
  607. textIndent = nodeIndent,
  608. emptyLines = -1;
  609. switch (character) {
  610. case CHAR_VERTICAL_LINE:
  611. folding = false;
  612. break;
  613. case CHAR_GREATER_THAN:
  614. folding = true;
  615. break;
  616. default:
  617. return false;
  618. }
  619. kind = KIND_STRING;
  620. result = '';
  621. while (position < length) {
  622. character = input.charCodeAt(++position);
  623. if (CHAR_PLUS === character || CHAR_MINUS === character) {
  624. if (CHOMPING_CLIP === chomping) {
  625. chomping = (CHAR_PLUS === character) ? CHOMPING_KEEP : CHOMPING_STRIP;
  626. } else {
  627. throwError('repeat of a chomping mode identifier');
  628. }
  629. } else if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) {
  630. if (CHAR_DIGIT_ZERO === character) {
  631. throwError('bad explicit indentation width of a block scalar; it cannot be less than one');
  632. } else if (!detectedIndent) {
  633. textIndent = nodeIndent + (character - CHAR_DIGIT_ONE);
  634. detectedIndent = true;
  635. } else {
  636. throwError('repeat of an indentation width identifier');
  637. }
  638. } else {
  639. break;
  640. }
  641. }
  642. if (CHAR_SPACE === character || CHAR_TAB === character) {
  643. do { character = input.charCodeAt(++position); }
  644. while (CHAR_SPACE === character || CHAR_TAB === character);
  645. if (CHAR_SHARP === character) {
  646. do { character = input.charCodeAt(++position); }
  647. while (position < length &&
  648. CHAR_LINE_FEED !== character &&
  649. CHAR_CARRIAGE_RETURN !== character);
  650. }
  651. }
  652. while (position < length) {
  653. readLineBreak();
  654. lineIndent = 0;
  655. while ((!detectedIndent || lineIndent < textIndent) &&
  656. (CHAR_SPACE === character)) {
  657. lineIndent += 1;
  658. character = input.charCodeAt(++position);
  659. }
  660. if (!detectedIndent && lineIndent > textIndent) {
  661. textIndent = lineIndent;
  662. }
  663. if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
  664. emptyLines += 1;
  665. continue;
  666. }
  667. // End of the scalar. Perform the chomping.
  668. if (lineIndent < textIndent) {
  669. if (CHOMPING_KEEP === chomping) {
  670. result += common.repeat('\n', emptyLines + 1);
  671. } else if (CHOMPING_CLIP === chomping) {
  672. result += '\n';
  673. }
  674. break;
  675. }
  676. detectedIndent = true;
  677. if (folding) {
  678. if (CHAR_SPACE === character || CHAR_TAB === character) {
  679. result += common.repeat('\n', emptyLines + 1);
  680. emptyLines = 1;
  681. } else if (0 === emptyLines) {
  682. result += ' ';
  683. emptyLines = 0;
  684. } else {
  685. result += common.repeat('\n', emptyLines);
  686. emptyLines = 0;
  687. }
  688. } else {
  689. result += common.repeat('\n', emptyLines + 1);
  690. emptyLines = 0;
  691. }
  692. captureStart = position;
  693. do { character = input.charCodeAt(++position); }
  694. while (position < length &&
  695. CHAR_LINE_FEED !== character &&
  696. CHAR_CARRIAGE_RETURN !== character);
  697. captureSegment(captureStart, position, false);
  698. }
  699. return true;
  700. }
  701. function readBlockSequence(nodeIndent) {
  702. var _line,
  703. _tag = tag,
  704. _result = [],
  705. following,
  706. detected = false;
  707. if (null !== anchor) {
  708. anchorMap[anchor] = _result;
  709. }
  710. while (position < length) {
  711. if (CHAR_MINUS !== character) {
  712. break;
  713. }
  714. following = input.charCodeAt(position + 1);
  715. if (CHAR_SPACE !== following &&
  716. CHAR_TAB !== following &&
  717. CHAR_LINE_FEED !== following &&
  718. CHAR_CARRIAGE_RETURN !== following) {
  719. break;
  720. }
  721. detected = true;
  722. position += 1;
  723. character = following;
  724. if (skipSeparationSpace(true, -1)) {
  725. if (lineIndent <= nodeIndent) {
  726. _result.push(null);
  727. continue;
  728. }
  729. }
  730. _line = line;
  731. composeNode(nodeIndent, CONTEXT_BLOCK_IN, false, true);
  732. _result.push(result);
  733. skipSeparationSpace(true, -1);
  734. if ((line === _line || lineIndent > nodeIndent) && position < length) {
  735. throwError('bad indentation of a sequence entry');
  736. } else if (lineIndent < nodeIndent) {
  737. break;
  738. }
  739. }
  740. if (detected) {
  741. tag = _tag;
  742. kind = KIND_ARRAY;
  743. result = _result;
  744. return true;
  745. } else {
  746. return false;
  747. }
  748. }
  749. function readBlockMapping(nodeIndent) {
  750. var following,
  751. allowCompact,
  752. _line,
  753. _tag = tag,
  754. _result = {},
  755. keyTag = null,
  756. keyNode = null,
  757. valueNode = null,
  758. atExplicitKey = false,
  759. detected = false;
  760. if (null !== anchor) {
  761. anchorMap[anchor] = _result;
  762. }
  763. while (position < length) {
  764. following = input.charCodeAt(position + 1);
  765. _line = line; // Save the current line.
  766. if ((CHAR_QUESTION === character ||
  767. CHAR_COLON === character) &&
  768. (CHAR_SPACE === following ||
  769. CHAR_TAB === following ||
  770. CHAR_LINE_FEED === following ||
  771. CHAR_CARRIAGE_RETURN === following)) {
  772. if (CHAR_QUESTION === character) {
  773. if (atExplicitKey) {
  774. storeMappingPair(_result, keyTag, keyNode, null);
  775. keyTag = keyNode = valueNode = null;
  776. }
  777. detected = true;
  778. atExplicitKey = true;
  779. allowCompact = true;
  780. } else if (atExplicitKey) {
  781. // i.e. CHAR_COLON === character after the explicit key.
  782. atExplicitKey = false;
  783. allowCompact = true;
  784. } else {
  785. throwError('incomplete explicit mapping pair; a key node is missed');
  786. }
  787. position += 1;
  788. character = following;
  789. } else if (composeNode(nodeIndent, CONTEXT_FLOW_OUT, false, true)) {
  790. if (line === _line) {
  791. // TODO: Remove this cycle when the flow readers will consume
  792. // trailing whitespaces like the block readers.
  793. while (CHAR_SPACE === character ||
  794. CHAR_TAB === character) {
  795. character = input.charCodeAt(++position);
  796. }
  797. if (CHAR_COLON === character) {
  798. character = input.charCodeAt(++position);
  799. if (CHAR_SPACE !== character &&
  800. CHAR_TAB !== character &&
  801. CHAR_LINE_FEED !== character &&
  802. CHAR_CARRIAGE_RETURN !== character) {
  803. throwError('a whitespace character is expected after the key-value separator within a block mapping');
  804. }
  805. if (atExplicitKey) {
  806. storeMappingPair(_result, keyTag, keyNode, null);
  807. keyTag = keyNode = valueNode = null;
  808. }
  809. detected = true;
  810. atExplicitKey = false;
  811. allowCompact = false;
  812. keyTag = tag;
  813. keyNode = result;
  814. } else if (detected) {
  815. throwError('can not read an implicit mapping pair; a colon is missed');
  816. } else {
  817. tag = _tag;
  818. return true; // Keep the result of `composeNode`.
  819. }
  820. } else if (detected) {
  821. throwError('can not read a block mapping entry; a multiline key may not be an implicit key');
  822. } else {
  823. tag = _tag;
  824. return true; // Keep the result of `composeNode`.
  825. }
  826. } else {
  827. break;
  828. }
  829. if (line === _line || lineIndent > nodeIndent) {
  830. if (composeNode(nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
  831. if (atExplicitKey) {
  832. keyNode = result;
  833. } else {
  834. valueNode = result;
  835. }
  836. }
  837. if (!atExplicitKey) {
  838. storeMappingPair(_result, keyTag, keyNode, valueNode);
  839. keyTag = keyNode = valueNode = null;
  840. }
  841. // TODO: It is needed only for flow node readers. It should be removed
  842. // when the flow readers will consume trailing whitespaces as well as
  843. // the block readers.
  844. skipSeparationSpace(true, -1);
  845. }
  846. if (lineIndent > nodeIndent && position < length) {
  847. throwError('bad indentation of a mapping entry');
  848. } else if (lineIndent < nodeIndent) {
  849. break;
  850. }
  851. }
  852. if (atExplicitKey) {
  853. storeMappingPair(_result, keyTag, keyNode, null);
  854. }
  855. if (detected) {
  856. tag = _tag;
  857. kind = KIND_OBJECT;
  858. result = _result;
  859. }
  860. return detected;
  861. }
  862. function readTagProperty() {
  863. var _position,
  864. isVerbatim = false,
  865. isNamed = false,
  866. tagHandle,
  867. tagName;
  868. if (CHAR_EXCLAMATION !== character) {
  869. return false;
  870. }
  871. if (null !== tag) {
  872. throwError('duplication of a tag property');
  873. }
  874. character = input.charCodeAt(++position);
  875. if (CHAR_LESS_THAN === character) {
  876. isVerbatim = true;
  877. character = input.charCodeAt(++position);
  878. } else if (CHAR_EXCLAMATION === character) {
  879. isNamed = true;
  880. tagHandle = '!!';
  881. character = input.charCodeAt(++position);
  882. } else {
  883. tagHandle = '!';
  884. }
  885. _position = position;
  886. if (isVerbatim) {
  887. do { character = input.charCodeAt(++position); }
  888. while (position < length && CHAR_GREATER_THAN !== character);
  889. if (position < length) {
  890. tagName = input.slice(_position, position);
  891. character = input.charCodeAt(++position);
  892. } else {
  893. throwError('unexpected end of the stream within a verbatim tag');
  894. }
  895. } else {
  896. while (position < length &&
  897. CHAR_SPACE !== character &&
  898. CHAR_TAB !== character &&
  899. CHAR_LINE_FEED !== character &&
  900. CHAR_CARRIAGE_RETURN !== character) {
  901. if (CHAR_EXCLAMATION === character) {
  902. if (!isNamed) {
  903. tagHandle = input.slice(_position - 1, position + 1);
  904. if (validate && !PATTERN_TAG_HANDLE.test(tagHandle)) {
  905. throwError('named tag handle cannot contain such characters');
  906. }
  907. isNamed = true;
  908. _position = position + 1;
  909. } else {
  910. throwError('tag suffix cannot contain exclamation marks');
  911. }
  912. }
  913. character = input.charCodeAt(++position);
  914. }
  915. tagName = input.slice(_position, position);
  916. if (validate && PATTERN_FLOW_INDICATORS.test(tagName)) {
  917. throwError('tag suffix cannot contain flow indicator characters');
  918. }
  919. }
  920. if (validate && tagName && !PATTERN_TAG_URI.test(tagName)) {
  921. throwError('tag name cannot contain such characters: ' + tagName);
  922. }
  923. if (isVerbatim) {
  924. tag = tagName;
  925. } else if (_hasOwnProperty.call(tagMap, tagHandle)) {
  926. tag = tagMap[tagHandle] + tagName;
  927. } else if ('!' === tagHandle) {
  928. tag = '!' + tagName;
  929. } else if ('!!' === tagHandle) {
  930. tag = 'tag:yaml.org,2002:' + tagName;
  931. } else {
  932. throwError('undeclared tag handle "' + tagHandle + '"');
  933. }
  934. return true;
  935. }
  936. function readAnchorProperty() {
  937. var _position;
  938. if (CHAR_AMPERSAND !== character) {
  939. return false;
  940. }
  941. if (null !== anchor) {
  942. throwError('duplication of an anchor property');
  943. }
  944. character = input.charCodeAt(++position);
  945. _position = position;
  946. while (position < length &&
  947. CHAR_SPACE !== character &&
  948. CHAR_TAB !== character &&
  949. CHAR_LINE_FEED !== character &&
  950. CHAR_CARRIAGE_RETURN !== character &&
  951. CHAR_COMMA !== character &&
  952. CHAR_LEFT_SQUARE_BRACKET !== character &&
  953. CHAR_RIGHT_SQUARE_BRACKET !== character &&
  954. CHAR_LEFT_CURLY_BRACKET !== character &&
  955. CHAR_RIGHT_CURLY_BRACKET !== character) {
  956. character = input.charCodeAt(++position);
  957. }
  958. if (position === _position) {
  959. throwError('name of an anchor node must contain at least one character');
  960. }
  961. anchor = input.slice(_position, position);
  962. return true;
  963. }
  964. function readAlias() {
  965. var _position, alias;
  966. if (CHAR_ASTERISK !== character) {
  967. return false;
  968. }
  969. character = input.charCodeAt(++position);
  970. _position = position;
  971. while (position < length &&
  972. CHAR_SPACE !== character &&
  973. CHAR_TAB !== character &&
  974. CHAR_LINE_FEED !== character &&
  975. CHAR_CARRIAGE_RETURN !== character &&
  976. CHAR_COMMA !== character &&
  977. CHAR_LEFT_SQUARE_BRACKET !== character &&
  978. CHAR_RIGHT_SQUARE_BRACKET !== character &&
  979. CHAR_LEFT_CURLY_BRACKET !== character &&
  980. CHAR_RIGHT_CURLY_BRACKET !== character) {
  981. character = input.charCodeAt(++position);
  982. }
  983. if (position === _position) {
  984. throwError('name of an alias node must contain at least one character');
  985. }
  986. alias = input.slice(_position, position);
  987. if (!anchorMap.hasOwnProperty(alias)) {
  988. throwError('unidentified alias "' + alias + '"');
  989. }
  990. result = anchorMap[alias];
  991. skipSeparationSpace(true, -1);
  992. return true;
  993. }
  994. function composeNode(parentIndent, nodeContext, allowToSeek, allowCompact) {
  995. var allowBlockStyles,
  996. allowBlockScalars,
  997. allowBlockCollections,
  998. atNewLine = false,
  999. isIndented = true,
  1000. hasContent = false,
  1001. typeIndex,
  1002. typeQuantity,
  1003. type,
  1004. typeLoader,
  1005. flowIndent,
  1006. blockIndent,
  1007. _result;
  1008. tag = null;
  1009. anchor = null;
  1010. kind = null;
  1011. result = null;
  1012. allowBlockStyles = allowBlockScalars = allowBlockCollections =
  1013. CONTEXT_BLOCK_OUT === nodeContext ||
  1014. CONTEXT_BLOCK_IN === nodeContext;
  1015. if (allowToSeek) {
  1016. if (skipSeparationSpace(true, -1)) {
  1017. atNewLine = true;
  1018. if (lineIndent === parentIndent) {
  1019. isIndented = false;
  1020. } else if (lineIndent > parentIndent) {
  1021. isIndented = true;
  1022. } else {
  1023. return false;
  1024. }
  1025. }
  1026. }
  1027. if (isIndented) {
  1028. while (readTagProperty() || readAnchorProperty()) {
  1029. if (skipSeparationSpace(true, -1)) {
  1030. atNewLine = true;
  1031. if (lineIndent > parentIndent) {
  1032. isIndented = true;
  1033. allowBlockCollections = allowBlockStyles;
  1034. } else if (lineIndent === parentIndent) {
  1035. isIndented = false;
  1036. allowBlockCollections = allowBlockStyles;
  1037. } else {
  1038. return true;
  1039. }
  1040. } else {
  1041. allowBlockCollections = false;
  1042. }
  1043. }
  1044. }
  1045. if (allowBlockCollections) {
  1046. allowBlockCollections = atNewLine || allowCompact;
  1047. }
  1048. if (isIndented || CONTEXT_BLOCK_OUT === nodeContext) {
  1049. if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
  1050. flowIndent = parentIndent;
  1051. } else {
  1052. flowIndent = parentIndent + 1;
  1053. }
  1054. blockIndent = position - lineStart;
  1055. if (isIndented) {
  1056. if (allowBlockCollections &&
  1057. (readBlockSequence(blockIndent) ||
  1058. readBlockMapping(blockIndent)) ||
  1059. readFlowCollection(flowIndent)) {
  1060. hasContent = true;
  1061. } else {
  1062. if ((allowBlockScalars && readBlockScalar(flowIndent)) ||
  1063. readSingleQuotedScalar(flowIndent) ||
  1064. readDoubleQuotedScalar(flowIndent)) {
  1065. hasContent = true;
  1066. } else if (readAlias()) {
  1067. hasContent = true;
  1068. if (null !== tag || null !== anchor) {
  1069. throwError('alias node should not have any properties');
  1070. }
  1071. } else if (readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
  1072. hasContent = true;
  1073. if (null === tag) {
  1074. tag = '?';
  1075. }
  1076. }
  1077. if (null !== anchor) {
  1078. anchorMap[anchor] = result;
  1079. }
  1080. }
  1081. } else {
  1082. hasContent = allowBlockCollections && readBlockSequence(blockIndent);
  1083. }
  1084. }
  1085. if (null !== tag && '!' !== tag) {
  1086. if ('?' === tag) {
  1087. if (resolve) {
  1088. for (typeIndex = 0, typeQuantity = implicitTypes.length;
  1089. typeIndex < typeQuantity;
  1090. typeIndex += 1) {
  1091. type = implicitTypes[typeIndex];
  1092. // Implicit resolving is not allowed for non-scalar types, and '?'
  1093. // non-specific tag is only assigned to plain scalars. So, it isn't
  1094. // needed to check for 'kind' conformity.
  1095. _result = type.loader.resolver(result, false);
  1096. if (NIL !== _result) {
  1097. tag = type.tag;
  1098. result = _result;
  1099. break;
  1100. }
  1101. }
  1102. }
  1103. } else if (_hasOwnProperty.call(typeMap, tag)) {
  1104. typeLoader = typeMap[tag].loader;
  1105. if (null !== result && typeLoader.kind !== kind) {
  1106. throwError('unacceptable node kind for !<' + tag + '> tag; it should be "' + typeLoader.kind + '", not "' + kind + '"');
  1107. }
  1108. if (typeLoader.resolver) {
  1109. _result = typeLoader.resolver(result, true);
  1110. if (NIL !== _result) {
  1111. result = _result;
  1112. } else {
  1113. throwError('cannot resolve a node with !<' + tag + '> explicit tag');
  1114. }
  1115. }
  1116. } else {
  1117. throwWarning('unknown tag !<' + tag + '>');
  1118. }
  1119. }
  1120. return null !== tag || null !== anchor || hasContent;
  1121. }
  1122. function readDocument() {
  1123. var documentStart = position,
  1124. _position,
  1125. directiveName,
  1126. directiveArgs,
  1127. hasDirectives = false;
  1128. version = null;
  1129. checkLineBreaks = legacy;
  1130. tagMap = {};
  1131. anchorMap = {};
  1132. while (position < length) {
  1133. skipSeparationSpace(true, -1);
  1134. if (lineIndent > 0 || CHAR_PERCENT !== character) {
  1135. break;
  1136. }
  1137. hasDirectives = true;
  1138. character = input.charCodeAt(++position);
  1139. _position = position;
  1140. while (position < length &&
  1141. CHAR_SPACE !== character &&
  1142. CHAR_TAB !== character &&
  1143. CHAR_LINE_FEED !== character &&
  1144. CHAR_CARRIAGE_RETURN !== character) {
  1145. character = input.charCodeAt(++position);
  1146. }
  1147. directiveName = input.slice(_position, position);
  1148. directiveArgs = [];
  1149. if (directiveName.length < 1) {
  1150. throwError('directive name must not be less than one character in length');
  1151. }
  1152. while (position < length) {
  1153. while (CHAR_SPACE === character || CHAR_TAB === character) {
  1154. character = input.charCodeAt(++position);
  1155. }
  1156. if (CHAR_SHARP === character) {
  1157. do { character = input.charCodeAt(++position); }
  1158. while (position < length &&
  1159. CHAR_LINE_FEED !== character &&
  1160. CHAR_CARRIAGE_RETURN !== character);
  1161. break;
  1162. }
  1163. if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) {
  1164. break;
  1165. }
  1166. _position = position;
  1167. while (position < length &&
  1168. CHAR_SPACE !== character &&
  1169. CHAR_TAB !== character &&
  1170. CHAR_LINE_FEED !== character &&
  1171. CHAR_CARRIAGE_RETURN !== character) {
  1172. character = input.charCodeAt(++position);
  1173. }
  1174. directiveArgs.push(input.slice(_position, position));
  1175. }
  1176. if (position < length) {
  1177. readLineBreak();
  1178. }
  1179. if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
  1180. directiveHandlers[directiveName](directiveName, directiveArgs);
  1181. } else {
  1182. throwWarning('unknown document directive "' + directiveName + '"');
  1183. }
  1184. }
  1185. skipSeparationSpace(true, -1);
  1186. if (0 === lineIndent &&
  1187. CHAR_MINUS === character &&
  1188. CHAR_MINUS === input.charCodeAt(position + 1) &&
  1189. CHAR_MINUS === input.charCodeAt(position + 2)) {
  1190. position += 3;
  1191. character = input.charCodeAt(position);
  1192. skipSeparationSpace(true, -1);
  1193. } else if (hasDirectives) {
  1194. throwError('directives end mark is expected');
  1195. }
  1196. composeNode(lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
  1197. skipSeparationSpace(true, -1);
  1198. if (validate && checkLineBreaks &&
  1199. PATTERN_NON_ASCII_LINE_BREAKS.test(input.slice(documentStart, position))) {
  1200. throwWarning('non-ASCII line breaks are interpreted as content');
  1201. }
  1202. output(result);
  1203. if (position === lineStart && testDocumentSeparator()) {
  1204. if (CHAR_DOT === character) {
  1205. position += 3;
  1206. character = input.charCodeAt(position);
  1207. skipSeparationSpace(true, -1);
  1208. }
  1209. return;
  1210. }
  1211. if (position < length) {
  1212. throwError('end of the stream or a document separator is expected');
  1213. } else {
  1214. return;
  1215. }
  1216. }
  1217. if (validate && PATTERN_NON_PRINTABLE.test(input)) {
  1218. throwError('the stream contains non-printable characters');
  1219. }
  1220. while (CHAR_SPACE === character) {
  1221. lineIndent += 1;
  1222. character = input.charCodeAt(++position);
  1223. }
  1224. while (position < length) {
  1225. readDocument();
  1226. }
  1227. }
  1228. function load(input, options) {
  1229. var result = null, received = false;
  1230. function callback(data) {
  1231. if (!received) {
  1232. result = data;
  1233. received = true;
  1234. } else {
  1235. throw new YAMLException('expected a single document in the stream, but found more');
  1236. }
  1237. }
  1238. loadAll(input, callback, options);
  1239. return result;
  1240. }
  1241. function safeLoadAll(input, output, options) {
  1242. loadAll(input, output, common.extend({ schema: SAFE_SCHEMA }, options));
  1243. }
  1244. function safeLoad(input, options) {
  1245. return load(input, common.extend({ schema: SAFE_SCHEMA }, options));
  1246. }
  1247. module.exports.loadAll = loadAll;
  1248. module.exports.load = load;
  1249. module.exports.safeLoadAll = safeLoadAll;
  1250. module.exports.safeLoad = safeLoad;