func safeParse()

in internal/resources/providers/aws_cis/monitoring/filter_pattern_parser.go [122:187]


func safeParse(s string, depth int) (MetricFilterPattern, error) {
	if depth > maxDepth {
		return MetricFilterPattern{}, errors.New("max depth reached, can't parse this expression")
	}

	var logicalOp logicalOperator
	// Capacity is an estimate of a maximum average of expressions. This avoids resizing slices every time we add a new item
	expressions := make([]MetricFilterPattern, 0, 20)

	buf := strings.Builder{}
	buf.Grow(len(s)) // grow buffer to max amount of runes it will have

	pointer := 0
	for len(s) > pointer {
		r := rune(s[pointer])
		i := pointer
		pointer++

		if r == '(' { // If it's a parenthesis opening, resolve the parenthesis
			exp, closingParenthesisPos, err := resolveParenthesis(s, depth, i)
			if err != nil {
				return MetricFilterPattern{}, err
			}
			expressions = append(expressions, exp)
			pointer = closingParenthesisPos + i + 1 // move pointer to the end of what has been already processed
			continue
		}

		if _, err := buf.WriteRune(r); err != nil {
			return MetricFilterPattern{}, fmt.Errorf("could not write rune %v", err)
		}

		tmpString := buf.String()
		if contains, op := hasSuffixLogicalOp(tmpString); contains { // && or || marks the end of a Simple MetricFilterPattern
			if logicalOp == "" { // set the LogicalOperator of the MetricFilterPattern without overriding it
				logicalOp = op
			}

			if logicalOp != op {
				return MetricFilterPattern{}, errors.New("not supported comparison with alternating logical operators")
			}

			cleanSimpleExpression := strings.TrimSuffix(tmpString, string(op))

			var err error
			expressions, err = appendSimpleExpression(cleanSimpleExpression, expressions)
			if err != nil {
				return MetricFilterPattern{}, err
			}

			buf.Reset()
			buf.Grow(len(s) - i)
		}
	}

	expressions, err := appendSimpleExpression(buf.String(), expressions)
	if err != nil {
		return MetricFilterPattern{}, err
	}

	if len(expressions) == 1 { // unwrap Simple Expressions
		return expressions[0], nil
	}

	return newComplexExpression(logicalOp, expressions...), nil
}