| 435 | } |
| 436 | |
| 437 | absl::Status Unparser::VisitBinary(const Expr::Call& expr, |
| 438 | const std::string& op) { |
| 439 | if (expr.args_size() != 2) { |
| 440 | return absl::InvalidArgumentError( |
| 441 | absl::StrCat("Unexpected binary: ", expr.ShortDebugString())); |
| 442 | } |
| 443 | |
| 444 | const auto& lhs = expr.args(0); |
| 445 | const auto& rhs = expr.args(1); |
| 446 | const auto& fun = expr.function(); |
| 447 | |
| 448 | // add parens if the current operator is lower precedence than the lhs expr |
| 449 | // operator. |
| 450 | bool lhs_paren = IsComplexOperatorWithRespectTo(lhs, fun); |
| 451 | // add parens if the current operator is lower precedence than the rhs expr |
| 452 | // operator, or the same precedence and the operator is left recursive. |
| 453 | bool rhs_paren = IsComplexOperatorWithRespectTo(rhs, fun); |
| 454 | if (!rhs_paren && IsOperatorLeftRecursive(fun)) { |
| 455 | rhs_paren = IsOperatorSamePrecedence(fun, rhs); |
| 456 | } |
| 457 | |
| 458 | CEL_RETURN_IF_ERROR(VisitMaybeNested(lhs, lhs_paren)); |
| 459 | Print(kSpace, op, kSpace); |
| 460 | return VisitMaybeNested(rhs, rhs_paren); |
| 461 | } |
| 462 | |
| 463 | absl::Status Unparser::VisitMaybeNested(const Expr& expr, bool nested) { |
| 464 | if (nested) { |
nothing calls this directly
no test coverage detected