Ejemplo n.º 1
0
        public void ExpressionLexerShouldThrows()
        {
            // Arrange
            ExpressionLexer lexer = new ExpressionLexer("name='xzg");

            // Act
            lexer.NextToken();                     // move to '='
            Action test = () => lexer.NextToken(); // test 'xzg

            ExceptionAssert.Throws <ODataException>(test, "There is an unterminated string literal at position 9 in 'name='xzg'.");
        }
Ejemplo n.º 2
0
        /// <summary>Reads a $select clause.</summary>
        /// <param name="value">Value to read.</param>
        /// <param name="dataServiceProviderWrapper">The provider wrapper for the service.</param>
        /// <returns>A list of paths, each of which is a list of identifiers.</returns>
        private static IList <IList <string> > SplitSelect(string value, DataServiceProviderWrapper dataServiceProviderWrapper)
        {
            Debug.Assert(!String.IsNullOrEmpty(value), "!String.IsNullOrEmpty(value)");

            List <IList <string> > result      = new List <IList <string> >();
            List <string>          currentPath = null;
            ExpressionLexer        lexer       = new ExpressionLexer(value);

            while (lexer.CurrentToken.Kind != ExpressionTokenKind.End)
            {
                string identifier;
                bool   lastSegment = false;
                if (lexer.CurrentToken.Kind == ExpressionTokenKind.Star)
                {
                    identifier = lexer.CurrentToken.Text;
                    lexer.NextToken();
                    lastSegment = true;
                }
                else
                {
                    identifier = lexer.ReadDottedIdentifier(true /*allowEndWithDotStar*/);
                    bool nameIsContainerQualifed;
                    if (dataServiceProviderWrapper.GetNameFromContainerQualifiedName(identifier, out nameIsContainerQualifed) == "*")
                    {
                        lastSegment = true;
                    }
                }

                if (currentPath == null)
                {
                    currentPath = new List <string>();
                    result.Add(currentPath);
                }

                currentPath.Add(identifier);

                // Check whether we're at the end, whether we're drilling in,
                // or whether we're finishing with this path.
                ExpressionTokenKind tokenId = lexer.CurrentToken.Kind;
                if (tokenId != ExpressionTokenKind.End)
                {
                    if (lastSegment || tokenId != ExpressionTokenKind.Slash)
                    {
                        lexer.ValidateToken(ExpressionTokenKind.Comma);
                        currentPath = null;
                    }

                    lexer.NextToken();
                }
            }

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>Attempts to parse nullable values (only positional values, no name-value pairs) from the specified text.</summary>
        /// <param name='text'>Text to parse (not null).</param>
        /// <param name='values'>After invocation, the parsed skiptoken/etag values as strings.</param>
        /// <returns>
        /// true if the given values were parsed; false if there was a
        /// syntactic error.
        /// </returns>
        /// <remarks>
        /// The returned collection contains only string values. They must be converted later.
        /// </remarks>
        internal static bool TryParseNullableTokens(string text, out IList <object> values)
        {
            Debug.Assert(text != null, "text != null");

            List <object> positionalValues = new List <object>();

            values = positionalValues;

#if ODATALIB
            ExpressionLexer lexer = new ExpressionLexer(text, true, false);
#else
            ExpressionLexer lexer = new ExpressionLexer(text);
#endif
            ExpressionToken currentToken = lexer.CurrentToken;
            if (currentToken.Kind == ExpressionTokenKind.End)
            {
                return(true);
            }

            do
            {
                if (currentToken.IsLiteral)
                {
                    // Positional value.
                    positionalValues.Add(lexer.CurrentToken.Text);
                }
                else
                {
                    return(false);
                }

                // Read the next token. We should be at the end, or find
                // we have a comma followed by something.
                lexer.NextToken();
                currentToken = lexer.CurrentToken;
                if (currentToken.Kind == ExpressionTokenKind.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Kind == ExpressionTokenKind.End)
                    {
                        // Trailing comma.
                        return(false);
                    }
                }
            }while (currentToken.Kind != ExpressionTokenKind.End);

            return(true);
        }
