private static JObject VisitFieldTokens()

in src/PSRule.Rules.Azure/Data/Policy/PolicyAssignmentVisitor.cs [1312:1499]


        private static JObject VisitFieldTokens(PolicyAssignmentContext context, JObject condition, TokenStream tokens)
        {
            if (tokens.ConsumeFunction(PROPERTY_FIELD) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _) &&
                tokens.ConsumeString(out var field) &&
                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _))
            {
                // Handle [field('type')]
                if (string.Equals(field, PROPERTY_TYPE, StringComparison.OrdinalIgnoreCase))
                {
                    condition.RemoveProperty(PROPERTY_VALUE);
                    condition.Add(PROPERTY_TYPE, DOT);
                }
                else
                {
                    condition.RemoveProperty(PROPERTY_VALUE);

                    field = context.TryPolicyAliasPath(field, out var aliasPath) ? TrimFieldName(context, aliasPath) : field;
                    condition.Add(PROPERTY_FIELD, field);
                }
            }

            else if (tokens.ConsumeFunction(PROPERTY_IF) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                var original = condition;

                // Condition
                var leftCondition = VisitFieldTokens(context, new JObject(), tokens);
                var rightCondition = ReverseCondition(Clone(leftCondition));

                var leftEvaluation = VisitFieldTokens(context, Clone(original), tokens);
                var rightEvaluation = VisitFieldTokens(context, Clone(original), tokens);

                var left = new JObject
                {
                    { PROPERTY_FIELD, DOT },
                    { PROPERTY_WHERE, leftCondition },
                    { PROPERTY_ALLOF, new JArray(new[] { leftEvaluation }) }
                };

                var right = new JObject
                {
                    { PROPERTY_FIELD, DOT },
                    { PROPERTY_WHERE, rightCondition },
                    { PROPERTY_ALLOF, new JArray(new[] { rightEvaluation }) }
                };

                var result = OrCondition(left, right);
                condition.Replace(result);
                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
                return result;
            }

            else if (tokens.ConsumeFunction(PROPERTY_EQUALS) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);
                if (tokens.ConsumeString(out var s))
                {
                    condition.Add(PROPERTY_EQUALS, s);
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_EMPTY) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                if (condition.TryBoolProperty(PROPERTY_EQUALS, out var emptyEquals))
                {
                    condition.RemoveProperty(PROPERTY_EQUALS);
                    condition.Add(PROPERTY_HAS_VALUE, !emptyEquals.Value);
                }
                VisitFieldTokens(context, condition, tokens);

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_LESS) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);

                if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
                {
                    if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
                    {
                        condition.RemoveProperty(PROPERTY_EQUALS);
                        condition.Add(comparison.Value ? PROPERTY_LESS : PROPERTY_GREATEROREQUALS, comparisonInt.Value);
                    }
                    else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
                    {
                        condition.RemoveProperty(PROPERTY_NOTEQUALS);
                        condition.Add(comparison.Value ? PROPERTY_GREATEROREQUALS : PROPERTY_LESS, comparisonInt.Value);
                    }
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_LESSOREQUALS) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);

                if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
                {
                    if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
                    {
                        condition.RemoveProperty(PROPERTY_EQUALS);
                        condition.Add(comparison.Value ? PROPERTY_LESSOREQUALS : PROPERTY_GREATER, comparisonInt.Value);
                    }
                    else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
                    {
                        condition.RemoveProperty(PROPERTY_NOTEQUALS);
                        condition.Add(comparison.Value ? PROPERTY_GREATER : PROPERTY_LESSOREQUALS, comparisonInt.Value);
                    }
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_GREATER) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);

                if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
                {
                    if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
                    {
                        condition.RemoveProperty(PROPERTY_EQUALS);
                        condition.Add(comparison.Value ? PROPERTY_GREATER : PROPERTY_LESSOREQUALS, comparisonInt.Value);
                    }
                    else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
                    {
                        condition.RemoveProperty(PROPERTY_NOTEQUALS);
                        condition.Add(comparison.Value ? PROPERTY_LESSOREQUALS : PROPERTY_GREATER, comparisonInt.Value);
                    }
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_GREATEROREQUALS) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);

                if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
                {
                    if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
                    {
                        condition.RemoveProperty(PROPERTY_EQUALS);
                        condition.Add(comparison.Value ? PROPERTY_GREATEROREQUALS : PROPERTY_LESS, comparisonInt.Value);
                    }
                    else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
                    {
                        condition.RemoveProperty(PROPERTY_NOTEQUALS);
                        condition.Add(comparison.Value ? PROPERTY_LESS : PROPERTY_GREATEROREQUALS, comparisonInt.Value);
                    }
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            else if (tokens.ConsumeFunction(PROPERTY_LENGTH) &&
                tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
            {
                VisitFieldTokens(context, condition, tokens);

                if (condition.TryIntegerProperty(PROPERTY_EQUALS, out var comparison))
                {
                    condition.RemoveProperty(PROPERTY_EQUALS);
                    condition.Add(PROPERTY_COUNT, comparison.Value);
                }
                else if (condition.TryIntegerProperty(PROPERTY_NOTEQUALS, out comparison))
                {
                    condition.RemoveProperty(PROPERTY_NOTEQUALS);
                    condition.Add(PROPERTY_NOTCOUNT, comparison.Value);
                }

                tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
            }

            return condition;
        }