/// <summary> /// Bind a parameter alias which is inside another alias value. /// </summary> /// <param name="bindingState">The alias name which is inside another alias value.</param> /// <param name="aliasToken">The cache of alias value nodes</param> /// <returns>The semantics node tree for alias (the @p1 in "@p1=...", not alias value expression)</returns> internal ParameterAliasNode BindParameterAlias(BindingState bindingState, FunctionParameterAliasToken aliasToken) { ExceptionUtils.CheckArgumentNotNull(bindingState, "bindingState"); ExceptionUtils.CheckArgumentNotNull(aliasToken, "aliasToken"); string alias = aliasToken.Alias; ParameterAliasValueAccessor aliasValueAccessor = bindingState.Configuration.ParameterAliasValueAccessor; if (aliasValueAccessor == null) { return(new ParameterAliasNode(alias, null)); } // in cache? SingleValueNode aliasValueNode = null; if (!aliasValueAccessor.ParameterAliasValueNodesCached.TryGetValue(alias, out aliasValueNode)) { // has value expression? string aliasValueExpression = aliasValueAccessor.GetAliasValueExpression(alias); if (aliasValueExpression == null) { aliasValueAccessor.ParameterAliasValueNodesCached[alias] = null; } else { aliasValueNode = this.ParseAndBindParameterAliasValueExpression(bindingState, aliasValueExpression); aliasValueAccessor.ParameterAliasValueNodesCached[alias] = aliasValueNode; } } return(new ParameterAliasNode(alias, aliasValueNode.GetEdmTypeReference())); }
/// <summary> /// Bind a parameter alias which is inside another alias value. /// </summary> /// <param name="bindingState">The alias name which is inside another alias value.</param> /// <param name="aliasToken">The cache of alias value nodes</param> /// <returns>The semantics node tree for alias (the @p1 in "@p1=...", not alias value expression)</returns> internal ParameterAliasNode BindParameterAlias(BindingState bindingState, FunctionParameterAliasToken aliasToken) { ExceptionUtils.CheckArgumentNotNull(bindingState, "bindingState"); ExceptionUtils.CheckArgumentNotNull(aliasToken, "aliasToken"); string alias = aliasToken.Alias; ParameterAliasValueAccessor aliasValueAccessor = bindingState.Configuration.ParameterAliasValueAccessor; if (aliasValueAccessor == null) { return new ParameterAliasNode(alias, null); } // in cache? SingleValueNode aliasValueNode = null; if (!aliasValueAccessor.ParameterAliasValueNodesCached.TryGetValue(alias, out aliasValueNode)) { // has value expression? string aliasValueExpression = aliasValueAccessor.GetAliasValueExpression(alias); if (aliasValueExpression == null) { aliasValueAccessor.ParameterAliasValueNodesCached[alias] = null; } else { aliasValueNode = this.ParseAndBindParameterAliasValueExpression(bindingState, aliasValueExpression, aliasToken.ExpectedParameterType); aliasValueAccessor.ParameterAliasValueNodesCached[alias] = aliasValueNode; } } return new ParameterAliasNode(alias, aliasValueNode.GetEdmTypeReference()); }
private static ICollection <FunctionParameterToken> HandleComplexOrCollectionParameterValueIfExists(IEdmModel model, IEdmOperation operation, ICollection <FunctionParameterToken> parameterTokens, bool enableCaseInsensitive, bool enableUriTemplateParsing = false) { ICollection <FunctionParameterToken> partiallyParsedParametersWithComplexOrCollection = new Collection <FunctionParameterToken>(); foreach (FunctionParameterToken paraToken in parameterTokens) { FunctionParameterToken funcParaToken; IEdmOperationParameter functionParameter = operation.FindParameter(paraToken.ParameterName); if (enableCaseInsensitive && functionParameter == null) { functionParameter = ODataUriResolver.ResolveOpearationParameterNameCaseInsensitive(operation, paraToken.ParameterName); // The functionParameter can not be null here, else this method won't be called. funcParaToken = new FunctionParameterToken(functionParameter.Name, paraToken.ValueToken); } else { funcParaToken = paraToken; } FunctionParameterAliasToken aliasToken = funcParaToken.ValueToken as FunctionParameterAliasToken; if (aliasToken != null) { aliasToken.ExpectedParameterType = functionParameter.Type; } LiteralToken valueToken = funcParaToken.ValueToken as LiteralToken; string valueStr = null; if (valueToken != null && (valueStr = valueToken.Value as string) != null && !string.IsNullOrEmpty(valueToken.OriginalText)) { var lexer = new ExpressionLexer(valueToken.OriginalText, true /*moveToFirstToken*/, false /*useSemicolonDelimiter*/, true /*parsingFunctionParameters*/); if (lexer.CurrentToken.Kind == ExpressionTokenKind.BracketedExpression) { object result; UriTemplateExpression expression; if (enableUriTemplateParsing && UriTemplateParser.TryParseLiteral(lexer.CurrentToken.Text, functionParameter.Type, out expression)) { result = expression; } else { // ExpressionTokenKind.BracketedExpression means text like [{\"Street\":\"NE 24th St.\",\"City\":\"Redmond\"},{\"Street\":\"Pine St.\",\"City\":\"Seattle\"}] // so now try convert it into complex or collection type value: result = ODataUriUtils.ConvertFromUriLiteral(valueStr, ODataVersion.V4, model, functionParameter.Type); } LiteralToken newValueToken = new LiteralToken(result, valueToken.OriginalText); FunctionParameterToken newFuncParaToken = new FunctionParameterToken(funcParaToken.ParameterName, newValueToken); partiallyParsedParametersWithComplexOrCollection.Add(newFuncParaToken); continue; } } partiallyParsedParametersWithComplexOrCollection.Add(funcParaToken); } return(partiallyParsedParametersWithComplexOrCollection); }
/// <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); }
/// <summary> /// Tries to create a parameter using any representation based on the provided delegate for creating it from a converted value. /// </summary> /// <param name="expressionToken">The current expression parameterToken from the lexer.</param> /// <param name="parameterValue">The parameter value if one was successfully created.</param> /// <returns>Whether the parameter could be created from the parameterToken.</returns> private static bool TryCreateParameterValueToken(ExpressionToken expressionToken, out QueryToken parameterValue) { if (expressionToken.Kind == ExpressionTokenKind.ParameterAlias) { parameterValue = new FunctionParameterAliasToken(expressionToken.Text); return(true); } if (expressionToken.IsFunctionParameterToken) { parameterValue = new RawFunctionParameterValueToken(expressionToken.Text); return(true); } parameterValue = null; return(false); }
/// <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; }
/// <summary> /// Bind parameter alias (figuring out its type by first parsing and binding its value expression). /// </summary> /// <param name="functionParameterAliasToken">The alias syntatics token.</param> /// <returns>The semantics node for parameter alias.</returns> protected virtual SingleValueNode BindParameterAlias(FunctionParameterAliasToken functionParameterAliasToken) { ParameterAliasBinder binder = new ParameterAliasBinder(this.Bind); return(binder.BindParameterAlias(this.BindingState, functionParameterAliasToken)); }
/// <summary> /// Bind parameter alias (figuring out its type by first parsing and binding its value expression). /// </summary> /// <param name="functionParameterAliasToken">The alias syntatics token.</param> /// <returns>The semantics node for parameter alias.</returns> protected virtual SingleValueNode BindParameterAlias(FunctionParameterAliasToken functionParameterAliasToken) { ParameterAliasBinder binder = new ParameterAliasBinder(this.Bind); return binder.BindParameterAlias(this.BindingState, functionParameterAliasToken); }