Ejemplo n.º 4
0
        private static List <List <string> > ReadExpandOrSelect(string value, bool select, IDataService dataService)
        {
            List <List <string> > list  = new List <List <string> >();
            List <string>         list2 = null;
            ExpressionLexer       lexer = new ExpressionLexer(value);

            while (lexer.CurrentToken.Id != TokenId.End)
            {
                string text;
                bool   flag = false;
                if (select && (lexer.CurrentToken.Id == TokenId.Star))
                {
                    text = lexer.CurrentToken.Text;
                    lexer.NextToken();
                    flag = true;
                }
                else if (select)
                {
                    bool flag2;
                    text = lexer.ReadDottedIdentifier(true);
                    if (dataService.Provider.GetNameFromContainerQualifiedName(text, out flag2) == "*")
                    {
                        flag = true;
                    }
                }
                else
                {
                    text = lexer.ReadDottedIdentifier(false);
                }
                if (list2 == null)
                {
                    list2 = new List <string> {
                    };
                }
                list2.Add(text);
                TokenId id = lexer.CurrentToken.Id;
                if (id != TokenId.End)
                {
                    if (flag || (id != TokenId.Slash))
                    {
                        lexer.ValidateToken(TokenId.Comma);
                        list2 = null;
                    }
                    lexer.NextToken();
                }
            }
            return(list);
        }
Ejemplo n.º 5
0
        public void ExpressionLexerCanParseEqualStartingExpression()
        {
            // Arrange
            ExpressionLexer lexer = new ExpressionLexer(" = abc");

            // Act
            Assert.Equal(ExpressionTokenKind.Equal, lexer.CurrentToken.Kind);

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind);
            Assert.Equal("abc", lexer.CurrentToken.Text);
            Assert.Equal(3, lexer.CurrentToken.Position);

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind);
        }
Ejemplo n.º 6
0
        public void ShouldThrowWhenIncorrectCharacterAtStart()
        {
            ExpressionLexer lexer     = new ExpressionLexer("#$*@#", false, false);
            Action          nextToken = () => lexer.NextToken();

            nextToken.Throws <ODataException>(ODataErrorStrings.ExpressionLexer_InvalidCharacter("#", "0", "#$*@#"));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Parses parameter alias into token.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The parameter alias token.</returns>
        private static FunctionParameterAliasToken ParseParameterAlias(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");
            FunctionParameterAliasToken ret = new FunctionParameterAliasToken(lexer.CurrentToken.Text);

            lexer.NextToken();
            return(ret);
        }
Ejemplo n.º 8
0
        public void ShouldOutputNextTokenWhenItExists()
        {
            ExpressionLexer lexer = new ExpressionLexer("5", false, false);

            ExpressionToken result = lexer.NextToken();
            result.Kind.Should().Be(ExpressionTokenKind.IntegerLiteral);
            lexer.CurrentToken.Should().Be(result);
            result.Text.Should().Be("5");
        }
Ejemplo n.º 9
0
        public void AdvanceThroughBalancedParentheticalExpressionWorks()
        {
            ExpressionLexer lexer = new ExpressionLexer("(expression)next", moveToFirstToken: true, useSemicolonDelimeter: true, parsingFunctionParameters: false);
            string result = lexer.AdvanceThroughBalancedParentheticalExpression();
            result.Should().Be("(expression)");
            // TODO: the state of the lexer is weird right now, see note in AdvanceThroughBalancedParentheticalExpression.

            lexer.NextToken().Text.Should().Be("next");
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Parses null literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseNullLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");
            Debug.Assert(lexer.CurrentToken.Kind == ExpressionTokenKind.NullLiteral, "this.lexer.CurrentToken.InternalKind == ExpressionTokenKind.NullLiteral");

            LiteralToken result = new LiteralToken(null, lexer.CurrentToken.Text);

            lexer.NextToken();
            return(result);
        }
Ejemplo n.º 11
0
        public void ExpressionLexerCanParseCommaStartingExpression()
        {
            // Arrange
            ExpressionLexer lexer = new ExpressionLexer(" , ,abc");

            // Act
            Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind); // first ,

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind); // second ,

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind);
            Assert.Equal("abc", lexer.CurrentToken.Text);
            Assert.Equal(4, lexer.CurrentToken.Position);

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind);
        }
