122 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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;
 |