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;
|
---|