Ejemplo n.º 12
0
        public void ShouldOutputNextTokenWhenItExists()
        {
            ExpressionLexer lexer = new ExpressionLexer("5", false, false);

            ExpressionToken result = lexer.NextToken();

            Assert.Equal(ExpressionTokenKind.IntegerLiteral, result.Kind);
            Assert.Equal(result, lexer.CurrentToken);
            Assert.Equal("5", result.Text);
        }
Ejemplo n.º 13
0
        private static void ValidateTokenSequence(string expression, bool parsingFunctionParameters, params ExpressionToken[] expectTokens)
        {
            ExpressionLexer l = new ExpressionLexer(expression, moveToFirstToken: true, useSemicolonDelimeter: false, parsingFunctionParameters: parsingFunctionParameters);
            for (int i = 0; i < expectTokens.Length; ++i)
            {
                Assert.Equal(expectTokens[i].Kind, l.CurrentToken.Kind);
                Assert.Equal(expectTokens[i].Text, l.CurrentToken.Text);
                l.NextToken();
            }

            Assert.Equal(ExpressionTokenKind.End, l.CurrentToken.Kind);
        }
Ejemplo n.º 14
0
        private void ValidateLexerException <T>(string expression, string message) where T : Exception
        {
            Action test = () =>
            {
                ExpressionLexer l = new ExpressionLexer(expression);
                while (l.CurrentToken.Kind != ExpressionTokenKind.End)
                {
                    l.NextToken();
                }
            };

            test.ShouldThrow <T>().WithMessage(message);
        }
Ejemplo n.º 15
0
        public void ExpressionLexerCanParseBracketsExpression()
        {
            // Arrange
            ExpressionLexer lexer = new ExpressionLexer("  [ abc ] ");

            // Act
            Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind);
            Assert.Equal("[ abc ]", lexer.CurrentToken.Text);
            Assert.Equal(2, lexer.CurrentToken.Position);

            lexer.NextToken();
            Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind);
        }
Ejemplo n.º 16
0
        private void ValidateTokenSequence(string expression, params ExpressionToken[] expectTokens)
        {
            ExpressionLexer l = new ExpressionLexer(expression);

            for (int i = 0; i < expectTokens.Length; ++i)
            {
                Assert.AreEqual(expectTokens[i].Kind, l.CurrentToken.Kind);
                Assert.AreEqual(expectTokens[i].Text, l.CurrentToken.Text);
                l.NextToken();
            }

            Assert.AreEqual(ExpressionTokenKind.End, l.CurrentToken.Kind);
        }
Ejemplo n.º 17
0
        private static void ValidateLexerException <T>(string expression, string message) where T : Exception
        {
            Action test = () =>
            {
                ExpressionLexer l = new ExpressionLexer(expression, moveToFirstToken: true, useSemicolonDelimiter: false);
                while (l.CurrentToken.Kind != ExpressionTokenKind.End)
                {
                    l.NextToken();
                }
            };

            test.Throws <T>(message);
        }
