in src/Microsoft.Azure.NotificationHubs/Messaging/ExpressionEvaluator.cs [59:170]
static List<Token> ValidateAndTokenize(string expression, out ExpressionType expressionType)
{
expressionType = ExpressionEvaluator.PeekExpressionType(expression);
if (expressionType == ExpressionType.Literal)
{
return new List<Token>();
}
List<Token> tokens = new List<Token>();
string workingInput = expression;
int tokenEndIndex;
if (expressionType == ExpressionType.Composite)
{
if (expression[expression.Length - 1] != '}')
{
throw new InvalidDataContractException(string.Format(SRClient.ExpressionMissingClosingParenthesesNoToken, expression));
}
workingInput = expression.Substring(1, expression.Length - 2).TrimEnd();
}
while (true)
{
Token token = new Token();
workingInput = workingInput.TrimStart();
if (workingInput.Length < 3)
{
throw new InvalidDataContractException(string.Format(SRClient.ExpressionInvalidToken, expression, workingInput));
}
switch (workingInput[0])
{
case '.':
token.Type = TokenType.Dot;
tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
break;
case '%':
token.Type = TokenType.Percentage;
tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
break;
case '\'':
token.Type = TokenType.SingleLiteral;
tokenEndIndex = ExpressionEvaluator.ExtractLiteral(expression, workingInput, token);
break;
case '"':
token.Type = TokenType.DoubleLiteral;
tokenEndIndex = ExpressionEvaluator.ExtractLiteral(expression, workingInput, token);
break;
case '#':
token.Type = TokenType.Hash;
tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
break;
case '$':
if (workingInput.ToLowerInvariant().StartsWith(BodyExpression, StringComparison.OrdinalIgnoreCase))
{
tokenEndIndex = BodyExpression.Length - 1;
token.Type = TokenType.Body;
}
else
{
token.Type = TokenType.Dollar;
tokenEndIndex = ExpressionEvaluator.ExtractToken(expression, workingInput, token);
}
break;
default:
throw new InvalidDataContractException(string.Format(SRClient.ExpressionInvalidTokenType, expression, workingInput));
}
if (token.Type != TokenType.SingleLiteral &&
token.Type != TokenType.DoubleLiteral &&
token.Type != TokenType.Body &&
!string.Equals(token.Property, ExpressionEvaluator.BodyExpression, StringComparison.OrdinalIgnoreCase))
{
if (!ExpressionEvaluator.PropertyNameRegEx.IsMatch(token.Property))
{
throw new InvalidDataContractException(string.Format(SRClient.PropertyNameIsBad, token.Property));
}
if (token.Property.Length > ExpressionEvaluator.MaxLengthOfPropertyName)
{
throw new InvalidDataContractException(string.Format(SRClient.PropertyTooLong, token.Property.Length, ExpressionEvaluator.MaxLengthOfPropertyName));
}
}
tokens.Add(token);
if (workingInput.Length == tokenEndIndex + 1)
{
break;
}
workingInput = workingInput.Substring(tokenEndIndex + 1).TrimStart();
if (workingInput[0] != '+')
{
throw new InvalidDataContractException(string.Format(SRClient.ExpressionInvalidCompositionOperator, expression, workingInput));
}
workingInput = workingInput.Substring(1);
}
if (tokens.Count > 1 && tokens.Find((token) => token.Type == TokenType.Hash) != null)
{
throw new InvalidDataContractException(SRClient.ExpressionHashInComposite);
}
return tokens;
}