/// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="expressionLexer">The expression lexer.</param>
        /// <param name="targetTypeReference">Expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static object ParseTypedLiteral(this ExpressionLexer expressionLexer, IEdmPrimitiveTypeReference targetTypeReference)
        {
            object targetValue;
            string reason;

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

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

                throw new ODataException(message);
            }

            expressionLexer.NextToken();
            return(targetValue);
        }
        /// <summary>
        /// Parses a literal.
        /// Precondition: lexer is at a literal token type: Boolean, DateTime, Decimal, Null, String, Int64, Integer, Double, Single, Guid, Binary.
        /// </summary>
        /// <param name="expressionLexer">The expression lexer.</param>
        /// <returns>The literal query token or null if something else was found.</returns>
        private static object TryParseLiteral(this ExpressionLexer expressionLexer)
        {
            Debug.Assert(expressionLexer.CurrentToken.Kind.IsLiteralType(), "TryParseLiteral called when not at a literal type token");

            switch (expressionLexer.CurrentToken.Kind)
            {
            case ExpressionTokenKind.BooleanLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetBoolean(false)));

            case ExpressionTokenKind.DecimalLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetDecimal(false)));

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

            case ExpressionTokenKind.StringLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetString(true)));

            case ExpressionTokenKind.Int64Literal:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetInt64(false)));

            case ExpressionTokenKind.IntegerLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetInt32(false)));

            case ExpressionTokenKind.DoubleLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetDouble(false)));

            case ExpressionTokenKind.SingleLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetSingle(false)));

            case ExpressionTokenKind.GuidLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetGuid(false)));

            case ExpressionTokenKind.BinaryLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetBinary(true)));

            case ExpressionTokenKind.DateLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetDate(false)));

            case ExpressionTokenKind.DateTimeOffsetLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetDateTimeOffset(false)));

            case ExpressionTokenKind.DurationLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false)));

            case ExpressionTokenKind.GeographyLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false)));

            case ExpressionTokenKind.GeometryLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false)));

            case ExpressionTokenKind.QuotedLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetString(true)));

            case ExpressionTokenKind.TimeOfDayLiteral:
                return(ParseTypedLiteral(expressionLexer, EdmCoreModel.Instance.GetTimeOfDay(false)));
            }

            return(null);
        }
Exemple #3
0
        /// <summary>
        /// Parses null literals.
        /// </summary>
        /// <param name="expressionLexer">The expression lexer.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static object ParseNullLiteral(this ExpressionLexer expressionLexer)
        {
            Debug.Assert(expressionLexer.CurrentToken.Kind == ExpressionTokenKind.NullLiteral, "this.lexer.CurrentToken.InternalKind == ExpressionTokenKind.NullLiteral");

            expressionLexer.NextToken();
            ODataNullValue nullValue = new ODataNullValue();

            return(nullValue);
        }
Exemple #4
0
        /// <summary>Reads the next token, checks that it is a literal token type, converts to to a Common Language Runtime value as appropriate, and returns the value.</summary>
        /// <param name="expressionLexer">The expression lexer.</param>
        /// <returns>The value represented by the next token.</returns>
        internal static object ReadLiteralToken(this ExpressionLexer expressionLexer)
        {
            expressionLexer.NextToken();

            if (expressionLexer.CurrentToken.Kind.IsLiteralType())
            {
                return(TryParseLiteral(expressionLexer));
            }

            throw new ODataException(ODataErrorStrings.ExpressionLexer_ExpectedLiteralToken(expressionLexer.CurrentToken.Text));
        }
        /// <summary>
        /// Converts the given <paramref name="value"/> to a corresponding CLR type. Expects the
        /// <paramref name="value"/> to have already been properly unescaped from an actual Uri.
        /// </summary>
        /// <param name="value">Value from a Uri to be converted.</param>
        /// <param name="version">Version to be compliant with.</param>
        /// <param name="model">Optional model to perform verification against.</param>
        /// <param name="typeReference">Optional IEdmTypeReference to perform verification against.
        ///  Callers must provide a <paramref name="model"/> containing this type if it is specified.</param>
        /// <returns>A CLR object that the <paramref name="value"/> represents or an EnumNode.</returns>
        public static object ConvertFromUriLiteral(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference)
        {
            ExceptionUtils.CheckArgumentNotNull(value, "value");
            if (typeReference != null && model == null)
            {
                throw new ODataException(ODataErrorStrings.ODataUriUtils_ConvertFromUriLiteralTypeRefWithoutModel);
            }

            if (model == null)
            {
                model = Microsoft.OData.Edm.Library.EdmCoreModel.Instance;
            }

            // Let ExpressionLexer try to get a primitive
            ExpressionLexer lexer = new ExpressionLexer(value, false /*moveToFirstToken*/, false /*useSemicolonDelimeter*/);
            Exception       error;
            ExpressionToken token;

            lexer.TryPeekNextToken(out token, out error);

            if (token.Kind == ExpressionTokenKind.BracketedExpression)
            {
                // Should be a complex or collection value
                return(ODataUriConversionUtils.ConvertFromComplexOrCollectionValue(value, version, model, typeReference));
            }

            QueryNode enumConstNode;

            if ((token.Kind == ExpressionTokenKind.Identifier) && // then try parsing the entire text as enum value
                EnumBinder.TryBindIdentifier(lexer.ExpressionText, null, model, out enumConstNode))
            {
                return(((ConstantNode)enumConstNode).Value);
            }

            object result = lexer.ReadLiteralToken();

            // If we have a typeReference then perform verification and convert if necessary
            if (typeReference != null)
            {
                result = ODataUriConversionUtils.VerifyAndCoerceUriPrimitiveLiteral(result, model, typeReference, version);
            }

            return(result);
        }