Ejemplo n.º 18
0
        public void ExpressionLexerShouldParseComplexKeyValuePairs()
        {
            // Arrange
            string          expression = " 123 = true, inOffice = 12345, name = 'abc,''efg' , 瑞갂థ్క= @p";
            ExpressionLexer lexer      = new ExpressionLexer(expression);

            // Act
            Action <string, string, bool> verifyAction = (key, value, hasComma) =>
            {
                Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind);
                Assert.Equal(key, lexer.CurrentToken.Text);

                lexer.NextToken();
                Assert.Equal(ExpressionTokenKind.Equal, lexer.CurrentToken.Kind);

                lexer.NextToken();
                Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind);
                Assert.Equal(value, lexer.CurrentToken.Text);

                lexer.NextToken();
                if (hasComma)
                {
                    Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind);
                    lexer.NextToken();
                }
                else
                {
                    Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind);
                }
            };

            verifyAction("123", "true", true);
            verifyAction("inOffice", "12345", true);
            verifyAction("name", "'abc,''efg'", true);
            verifyAction("瑞갂థ్క", "@p", false);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Parses a literal.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal query token or null if something else was found.</returns>
        internal static LiteralToken TryParseLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");

            switch (lexer.CurrentToken.Kind)
            {
            case ExpressionTokenKind.BooleanLiteral:
            case ExpressionTokenKind.DateLiteral:
            case ExpressionTokenKind.DecimalLiteral:
            case ExpressionTokenKind.StringLiteral:
            case ExpressionTokenKind.Int64Literal:
            case ExpressionTokenKind.IntegerLiteral:
            case ExpressionTokenKind.DoubleLiteral:
            case ExpressionTokenKind.SingleLiteral:
            case ExpressionTokenKind.GuidLiteral:
            case ExpressionTokenKind.BinaryLiteral:
            case ExpressionTokenKind.GeographyLiteral:
            case ExpressionTokenKind.GeometryLiteral:
            case ExpressionTokenKind.QuotedLiteral:
            case ExpressionTokenKind.DurationLiteral:
            case ExpressionTokenKind.TimeOfDayLiteral:
            case ExpressionTokenKind.DateTimeOffsetLiteral:
            case ExpressionTokenKind.CustomTypeLiteral:
                IEdmTypeReference literalEdmTypeReference = lexer.CurrentToken.GetLiteralEdmTypeReference();

                // Why not using EdmTypeReference.FullName? (literalEdmTypeReference.FullName)
                string edmConstantName = GetEdmConstantNames(literalEdmTypeReference);
                return(ParseTypedLiteral(lexer, literalEdmTypeReference, edmConstantName));

            case ExpressionTokenKind.BracketedExpression:
            {
                // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"]  or {...}
                LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text);
                lexer.NextToken();
                return(result);
            }

            case ExpressionTokenKind.NullLiteral:
                return(ParseNullLiteral(lexer));

            default:
                return(null);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <param name="targetTypeReference">Expected type to be parsed.</param>
        /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmTypeReference targetTypeReference, string targetTypeName)
        {
            Debug.Assert(lexer != null, "lexer != null");

            UriLiteralParsingException typeParsingException;
            object targetValue = DefaultUriLiteralParser.Instance.ParseUriStringToType(lexer.CurrentToken.Text, targetTypeReference, out typeParsingException);

            if (targetValue == null)
            {
                string message;

                if (typeParsingException == null)
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText);

                    throw ParseError(message);
                }
                else
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText,
                        typeParsingException.Message);

                    throw ParseError(message, typeParsingException);
                }
            }

            LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text);

            lexer.NextToken();
            return(result);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <param name="targetTypeReference">Expected type to be parsed.</param>
        /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmPrimitiveTypeReference targetTypeReference, string targetTypeName)
        {
            Debug.Assert(lexer != null, "lexer != null");

            object targetValue;
            string reason;

            if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetTypeReference, out targetValue, out reason))
            {
                string message;

                if (reason == null)
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText);
                }
                else
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText,
                        reason);
                }

                throw ParseError(message);
            }

            LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text);

            lexer.NextToken();
            return(result);
        }
