Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion common/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -2609,7 +2609,8 @@ static_assert(std::is_nothrow_swappable_v<Value>);

inline common_internal::ImplicitlyConvertibleStatus
ErrorValueAssign::operator()(absl::Status status) const {
*value_ = ErrorValue(std::move(status));
*value_ = arena_ != nullptr ? ErrorValue::From(std::move(status), arena_)
: ErrorValue(std::move(status));
return common_internal::ImplicitlyConvertibleStatus();
}

Expand Down
108 changes: 83 additions & 25 deletions common/values/error_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,46 +46,106 @@ const absl::Status& DefaultErrorValue() {
return *value;
}

absl::Status MakeNoSuchFieldError(absl::string_view field) {
return absl::NotFoundError(
absl::StrCat("no_such_field", field.empty() ? "" : " : ", field));
}

absl::Status MakeNoSuchKeyError(absl::string_view key) {
return absl::NotFoundError(absl::StrCat("Key not found in map : ", key));
}

absl::Status MakeNoSuchTypeError(absl::string_view type) {
return absl::NotFoundError(absl::StrCat("type not found: ", type));
}

absl::Status MakeTypeConversionError(absl::string_view from,
absl::string_view to) {
return absl::InvalidArgumentError(
absl::StrCat("type conversion error from '", from, "' to '", to, "'"));
}

absl::Status MakeIndexOutOfBoundsError(size_t index) {
return absl::InvalidArgumentError(
absl::StrCat("index out of bounds: ", index));
}

absl::Status MakeIndexOutOfBoundsError(ptrdiff_t index) {
return absl::InvalidArgumentError(
absl::StrCat("index out of bounds: ", index));
}

} // namespace

ErrorValue::ErrorValue() : ErrorValue(DefaultErrorValue()) {}
ErrorValue::ErrorValue() : ErrorValue(nullptr, &DefaultErrorValue()) {}

ErrorValue NoSuchFieldError(absl::string_view field) {
return ErrorValue(absl::NotFoundError(
absl::StrCat("no_such_field", field.empty() ? "" : " : ", field)));
return ErrorValue(MakeNoSuchFieldError(field));
}

ErrorValue NoSuchFieldError(absl::string_view field,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeNoSuchFieldError(field), arena);
}

ErrorValue NoSuchKeyError(absl::string_view key) {
return ErrorValue(
absl::NotFoundError(absl::StrCat("Key not found in map : ", key)));
return ErrorValue(MakeNoSuchKeyError(key));
}

ErrorValue NoSuchKeyError(absl::string_view key,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeNoSuchKeyError(key), arena);
}

ErrorValue NoSuchTypeError(absl::string_view type) {
return ErrorValue(
absl::NotFoundError(absl::StrCat("type not found: ", type)));
return ErrorValue(MakeNoSuchTypeError(type));
}

ErrorValue NoSuchTypeError(absl::string_view type,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeNoSuchTypeError(type), arena);
}

ErrorValue DuplicateKeyError() {
return ErrorValue(absl::AlreadyExistsError("duplicate key in map"));
static const absl::NoDestructor<absl::Status> error(
absl::AlreadyExistsError("duplicate key in map"));
return ErrorValue(nullptr, &*error);
}

ErrorValue TypeConversionError(absl::string_view from, absl::string_view to) {
return ErrorValue(absl::InvalidArgumentError(
absl::StrCat("type conversion error from '", from, "' to '", to, "'")));
return ErrorValue(MakeTypeConversionError(from, to));
}

ErrorValue TypeConversionError(absl::string_view from, absl::string_view to,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeTypeConversionError(from, to), arena);
}

ErrorValue TypeConversionError(const Type& from, const Type& to) {
return TypeConversionError(from.DebugString(), to.DebugString());
}

ErrorValue TypeConversionError(const Type& from, const Type& to,
google::protobuf::Arena* absl_nonnull arena) {
return TypeConversionError(from.DebugString(), to.DebugString(), arena);
}

ErrorValue IndexOutOfBoundsError(size_t index) {
return ErrorValue(
absl::InvalidArgumentError(absl::StrCat("index out of bounds: ", index)));
return ErrorValue(MakeIndexOutOfBoundsError(index));
}

ErrorValue IndexOutOfBoundsError(size_t index,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeIndexOutOfBoundsError(index), arena);
}

ErrorValue IndexOutOfBoundsError(ptrdiff_t index) {
return ErrorValue(
absl::InvalidArgumentError(absl::StrCat("index out of bounds: ", index)));
return ErrorValue(MakeIndexOutOfBoundsError(index));
}

ErrorValue IndexOutOfBoundsError(ptrdiff_t index,
google::protobuf::Arena* absl_nonnull arena) {
return ErrorValue::From(MakeIndexOutOfBoundsError(index), arena);
}

bool IsNoSuchField(const ErrorValue& value) {
Expand Down Expand Up @@ -159,30 +219,28 @@ ErrorValue ErrorValue::Clone(google::protobuf::Arena* absl_nonnull arena) const

absl::Status ErrorValue::ToStatus() const& {
ABSL_DCHECK(*this);

if (arena_ == nullptr) {
if (status_ptr_ == nullptr) {
return *std::launder(
reinterpret_cast<const absl::Status*>(&status_.val[0]));
reinterpret_cast<const absl::Status*>(&status_val_[0]));
}
return *status_.ptr;
return *status_ptr_;
}

absl::Status ErrorValue::ToStatus() && {
ABSL_DCHECK(*this);

if (arena_ == nullptr) {
if (status_ptr_ == nullptr) {
return std::move(
*std::launder(reinterpret_cast<absl::Status*>(&status_.val[0])));
*std::launder(reinterpret_cast<absl::Status*>(&status_val_[0])));
}
return *status_.ptr;
return *status_ptr_;
}

ErrorValue::operator bool() const {
if (arena_ == nullptr) {
return !std::launder(reinterpret_cast<const absl::Status*>(&status_.val[0]))
if (status_ptr_ == nullptr) {
return !std::launder(reinterpret_cast<const absl::Status*>(&status_val_[0]))
->ok();
}
return status_.ptr != nullptr && !status_.ptr->ok();
return !status_ptr_->ok();
}

void swap(ErrorValue& lhs, ErrorValue& rhs) noexcept {
Expand Down
Loading
Loading