static List ValidateAndTokenize()

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