Ejemplo n.º 22
0
        // parses $apply aggregate tranformation (.e.g. aggregate(UnitPrice with sum as TotalUnitPrice)
        internal AggregateToken ParseAggregate()
        {
            Debug.Assert(TokenIdentifierIs(ExpressionConstants.KeywordAggregate), "token identifier is aggregate");
            lexer.NextToken();

            // '('
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.OpenParen)
            {
                throw ParseError(ODataErrorStrings.UriQueryExpressionParser_OpenParenExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();

            // series of statements separates by commas
            var statements = new List <AggregateExpressionToken>();

            while (true)
            {
                statements.Add(this.ParseAggregateExpression());

                if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.Comma)
                {
                    break;
                }

                this.lexer.NextToken();
            }

            // ")"
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen)
            {
                throw ParseError(ODataErrorStrings.UriQueryExpressionParser_CloseParenOrCommaExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();

            return(new AggregateToken(statements));
        }
Ejemplo n.º 23
0
 private static void ValidateIdentifierToken(ExpressionLexer lexer, string text)
 {
     Assert.Equal(ExpressionTokenKind.Identifier, lexer.CurrentToken.Kind);
     Assert.Equal(text, lexer.CurrentToken.Text);
     lexer.NextToken();
 }
Ejemplo n.º 24
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     Assert.Equal(kind, lexer.CurrentToken.Kind);
     lexer.NextToken();
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Parses a literal.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal query token or null if something else was found.</returns>
        internal static LiteralToken TryParseLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");

            switch (lexer.CurrentToken.Kind)
            {
                case ExpressionTokenKind.BooleanLiteral:
                case ExpressionTokenKind.DateLiteral:
                case ExpressionTokenKind.DecimalLiteral:
                case ExpressionTokenKind.StringLiteral:
                case ExpressionTokenKind.Int64Literal:
                case ExpressionTokenKind.IntegerLiteral:
                case ExpressionTokenKind.DoubleLiteral:
                case ExpressionTokenKind.SingleLiteral:
                case ExpressionTokenKind.GuidLiteral:
                case ExpressionTokenKind.BinaryLiteral:
                case ExpressionTokenKind.GeographyLiteral:
                case ExpressionTokenKind.GeometryLiteral:
                case ExpressionTokenKind.QuotedLiteral:
                case ExpressionTokenKind.DurationLiteral:
                case ExpressionTokenKind.TimeOfDayLiteral:
                case ExpressionTokenKind.DateTimeOffsetLiteral:
                case ExpressionTokenKind.CustomTypeLiteral:
                    IEdmTypeReference literalEdmTypeReference = lexer.CurrentToken.GetLiteralEdmTypeReference();

                    // Why not using EdmTypeReference.FullName? (literalEdmTypeReference.FullName)
                    string edmConstantName = GetEdmConstantNames(literalEdmTypeReference);
                    return ParseTypedLiteral(lexer, literalEdmTypeReference, edmConstantName);

                case ExpressionTokenKind.BracketedExpression:
                    {
                        // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"]  or {...}
                        LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text);
                        lexer.NextToken();
                        return result;
                    }

                case ExpressionTokenKind.NullLiteral:
                    return ParseNullLiteral(lexer);

                default:
                    return null;
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Parses a literal.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal query token or null if something else was found.</returns>
        internal static LiteralToken TryParseLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");

            switch (lexer.CurrentToken.Kind)
            {
            case ExpressionTokenKind.BooleanLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBoolean(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmBooleanTypeName));

            case ExpressionTokenKind.DateLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDate(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTypeName));

            case ExpressionTokenKind.DateTimeOffsetLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.DateTimeOffset, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTimeOffsetTypeName));

            case ExpressionTokenKind.DurationLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDurationTypeName));

            case ExpressionTokenKind.DecimalLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDecimal(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDecimalTypeName));

            case ExpressionTokenKind.NullLiteral:
                return(ParseNullLiteral(lexer));

            case ExpressionTokenKind.StringLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName));

            case ExpressionTokenKind.Int64Literal:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt64(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt64TypeName));

            case ExpressionTokenKind.IntegerLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt32(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt32TypeName));

            case ExpressionTokenKind.DoubleLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDouble(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDoubleTypeName));

            case ExpressionTokenKind.SingleLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSingle(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmSingleTypeName));

            case ExpressionTokenKind.GuidLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetGuid(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGuidTypeName));

            case ExpressionTokenKind.BinaryLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBinary(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmBinaryTypeName));

            case ExpressionTokenKind.GeographyLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeographyTypeName));

            case ExpressionTokenKind.GeometryLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeometryTypeName));

            case ExpressionTokenKind.QuotedLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName));

            case ExpressionTokenKind.BracketedExpression:
            {
                // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"]  or {...}
                LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text);
                lexer.NextToken();
                return(result);
            }

            case ExpressionTokenKind.TimeOfDayLiteral:
                return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.TimeOfDay, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmTimeOfDayTypeName));

            default:
                return(null);
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <param name="targetTypeReference">Expected type to be parsed.</param>
        /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmTypeReference targetTypeReference, string targetTypeName)
        {
            Debug.Assert(lexer != null, "lexer != null");

            UriLiteralParsingException typeParsingException;
            object targetValue = DefaultUriLiteralParser.Instance.ParseUriStringToType(lexer.CurrentToken.Text, targetTypeReference, out typeParsingException);

            if (targetValue == null)
            {
                string message;

                if (typeParsingException == null)
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText);

                    throw ParseError(message);
                }
                else
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText,
                        typeParsingException.Message);

                    throw ParseError(message, typeParsingException);
                }
            }

            LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text);
            lexer.NextToken();
            return result;
        }
