private void Validate(
            ref LiteralToken literal,
            DefinitionInfo definition)
        {
            // Legal
            var literal2 = literal;

            if (definition.Get <ScalarDefinition>().Any(x => x.IsMatch(literal2)))
            {
                return;
            }

            // Not a string, convert
            if (literal.Type != TokenType.String)
            {
                var stringToken = new StringToken(literal.FileId, literal.Line, literal.Column, literal.ToString());

                // Legal
                if (definition.Get <StringDefinition>().Any(x => x.IsMatch(stringToken)))
                {
                    literal = stringToken;
                    return;
                }
            }

            // Illegal
            m_context.Error(literal, TemplateStrings.UnexpectedValue(literal));
        }
예제 #2
0
        private void Validate(
            ref ScalarToken scalar,
            DefinitionInfo definition)
        {
            switch (scalar.Type)
            {
            case TokenType.Null:
            case TokenType.Boolean:
            case TokenType.Number:
            case TokenType.String:
                var literal = scalar as LiteralToken;

                // Legal
                if (definition.Get <ScalarDefinition>().Any(x => x.IsMatch(literal)))
                {
                    return;
                }

                // Not a string, convert
                if (literal.Type != TokenType.String)
                {
                    literal = new StringToken(literal.FileId, literal.Line, literal.Column, literal.ToString());

                    // Legal
                    if (definition.Get <StringDefinition>().Any(x => x.IsMatch(literal)))
                    {
                        scalar = literal;
                        return;
                    }
                }

                // Illegal
                m_context.Error(literal, TemplateStrings.UnexpectedValue(literal));
                break;

            case TokenType.BasicExpression:

                // Illegal
                if (definition.AllowedContext.Length == 0)
                {
                    m_context.Error(scalar, TemplateStrings.ExpressionNotAllowed());
                }

                break;

            default:
                m_context.Error(scalar, TemplateStrings.UnexpectedValue(scalar));
                break;
            }
        }
        private TemplateToken Evaluate(DefinitionInfo definition)
        {
            // Scalar
            if (m_unraveler.AllowScalar(definition.Expand, out ScalarToken scalar))
            {
                if (scalar is LiteralToken literal)
                {
                    Validate(ref literal, definition);
                    return(literal);
                }
                else
                {
                    return(scalar);
                }
            }

            // Sequence start
            if (m_unraveler.AllowSequenceStart(definition.Expand, out SequenceToken sequence))
            {
                var sequenceDefinition = definition.Get <SequenceDefinition>().FirstOrDefault();

                // Legal
                if (sequenceDefinition != null)
                {
                    var itemDefinition = new DefinitionInfo(definition, sequenceDefinition.ItemType);

                    // Add each item
                    while (!m_unraveler.AllowSequenceEnd(definition.Expand))
                    {
                        var item = Evaluate(itemDefinition);
                        sequence.Add(item);
                    }
                }
                // Illegal
                else
                {
                    // Error
                    m_context.Error(sequence, TemplateStrings.UnexpectedSequenceStart());

                    // Skip each item
                    while (!m_unraveler.AllowSequenceEnd(expand: false))
                    {
                        m_unraveler.SkipSequenceItem();
                    }
                }

                return(sequence);
            }

            // Mapping
            if (m_unraveler.AllowMappingStart(definition.Expand, out MappingToken mapping))
            {
                var mappingDefinitions = definition.Get <MappingDefinition>().ToList();

                // Legal
                if (mappingDefinitions.Count > 0)
                {
                    if (mappingDefinitions.Count > 1 ||
                        m_schema.HasProperties(mappingDefinitions[0]) ||
                        String.IsNullOrEmpty(mappingDefinitions[0].LooseKeyType))
                    {
                        HandleMappingWithWellKnownProperties(definition, mappingDefinitions, mapping);
                    }
                    else
                    {
                        var keyDefinition   = new DefinitionInfo(definition, mappingDefinitions[0].LooseKeyType);
                        var valueDefinition = new DefinitionInfo(definition, mappingDefinitions[0].LooseValueType);
                        HandleMappingWithAllLooseProperties(definition, keyDefinition, valueDefinition, mapping);
                    }
                }
                // Illegal
                else
                {
                    m_context.Error(mapping, TemplateStrings.UnexpectedMappingStart());

                    while (!m_unraveler.AllowMappingEnd(expand: false))
                    {
                        m_unraveler.SkipMappingKey();
                        m_unraveler.SkipMappingValue();
                    }
                }

                return(mapping);
            }

            throw new ArgumentException(TemplateStrings.ExpectedScalarSequenceOrMapping());
        }
예제 #4
0
        private TemplateToken ReadValue(DefinitionInfo definition)
        {
            m_memory.IncrementEvents();

            // Scalar
            if (m_objectReader.AllowLiteral(out LiteralToken literal))
            {
                var scalar = ParseScalar(literal, definition.AllowedContext);
                Validate(ref scalar, definition);
                m_memory.AddBytes(scalar);
                return(scalar);
            }

            // Sequence
            if (m_objectReader.AllowSequenceStart(out SequenceToken sequence))
            {
                m_memory.IncrementDepth();
                m_memory.AddBytes(sequence);

                var sequenceDefinition = definition.Get <SequenceDefinition>().FirstOrDefault();

                // Legal
                if (sequenceDefinition != null)
                {
                    var itemDefinition = new DefinitionInfo(definition, sequenceDefinition.ItemType);

                    // Add each item
                    while (!m_objectReader.AllowSequenceEnd())
                    {
                        var item = ReadValue(itemDefinition);
                        sequence.Add(item);
                    }
                }
                // Illegal
                else
                {
                    // Error
                    m_context.Error(sequence, TemplateStrings.UnexpectedSequenceStart());

                    // Skip each item
                    while (!m_objectReader.AllowSequenceEnd())
                    {
                        SkipValue();
                    }
                }

                m_memory.DecrementDepth();
                return(sequence);
            }

            // Mapping
            if (m_objectReader.AllowMappingStart(out MappingToken mapping))
            {
                m_memory.IncrementDepth();
                m_memory.AddBytes(mapping);

                var mappingDefinitions = definition.Get <MappingDefinition>().ToList();

                // Legal
                if (mappingDefinitions.Count > 0)
                {
                    if (mappingDefinitions.Count > 1 ||
                        m_schema.HasProperties(mappingDefinitions[0]) ||
                        String.IsNullOrEmpty(mappingDefinitions[0].LooseKeyType))
                    {
                        HandleMappingWithWellKnownProperties(definition, mappingDefinitions, mapping);
                    }
                    else
                    {
                        var keyDefinition   = new DefinitionInfo(definition, mappingDefinitions[0].LooseKeyType);
                        var valueDefinition = new DefinitionInfo(definition, mappingDefinitions[0].LooseValueType);
                        HandleMappingWithAllLooseProperties(definition, keyDefinition, valueDefinition, mapping);
                    }
                }
                // Illegal
                else
                {
                    m_context.Error(mapping, TemplateStrings.UnexpectedMappingStart());

                    while (!m_objectReader.AllowMappingEnd())
                    {
                        SkipValue();
                        SkipValue();
                    }
                }

                m_memory.DecrementDepth();
                return(mapping);
            }

            throw new InvalidOperationException(TemplateStrings.ExpectedScalarSequenceOrMapping());
        }