| 137 | }; |
| 138 | |
| 139 | absl::Status SelectStep::Evaluate(ExecutionFrame* frame) const { |
| 140 | if (!frame->value_stack().HasEnough(1)) { |
| 141 | return absl::Status(absl::StatusCode::kInternal, |
| 142 | "No arguments supplied for Select-type expression"); |
| 143 | } |
| 144 | |
| 145 | const Value& arg = frame->value_stack().Peek(); |
| 146 | const AttributeTrail& trail = frame->value_stack().PeekAttribute(); |
| 147 | |
| 148 | if (arg.IsUnknown() || arg.IsError()) { |
| 149 | // Bubble up unknowns and errors. |
| 150 | return absl::OkStatus(); |
| 151 | } |
| 152 | |
| 153 | AttributeTrail result_trail; |
| 154 | |
| 155 | // Handle unknown resolution. |
| 156 | if (frame->enable_unknowns() || frame->enable_missing_attribute_errors()) { |
| 157 | result_trail = trail.Step(&field_); |
| 158 | } |
| 159 | |
| 160 | absl::optional<OptionalValue> optional_arg; |
| 161 | |
| 162 | if (enable_optional_types_ && arg.IsOptional()) { |
| 163 | optional_arg = arg.GetOptional(); |
| 164 | } |
| 165 | |
| 166 | if (!(optional_arg || arg->Is<MapValue>() || arg->Is<StructValue>())) { |
| 167 | frame->value_stack().PopAndPush(cel::ErrorValue(InvalidSelectTargetError()), |
| 168 | std::move(result_trail)); |
| 169 | return absl::OkStatus(); |
| 170 | } |
| 171 | |
| 172 | absl::optional<Value> marked_attribute_check = |
| 173 | CheckForMarkedAttributes(result_trail, *frame); |
| 174 | if (marked_attribute_check.has_value()) { |
| 175 | frame->value_stack().PopAndPush(std::move(marked_attribute_check).value(), |
| 176 | std::move(result_trail)); |
| 177 | return absl::OkStatus(); |
| 178 | } |
| 179 | |
| 180 | // Handle test only Select. |
| 181 | if (test_field_presence_) { |
| 182 | if (optional_arg) { |
| 183 | if (!optional_arg->HasValue()) { |
| 184 | frame->value_stack().PopAndPush(cel::BoolValue{false}); |
| 185 | return absl::OkStatus(); |
| 186 | } |
| 187 | Value value; |
| 188 | optional_arg->Value(&value); |
| 189 | return PerformTestOnlySelect(frame, value); |
| 190 | } |
| 191 | return PerformTestOnlySelect(frame, arg); |
| 192 | } |
| 193 | |
| 194 | // Normal select path. |
| 195 | // Select steps can be applied to either maps or messages |
| 196 | if (optional_arg) { |
no test coverage detected