Ejemplo n.º 28
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     lexer.CurrentToken.Kind.Should().Be(kind);
     lexer.NextToken();
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Parses parameter alias into token.
 /// </summary>
 /// <param name="lexer">The lexer to use.</param>
 /// <returns>The parameter alias token.</returns>
 private static FunctionParameterAliasToken ParseParameterAlias(ExpressionLexer lexer)
 {
     Debug.Assert(lexer != null, "lexer != null");
     FunctionParameterAliasToken ret = new FunctionParameterAliasToken(lexer.CurrentToken.Text);
     lexer.NextToken();
     return ret;
 }
Ejemplo n.º 30
0
 private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text)
 {
     Assert.Equal(ExpressionTokenKind.StringLiteral, lexer.CurrentToken.Kind);
     Assert.Equal(text, lexer.CurrentToken.Text);
     lexer.NextToken();
 }
Ejemplo n.º 31
0
 private static void ValidateIdentifierToken(ExpressionLexer lexer, string text)
 {
     lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.Identifier);
     lexer.CurrentToken.Text.Should().Be(text);
     lexer.NextToken();
 }
Ejemplo n.º 32
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     lexer.CurrentToken.Kind.Should().Be(kind);
     lexer.NextToken();
 }
Ejemplo n.º 33
0
        /// <summary>Attempts to parse key values from the specified text.</summary>
        /// <param name='text'>Text to parse (not null).</param>
        /// <param name="allowNamedValues">Set to true if the parser should accept named values
        ///   so syntax like Name='value'. If this is false, the parsing will fail on such constructs.</param>
        /// <param name="allowNull">Set to true if the parser should accept null values.
        ///   If set to false, the parser will fail on null values.</param>
        /// <param name='instance'>After invocation, the parsed key instance.</param>
        /// <returns>
        /// true if the key instance was parsed; false if there was a
        /// syntactic error.
        /// </returns>
        /// <remarks>
        /// The returned instance contains only string values. To get typed values, a call to
        /// <see cref="TryConvertValues"/> is necessary.
        /// </remarks>
        private static bool TryParseFromUri(string text, bool allowNamedValues, bool allowNull, out KeyInstance instance)
        {
            Debug.Assert(text != null, "text != null");

            Dictionary <string, object> namedValues = null;
            List <object> positionalValues          = null;

            ExpressionLexer lexer        = new ExpressionLexer(text);
            Token           currentToken = lexer.CurrentToken;

            if (currentToken.Id == TokenId.End)
            {
                instance = Empty;
                return(true);
            }

            instance = null;
            do
            {
                if (currentToken.Id == TokenId.Identifier && allowNamedValues)
                {
                    // Name-value pair.
                    if (positionalValues != null)
                    {
                        // We cannot mix named and non-named values.
                        return(false);
                    }

                    string identifier = lexer.CurrentToken.GetIdentifier();
                    lexer.NextToken();
                    if (lexer.CurrentToken.Id != TokenId.Equal)
                    {
                        return(false);
                    }

                    lexer.NextToken();
                    if (!lexer.CurrentToken.IsKeyValueToken)
                    {
                        return(false);
                    }

                    string namedValue = lexer.CurrentToken.Text;
                    WebUtil.CreateIfNull(ref namedValues);
                    if (namedValues.ContainsKey(identifier))
                    {
                        // Duplicate name.
                        return(false);
                    }

                    namedValues.Add(identifier, namedValue);
                }
                else if (currentToken.IsKeyValueToken || (allowNull && currentToken.Id == TokenId.NullLiteral))
                {
                    // Positional value.
                    if (namedValues != null)
                    {
                        // We cannot mix named and non-named values.
                        return(false);
                    }

                    WebUtil.CreateIfNull(ref positionalValues);
                    positionalValues.Add(lexer.CurrentToken.Text);
                }
                else
                {
                    return(false);
                }

                // Read the next token. We should be at the end, or find
                // we have a comma followed by something.
                lexer.NextToken();
                currentToken = lexer.CurrentToken;
                if (currentToken.Id == TokenId.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Id == TokenId.End)
                    {
                        // Trailing comma.
                        return(false);
                    }
                }
            }while (currentToken.Id != TokenId.End);

            instance = new KeyInstance(namedValues, positionalValues);
            return(true);
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Parses null literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseNullLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");
            Debug.Assert(lexer.CurrentToken.Kind == ExpressionTokenKind.NullLiteral, "this.lexer.CurrentToken.InternalKind == ExpressionTokenKind.NullLiteral");

            LiteralToken result = new LiteralToken(null, lexer.CurrentToken.Text);

            lexer.NextToken();
            return result;
        }
