| 83 | : JumpStepBase({}, expr_id), kind_(kind) {} |
| 84 | |
| 85 | absl::Status Evaluate(ExecutionFrame* frame) const override { |
| 86 | if (!frame->value_stack().HasEnough(1)) { |
| 87 | return absl::Status(absl::StatusCode::kInternal, "Value stack underflow"); |
| 88 | } |
| 89 | const auto& value = frame->value_stack().Peek(); |
| 90 | auto optional_value = As<OptionalValue>(value); |
| 91 | // We jump if the receiver is `optional_type` which has a value or the |
| 92 | // receiver is an error/unknown. Unlike `_||_` we are not commutative. If |
| 93 | // we run into an error/unknown, we skip the `else` branch. |
| 94 | const bool should_jump = |
| 95 | (optional_value.has_value() && optional_value->HasValue()) || |
| 96 | (!optional_value.has_value() && (cel::InstanceOf<ErrorValue>(value) || |
| 97 | cel::InstanceOf<UnknownValue>(value))); |
| 98 | if (should_jump) { |
| 99 | if (kind_ == OptionalOrKind::kOrValue && optional_value.has_value()) { |
| 100 | frame->value_stack().PopAndPush(optional_value->Value()); |
| 101 | } |
| 102 | return Jump(frame); |
| 103 | } |
| 104 | return absl::OkStatus(); |
| 105 | } |
| 106 | |
| 107 | private: |
| 108 | const OptionalOrKind kind_; |