| 142 | optional_indices_(std::move(optional_indices)) {} |
| 143 | |
| 144 | absl::Status Evaluate(ExecutionFrameBase& frame, Value& result, |
| 145 | AttributeTrail& attribute_trail) const override { |
| 146 | ListValueBuilderPtr builder = NewListValueBuilder(frame.arena()); |
| 147 | builder->Reserve(elements_.size()); |
| 148 | |
| 149 | AttributeUtility::Accumulator unknowns = |
| 150 | frame.attribute_utility().CreateAccumulator(); |
| 151 | AttributeTrail tmp_attr; |
| 152 | |
| 153 | for (size_t i = 0; i < elements_.size(); ++i) { |
| 154 | const auto& element = elements_[i]; |
| 155 | CEL_RETURN_IF_ERROR(element->Evaluate(frame, result, tmp_attr)); |
| 156 | |
| 157 | if (result.IsError()) { |
| 158 | return absl::OkStatus(); |
| 159 | } |
| 160 | |
| 161 | if (frame.attribute_tracking_enabled()) { |
| 162 | if (frame.missing_attribute_errors_enabled()) { |
| 163 | if (frame.attribute_utility().CheckForMissingAttribute(tmp_attr)) { |
| 164 | CEL_ASSIGN_OR_RETURN( |
| 165 | result, frame.attribute_utility().CreateMissingAttributeError( |
| 166 | tmp_attr.attribute())); |
| 167 | return absl::OkStatus(); |
| 168 | } |
| 169 | } |
| 170 | if (frame.unknown_processing_enabled()) { |
| 171 | if (result.IsUnknown()) { |
| 172 | unknowns.Add(result.GetUnknown()); |
| 173 | } |
| 174 | if (frame.attribute_utility().CheckForUnknown(tmp_attr, |
| 175 | /*use_partial=*/true)) { |
| 176 | unknowns.Add(tmp_attr); |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | if (!unknowns.IsEmpty()) { |
| 182 | // We found an unknown, there is no point in attempting to create a |
| 183 | // list. Instead iterate through the remaining elements and look for |
| 184 | // more unknowns. |
| 185 | continue; |
| 186 | } |
| 187 | |
| 188 | // Conditionally add if optional. |
| 189 | if (optional_indices_.contains(static_cast<int32_t>(i))) { |
| 190 | if (auto optional_arg = result.AsOptional(); optional_arg) { |
| 191 | if (!optional_arg->HasValue()) { |
| 192 | continue; |
| 193 | } |
| 194 | Value optional_arg_value; |
| 195 | optional_arg->Value(&optional_arg_value); |
| 196 | if (optional_arg_value.IsError()) { |
| 197 | // Error should never be in optional, but better safe than sorry. |
| 198 | result = std::move(optional_arg_value); |
| 199 | return absl::OkStatus(); |
| 200 | } |
| 201 | CEL_RETURN_IF_ERROR(builder->Add(std::move(optional_arg_value))); |
nothing calls this directly
no test coverage detected