/// <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); }
/// <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); }
/// <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); }