[d565449] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | /*eslint-disable max-len*/
|
---|
| 4 |
|
---|
| 5 | var YAMLException = require('./exception');
|
---|
| 6 | var Type = require('./type');
|
---|
| 7 |
|
---|
| 8 |
|
---|
| 9 | function compileList(schema, name) {
|
---|
| 10 | var result = [];
|
---|
| 11 |
|
---|
| 12 | schema[name].forEach(function (currentType) {
|
---|
| 13 | var newIndex = result.length;
|
---|
| 14 |
|
---|
| 15 | result.forEach(function (previousType, previousIndex) {
|
---|
| 16 | if (previousType.tag === currentType.tag &&
|
---|
| 17 | previousType.kind === currentType.kind &&
|
---|
| 18 | previousType.multi === currentType.multi) {
|
---|
| 19 |
|
---|
| 20 | newIndex = previousIndex;
|
---|
| 21 | }
|
---|
| 22 | });
|
---|
| 23 |
|
---|
| 24 | result[newIndex] = currentType;
|
---|
| 25 | });
|
---|
| 26 |
|
---|
| 27 | return result;
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 |
|
---|
| 31 | function compileMap(/* lists... */) {
|
---|
| 32 | var result = {
|
---|
| 33 | scalar: {},
|
---|
| 34 | sequence: {},
|
---|
| 35 | mapping: {},
|
---|
| 36 | fallback: {},
|
---|
| 37 | multi: {
|
---|
| 38 | scalar: [],
|
---|
| 39 | sequence: [],
|
---|
| 40 | mapping: [],
|
---|
| 41 | fallback: []
|
---|
| 42 | }
|
---|
| 43 | }, index, length;
|
---|
| 44 |
|
---|
| 45 | function collectType(type) {
|
---|
| 46 | if (type.multi) {
|
---|
| 47 | result.multi[type.kind].push(type);
|
---|
| 48 | result.multi['fallback'].push(type);
|
---|
| 49 | } else {
|
---|
| 50 | result[type.kind][type.tag] = result['fallback'][type.tag] = type;
|
---|
| 51 | }
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | for (index = 0, length = arguments.length; index < length; index += 1) {
|
---|
| 55 | arguments[index].forEach(collectType);
|
---|
| 56 | }
|
---|
| 57 | return result;
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 |
|
---|
| 61 | function Schema(definition) {
|
---|
| 62 | return this.extend(definition);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 |
|
---|
| 66 | Schema.prototype.extend = function extend(definition) {
|
---|
| 67 | var implicit = [];
|
---|
| 68 | var explicit = [];
|
---|
| 69 |
|
---|
| 70 | if (definition instanceof Type) {
|
---|
| 71 | // Schema.extend(type)
|
---|
| 72 | explicit.push(definition);
|
---|
| 73 |
|
---|
| 74 | } else if (Array.isArray(definition)) {
|
---|
| 75 | // Schema.extend([ type1, type2, ... ])
|
---|
| 76 | explicit = explicit.concat(definition);
|
---|
| 77 |
|
---|
| 78 | } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
|
---|
| 79 | // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
|
---|
| 80 | if (definition.implicit) implicit = implicit.concat(definition.implicit);
|
---|
| 81 | if (definition.explicit) explicit = explicit.concat(definition.explicit);
|
---|
| 82 |
|
---|
| 83 | } else {
|
---|
| 84 | throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' +
|
---|
| 85 | 'or a schema definition ({ implicit: [...], explicit: [...] })');
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | implicit.forEach(function (type) {
|
---|
| 89 | if (!(type instanceof Type)) {
|
---|
| 90 | throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | if (type.loadKind && type.loadKind !== 'scalar') {
|
---|
| 94 | throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | if (type.multi) {
|
---|
| 98 | throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');
|
---|
| 99 | }
|
---|
| 100 | });
|
---|
| 101 |
|
---|
| 102 | explicit.forEach(function (type) {
|
---|
| 103 | if (!(type instanceof Type)) {
|
---|
| 104 | throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
|
---|
| 105 | }
|
---|
| 106 | });
|
---|
| 107 |
|
---|
| 108 | var result = Object.create(Schema.prototype);
|
---|
| 109 |
|
---|
| 110 | result.implicit = (this.implicit || []).concat(implicit);
|
---|
| 111 | result.explicit = (this.explicit || []).concat(explicit);
|
---|
| 112 |
|
---|
| 113 | result.compiledImplicit = compileList(result, 'implicit');
|
---|
| 114 | result.compiledExplicit = compileList(result, 'explicit');
|
---|
| 115 | result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
|
---|
| 116 |
|
---|
| 117 | return result;
|
---|
| 118 | };
|
---|
| 119 |
|
---|
| 120 |
|
---|
| 121 | module.exports = Schema;
|
---|