You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					122 lines
				
				3.3 KiB
			
		
		
			
		
	
	
					122 lines
				
				3.3 KiB
			| 
											3 years ago
										 | 'use strict'; | ||
|  | 
 | ||
|  | /*eslint-disable max-len*/ | ||
|  | 
 | ||
|  | var YAMLException = require('./exception'); | ||
|  | var Type          = require('./type'); | ||
|  | 
 | ||
|  | 
 | ||
|  | function compileList(schema, name) { | ||
|  |   var result = []; | ||
|  | 
 | ||
|  |   schema[name].forEach(function (currentType) { | ||
|  |     var newIndex = result.length; | ||
|  | 
 | ||
|  |     result.forEach(function (previousType, previousIndex) { | ||
|  |       if (previousType.tag === currentType.tag && | ||
|  |           previousType.kind === currentType.kind && | ||
|  |           previousType.multi === currentType.multi) { | ||
|  | 
 | ||
|  |         newIndex = previousIndex; | ||
|  |       } | ||
|  |     }); | ||
|  | 
 | ||
|  |     result[newIndex] = currentType; | ||
|  |   }); | ||
|  | 
 | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | function compileMap(/* lists... */) { | ||
|  |   var result = { | ||
|  |         scalar: {}, | ||
|  |         sequence: {}, | ||
|  |         mapping: {}, | ||
|  |         fallback: {}, | ||
|  |         multi: { | ||
|  |           scalar: [], | ||
|  |           sequence: [], | ||
|  |           mapping: [], | ||
|  |           fallback: [] | ||
|  |         } | ||
|  |       }, index, length; | ||
|  | 
 | ||
|  |   function collectType(type) { | ||
|  |     if (type.multi) { | ||
|  |       result.multi[type.kind].push(type); | ||
|  |       result.multi['fallback'].push(type); | ||
|  |     } else { | ||
|  |       result[type.kind][type.tag] = result['fallback'][type.tag] = type; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   for (index = 0, length = arguments.length; index < length; index += 1) { | ||
|  |     arguments[index].forEach(collectType); | ||
|  |   } | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | function Schema(definition) { | ||
|  |   return this.extend(definition); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | Schema.prototype.extend = function extend(definition) { | ||
|  |   var implicit = []; | ||
|  |   var explicit = []; | ||
|  | 
 | ||
|  |   if (definition instanceof Type) { | ||
|  |     // Schema.extend(type)
 | ||
|  |     explicit.push(definition); | ||
|  | 
 | ||
|  |   } else if (Array.isArray(definition)) { | ||
|  |     // Schema.extend([ type1, type2, ... ])
 | ||
|  |     explicit = explicit.concat(definition); | ||
|  | 
 | ||
|  |   } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { | ||
|  |     // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
 | ||
|  |     if (definition.implicit) implicit = implicit.concat(definition.implicit); | ||
|  |     if (definition.explicit) explicit = explicit.concat(definition.explicit); | ||
|  | 
 | ||
|  |   } else { | ||
|  |     throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' + | ||
|  |       'or a schema definition ({ implicit: [...], explicit: [...] })'); | ||
|  |   } | ||
|  | 
 | ||
|  |   implicit.forEach(function (type) { | ||
|  |     if (!(type instanceof Type)) { | ||
|  |       throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (type.loadKind && type.loadKind !== 'scalar') { | ||
|  |       throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (type.multi) { | ||
|  |       throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); | ||
|  |     } | ||
|  |   }); | ||
|  | 
 | ||
|  |   explicit.forEach(function (type) { | ||
|  |     if (!(type instanceof Type)) { | ||
|  |       throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); | ||
|  |     } | ||
|  |   }); | ||
|  | 
 | ||
|  |   var result = Object.create(Schema.prototype); | ||
|  | 
 | ||
|  |   result.implicit = (this.implicit || []).concat(implicit); | ||
|  |   result.explicit = (this.explicit || []).concat(explicit); | ||
|  | 
 | ||
|  |   result.compiledImplicit = compileList(result, 'implicit'); | ||
|  |   result.compiledExplicit = compileList(result, 'explicit'); | ||
|  |   result.compiledTypeMap  = compileMap(result.compiledImplicit, result.compiledExplicit); | ||
|  | 
 | ||
|  |   return result; | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | module.exports = Schema; |