Skip to content

Commit 4bc0e30

Browse files
jckingcopybara-github
authored andcommitted
Fix error value handling in create map/struct
PiperOrigin-RevId: 736527922
1 parent 0b2a2fc commit 4bc0e30

14 files changed

+807
-513
lines changed

common/type_reflector_test.cc

Lines changed: 186 additions & 93 deletions
Large diffs are not rendered by default.

common/value.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#ifndef THIRD_PARTY_CEL_CPP_COMMON_VALUE_H_
1616
#define THIRD_PARTY_CEL_CPP_COMMON_VALUE_H_
1717

18-
#include <algorithm>
18+
#include <cstddef>
1919
#include <cstdint>
2020
#include <cstring>
2121
#include <memory>
@@ -2630,6 +2630,12 @@ static_assert(std::is_nothrow_move_constructible_v<Value>);
26302630
static_assert(std::is_nothrow_move_assignable_v<Value>);
26312631
static_assert(std::is_nothrow_swappable_v<Value>);
26322632

2633+
inline common_internal::ImplicitlyConvertibleStatus
2634+
ErrorValueAssign::operator()(absl::Status status) const {
2635+
*value_ = ErrorValue(std::move(status));
2636+
return common_internal::ImplicitlyConvertibleStatus();
2637+
}
2638+
26332639
namespace common_internal {
26342640

26352641
template <typename Base>
@@ -2855,9 +2861,11 @@ class ValueBuilder {
28552861
public:
28562862
virtual ~ValueBuilder() = default;
28572863

2858-
virtual absl::Status SetFieldByName(absl::string_view name, Value value) = 0;
2864+
virtual absl::StatusOr<absl::optional<ErrorValue>> SetFieldByName(
2865+
absl::string_view name, Value value) = 0;
28592866

2860-
virtual absl::Status SetFieldByNumber(int64_t number, Value value) = 0;
2867+
virtual absl::StatusOr<absl::optional<ErrorValue>> SetFieldByNumber(
2868+
int64_t number, Value value) = 0;
28612869

28622870
virtual absl::StatusOr<Value> Build() && = 0;
28632871
};

common/values/error_value.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_ERROR_VALUE_H_
2020

2121
#include <cstddef>
22+
#include <memory>
2223
#include <new>
2324
#include <ostream>
2425
#include <string>
@@ -29,6 +30,7 @@
2930
#include "absl/base/nullability.h"
3031
#include "absl/log/absl_check.h"
3132
#include "absl/status/status.h"
33+
#include "absl/status/statusor.h"
3234
#include "absl/strings/cord.h"
3335
#include "absl/strings/string_view.h"
3436
#include "common/arena.h"
@@ -217,6 +219,48 @@ class ErrorValueReturn final {
217219
}
218220
};
219221

222+
namespace common_internal {
223+
224+
struct ImplicitlyConvertibleStatus {
225+
// NOLINTNEXTLINE(google-explicit-constructor)
226+
operator absl::Status() const { return absl::OkStatus(); }
227+
228+
template <typename T>
229+
// NOLINTNEXTLINE(google-explicit-constructor)
230+
operator absl::StatusOr<T>() const {
231+
return T();
232+
}
233+
};
234+
235+
} // namespace common_internal
236+
237+
// For use with `RETURN_IF_ERROR(...).With(cel::ErrorValueAssign(&result))` and
238+
// `ASSIGN_OR_RETURN(..., ..., _.With(cel::ErrorValueAssign(&result)))`.
239+
//
240+
// IMPORTANT:
241+
// If the returning type is `absl::Status` the result will be
242+
// `absl::OkStatus()`. If the returning type is `absl::StatusOr<T>` the result
243+
// will be `T()`.
244+
class ErrorValueAssign final {
245+
public:
246+
ErrorValueAssign() = delete;
247+
248+
explicit ErrorValueAssign(Value& value ABSL_ATTRIBUTE_LIFETIME_BOUND)
249+
: ErrorValueAssign(std::addressof(value)) {}
250+
251+
explicit ErrorValueAssign(
252+
absl::Nonnull<Value*> value ABSL_ATTRIBUTE_LIFETIME_BOUND)
253+
: value_(value) {
254+
ABSL_DCHECK(value != nullptr);
255+
}
256+
257+
common_internal::ImplicitlyConvertibleStatus operator()(
258+
absl::Status status) const;
259+
260+
private:
261+
absl::Nonnull<Value*> value_;
262+
};
263+
220264
template <>
221265
struct ArenaTraits<ErrorValue> {
222266
static bool trivially_destructible(const ErrorValue& value) {

common/values/struct_value.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,11 @@ class StructValueBuilder {
483483
public:
484484
virtual ~StructValueBuilder() = default;
485485

486-
virtual absl::Status SetFieldByName(absl::string_view name, Value value) = 0;
486+
virtual absl::StatusOr<absl::optional<ErrorValue>> SetFieldByName(
487+
absl::string_view name, Value value) = 0;
487488

488-
virtual absl::Status SetFieldByNumber(int64_t number, Value value) = 0;
489+
virtual absl::StatusOr<absl::optional<ErrorValue>> SetFieldByNumber(
490+
int64_t number, Value value) = 0;
489491

490492
virtual absl::StatusOr<StructValue> Build() && = 0;
491493
};

0 commit comments

Comments
 (0)