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