Ejemplo n.º 1
0
        private static IEnumerable <KeyValuePair <String, PropertyValue> > GetMergedProperties(
            TemplateSchema schema,
            MappingDefinition mapping)
        {
            foreach (var property in mapping.Properties)
            {
                yield return(property);
            }

            if (!String.IsNullOrEmpty(mapping.Inherits))
            {
                var inherited = schema.GetDefinition(mapping.Inherits) as MappingDefinition;

                if (!String.IsNullOrEmpty(inherited.Inherits))
                {
                    throw new NotSupportedException("Multiple levels of inheritance is not supported");
                }

                foreach (var property in inherited.Properties)
                {
                    if (!mapping.Properties.ContainsKey(property.Key))
                    {
                        yield return(property);
                    }
                }
            }
        }
        internal Boolean HasProperties(MappingDefinition definition)
        {
            for (int i = 0; i < 10; i++)
            {
                if (definition.Properties.Count > 0)
                {
                    return(true);
                }

                if (String.IsNullOrEmpty(definition.Inherits))
                {
                    return(false);
                }

                definition = GetDefinition(definition.Inherits) as MappingDefinition;
            }

            throw new InvalidOperationException("Inheritance depth exceeded 10");
        }
        internal Boolean TryGetProperty(
            MappingDefinition definition,
            String name,
            out String type)
        {
            for (int i = 0; i < 10; i++)
            {
                if (definition.Properties.TryGetValue(name, out PropertyValue property))
                {
                    type = property.Type;
                    return(true);
                }

                if (String.IsNullOrEmpty(definition.Inherits))
                {
                    type = default;
                    return(false);
                }

                definition = GetDefinition(definition.Inherits) as MappingDefinition;
            }

            throw new InvalidOperationException("Inheritance depth exceeded 10");
        }
        private TemplateSchema(MappingToken mapping)
        {
            // Add built-in type: null
            var nullDefinition = new NullDefinition();

            Definitions.Add(TemplateConstants.Null, nullDefinition);

            // Add built-in type: boolean
            var booleanDefinition = new BooleanDefinition();

            Definitions.Add(TemplateConstants.Boolean, booleanDefinition);

            // Add built-in type: number
            var numberDefinition = new NumberDefinition();

            Definitions.Add(TemplateConstants.Number, numberDefinition);

            // Add built-in type: string
            var stringDefinition = new StringDefinition();

            Definitions.Add(TemplateConstants.String, stringDefinition);

            // Add built-in type: sequence
            var sequenceDefinition = new SequenceDefinition {
                ItemType = TemplateConstants.Any
            };

            Definitions.Add(TemplateConstants.Sequence, sequenceDefinition);

            // Add built-in type: mapping
            var mappingDefinition = new MappingDefinition {
                LooseKeyType = TemplateConstants.String, LooseValueType = TemplateConstants.Any
            };

            Definitions.Add(TemplateConstants.Mapping, mappingDefinition);

            // Add built-in type: any
            var anyDefinition = new OneOfDefinition();

            anyDefinition.OneOf.Add(TemplateConstants.Null);
            anyDefinition.OneOf.Add(TemplateConstants.Boolean);
            anyDefinition.OneOf.Add(TemplateConstants.Number);
            anyDefinition.OneOf.Add(TemplateConstants.String);
            anyDefinition.OneOf.Add(TemplateConstants.Sequence);
            anyDefinition.OneOf.Add(TemplateConstants.Mapping);
            Definitions.Add(TemplateConstants.Any, anyDefinition);

            if (mapping != null)
            {
                foreach (var pair in mapping)
                {
                    var key = pair.Key.AssertString($"{TemplateConstants.TemplateSchema} key");
                    switch (key.Value)
                    {
                    case TemplateConstants.Version:
                        var version = pair.Value.AssertString(TemplateConstants.Version);
                        Version = version.Value;
                        break;

                    case TemplateConstants.Definitions:
                        var definitions = pair.Value.AssertMapping(TemplateConstants.Definitions);
                        foreach (var definitionsPair in definitions)
                        {
                            var definitionsKey   = definitionsPair.Key.AssertString($"{TemplateConstants.Definitions} key");
                            var definitionsValue = definitionsPair.Value.AssertMapping(TemplateConstants.Definition);
                            var definition       = default(Definition);
                            foreach (var definitionPair in definitionsValue)
                            {
                                var definitionKey = definitionPair.Key.AssertString($"{TemplateConstants.Definition} key");
                                switch (definitionKey.Value)
                                {
                                case TemplateConstants.Null:
                                    definition = new NullDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.Boolean:
                                    definition = new BooleanDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.Number:
                                    definition = new NumberDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.String:
                                    definition = new StringDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.Sequence:
                                    definition = new SequenceDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.Mapping:
                                    definition = new MappingDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.OneOf:
                                    definition = new OneOfDefinition(definitionsValue);
                                    break;

                                case TemplateConstants.Context:
                                case TemplateConstants.Description:
                                    continue;

                                default:
                                    definitionKey.AssertUnexpectedValue("definition mapping key");         // throws
                                    break;
                                }

                                break;
                            }

                            if (definition == null)
                            {
                                throw new ArgumentException($"Unable to determine definition details. Specify the '{TemplateConstants.Structure}' property");
                            }

                            Definitions.Add(definitionsKey.Value, definition);
                        }
                        break;

                    default:
                        key.AssertUnexpectedValue($"{TemplateConstants.TemplateSchema} key");     // throws
                        break;
                    }
                }
            }
        }