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
}