Ejemplo n.º 35
0
        /// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <param name="targetTypeReference">Expected type to be parsed.</param>
        /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmPrimitiveTypeReference targetTypeReference, string targetTypeName)
        {
            Debug.Assert(lexer != null, "lexer != null");

            object targetValue;
            string reason;
            if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetTypeReference, out targetValue, out reason))
            {
                string message;

                if (reason == null)
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText);
                }
                else
                {
                    message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason(
                        targetTypeName,
                        lexer.CurrentToken.Text,
                        lexer.CurrentToken.Position,
                        lexer.ExpressionText,
                        reason);
                }

                throw ParseError(message);
            }

            LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text);
            lexer.NextToken();
            return result;
        }
Ejemplo n.º 36
0
 private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text)
 {
     lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.StringLiteral);
     lexer.CurrentToken.Text.Should().Be(text);
     lexer.NextToken();
 }
Ejemplo n.º 37
0
 private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text)
 {
     lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.StringLiteral);
     lexer.CurrentToken.Text.Should().Be(text);
     lexer.NextToken();
 }
Ejemplo n.º 38
0
 private static void ValidateIdentifierToken(ExpressionLexer lexer, string text)
 {
     lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.Identifier);
     lexer.CurrentToken.Text.Should().Be(text);
     lexer.NextToken();
 }
Ejemplo n.º 39
0
        /// <summary>
        /// Parses a literal.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <returns>The literal query token or null if something else was found.</returns>
        internal static LiteralToken TryParseLiteral(ExpressionLexer lexer)
        {
            Debug.Assert(lexer != null, "lexer != null");

            switch (lexer.CurrentToken.Kind)
            {
                case ExpressionTokenKind.BooleanLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBoolean(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmBooleanTypeName);
                case ExpressionTokenKind.DateLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDate(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTypeName);
                case ExpressionTokenKind.DateTimeOffsetLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.DateTimeOffset, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTimeOffsetTypeName);
                case ExpressionTokenKind.DurationLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDurationTypeName);
                case ExpressionTokenKind.DecimalLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDecimal(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDecimalTypeName);
                case ExpressionTokenKind.NullLiteral:
                    return ParseNullLiteral(lexer);
                case ExpressionTokenKind.StringLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName);
                case ExpressionTokenKind.Int64Literal:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt64(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt64TypeName);
                case ExpressionTokenKind.IntegerLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt32(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt32TypeName);
                case ExpressionTokenKind.DoubleLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDouble(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDoubleTypeName);
                case ExpressionTokenKind.SingleLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSingle(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmSingleTypeName);
                case ExpressionTokenKind.GuidLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetGuid(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGuidTypeName);
                case ExpressionTokenKind.BinaryLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBinary(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmBinaryTypeName);
                case ExpressionTokenKind.GeographyLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeographyTypeName);
                case ExpressionTokenKind.GeometryLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeometryTypeName);
                case ExpressionTokenKind.QuotedLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName);
                case ExpressionTokenKind.BracketedExpression:
                    {
                        // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"]  or {...}
                        LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text);
                        lexer.NextToken();
                        return result;
                    }

                case ExpressionTokenKind.TimeOfDayLiteral:
                    return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.TimeOfDay, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmTimeOfDayTypeName);
                default:
                    return null;
            }
        }