2019-10-10 00:52:42 -04:00
using System ;
using System.Collections.Generic ;
using GitHub.DistributedTask.ObjectTemplating.Tokens ;
namespace GitHub.DistributedTask.ObjectTemplating.Schema
{
internal sealed class MappingDefinition : Definition
{
internal MappingDefinition ( )
{
}
internal MappingDefinition ( MappingToken definition )
: base ( definition )
{
foreach ( var definitionPair in definition )
{
var definitionKey = definitionPair . Key . AssertString ( $"{TemplateConstants.Definition} key" ) ;
switch ( definitionKey . Value )
{
case TemplateConstants . Mapping :
var mapping = definitionPair . Value . AssertMapping ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping}" ) ;
foreach ( var mappingPair in mapping )
{
var mappingKey = mappingPair . Key . AssertString ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping} key" ) ;
switch ( mappingKey . Value )
{
case TemplateConstants . Properties :
var properties = mappingPair . Value . AssertMapping ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping} {TemplateConstants.Properties}" ) ;
foreach ( var propertiesPair in properties )
{
var propertyName = propertiesPair . Key . AssertString ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping} {TemplateConstants.Properties} key" ) ;
2020-03-14 17:54:58 -04:00
Properties . Add ( propertyName . Value , new PropertyValue ( propertiesPair . Value ) ) ;
2019-10-10 00:52:42 -04:00
}
break ;
case TemplateConstants . LooseKeyType :
var looseKeyType = mappingPair . Value . AssertString ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping} {TemplateConstants.LooseKeyType}" ) ;
LooseKeyType = looseKeyType . Value ;
break ;
case TemplateConstants . LooseValueType :
var looseValueType = mappingPair . Value . AssertString ( $"{TemplateConstants.Definition} {TemplateConstants.Mapping} {TemplateConstants.LooseValueType}" ) ;
LooseValueType = looseValueType . Value ;
break ;
default :
definitionKey . AssertUnexpectedValue ( $"{TemplateConstants.Definition} key" ) ;
break ;
}
}
break ;
default :
definitionKey . AssertUnexpectedValue ( $"{TemplateConstants.Definition} key" ) ;
break ;
}
}
}
internal override DefinitionType DefinitionType = > DefinitionType . Mapping ;
internal String Inherits { get ; set ; }
internal String LooseKeyType { get ; set ; }
internal String LooseValueType { get ; set ; }
internal Dictionary < String , PropertyValue > Properties { get ; } = new Dictionary < String , PropertyValue > ( StringComparer . Ordinal ) ;
internal override void Validate (
TemplateSchema schema ,
String name )
{
// Lookup loose key type
if ( ! String . IsNullOrEmpty ( LooseKeyType ) )
{
schema . GetDefinition ( LooseKeyType ) ;
// Lookup loose value type
if ( ! String . IsNullOrEmpty ( LooseValueType ) )
{
schema . GetDefinition ( LooseValueType ) ;
}
else
{
2020-03-14 17:54:58 -04:00
throw new ArgumentException ( $"Property '{TemplateConstants.LooseKeyType}' is defined but '{TemplateConstants.LooseValueType}' is not defined on '{name}'" ) ;
2019-10-10 00:52:42 -04:00
}
}
// Otherwise validate loose value type not be defined
else if ( ! String . IsNullOrEmpty ( LooseValueType ) )
{
throw new ArgumentException ( $"Property '{TemplateConstants.LooseValueType}' is defined but '{TemplateConstants.LooseKeyType}' is not defined" ) ;
}
// Lookup each property
2020-03-14 17:54:58 -04:00
foreach ( var property in Properties )
2019-10-10 00:52:42 -04:00
{
2020-03-14 17:54:58 -04:00
if ( String . IsNullOrEmpty ( property . Value . Type ) )
{
throw new ArgumentException ( $"Type not specified for the '{property.Key}' property on the '{name}' type" ) ;
}
schema . GetDefinition ( property . Value . Type ) ;
2019-10-10 00:52:42 -04:00
}
if ( ! String . IsNullOrEmpty ( Inherits ) )
{
var inherited = schema . GetDefinition ( Inherits ) ;
2020-03-18 12:08:51 -04:00
if ( inherited . ReaderContext . Length > 0 )
2019-10-10 00:52:42 -04:00
{
throw new NotSupportedException ( $"Property '{TemplateConstants.Context}' is not supported on inhertied definitions" ) ;
}
if ( inherited . DefinitionType ! = DefinitionType . Mapping )
{
throw new NotSupportedException ( $"Expected structure of inherited definition to match. Actual '{inherited.DefinitionType}'" ) ;
}
var inheritedMapping = inherited as MappingDefinition ;
if ( ! String . IsNullOrEmpty ( inheritedMapping . Inherits ) )
{
throw new NotSupportedException ( $"Property '{TemplateConstants.Inherits}' is not supported on inherited definition" ) ;
}
if ( ! String . IsNullOrEmpty ( inheritedMapping . LooseKeyType ) )
{
throw new NotSupportedException ( $"Property '{TemplateConstants.LooseKeyType}' is not supported on inherited definition" ) ;
}
if ( ! String . IsNullOrEmpty ( inheritedMapping . LooseValueType ) )
{
throw new NotSupportedException ( $"Property '{TemplateConstants.LooseValueType}' is not supported on inherited definition" ) ;
}
}
}
}
}