19 #ifndef ASYLO_UTIL_ERROR_SPACE_H_ 20 #define ASYLO_UTIL_ERROR_SPACE_H_ 23 #include <type_traits> 24 #include <unordered_map> 26 #include "absl/status/status.h" 27 #include "absl/strings/str_format.h" 28 #include "asylo/platform/common/static_map.h" 29 #include "asylo/util/error_codes.h" 40 static constexpr char kCanonicalErrorSpaceName[] =
41 "::asylo::error::GoogleErrorSpace";
50 template <
typename EnumT>
51 struct ErrorSpaceAdlTag {
53 static_assert(std::is_enum<EnumT>::value,
54 "Cannot associate an error space with a non-enum type");
64 template <
typename EnumT>
65 struct error_enum_traits {
82 template <
typename EnumU>
83 static auto TestErrorSpaceBinding(
ErrorSpace const *space)
84 ->
decltype(space = GetErrorSpace(ErrorSpaceAdlTag<EnumU>()),
88 template <
typename EnumU>
89 static auto TestErrorSpaceBinding(...) -> std::false_type;
93 template <
typename Tag>
94 static ErrorSpace const *get_error_space(Tag tag, std::true_type t) {
95 return GetErrorSpace(tag);
104 template <
typename Tag,
typename TruthType>
105 static ErrorSpace const *get_error_space(Tag tag, TruthType truth_type) {
106 static_assert(TruthType::value,
107 "No error-space binding found for template parameter EnumT, " 108 "Make sure that GetErrorSpace(ErrorSpaceAdlTag<EnumT>) is " 114 using error_space_binding_type =
decltype(TestErrorSpaceBinding<EnumT>(0));
117 return get_error_space(ErrorSpaceAdlTag<EnumT>(),
118 error_space_binding_type());
213 virtual std::string
SpaceName()
const = 0;
218 virtual std::string
String(
int code)
const = 0;
234 namespace error_internal {
238 struct ErrorSpaceNamer {
239 std::string operator()(
const ErrorSpace &space) {
return space.SpaceName(); }
244 class AsyloErrorSpaceStaticMap
245 :
public ::asylo::StaticMap<AsyloErrorSpaceStaticMap,
const ErrorSpace,
257 template <
typename ErrorSpaceT>
268 const std::string &space_name,
269 const std::string &default_error_string =
"Unrecognized Code")
273 DoNotOptimize(&inserter_);
282 GoogleError google_error_code) {
283 CHECK(code_translation_map_
284 .emplace(code, std::pair<std::string, GoogleError>(
285 error_string, google_error_code))
287 <<
"Duplicate map key: " << code;
290 std::string
SpaceName()
const override {
return space_name_; }
292 std::string
String(
int code)
const override {
293 auto it = code_translation_map_.find(code);
294 if (it == code_translation_map_.cend()) {
298 return absl::StrFormat(
"%s (%d)", default_error_string_, code);
300 return it->second.first;
306 return GoogleError::OK;
308 auto it = code_translation_map_.find(code);
309 if (it == code_translation_map_.cend()) {
310 return GoogleError::UNKNOWN;
312 return it->second.second;
316 using InserterType = error_internal::AsyloErrorSpaceStaticMap::ValueInserter;
317 InserterType *DoNotOptimize(InserterType *inserter) {
return inserter; }
318 static InserterType inserter_;
322 std::unordered_map<
int, std::pair<std::string, GoogleError>>
323 code_translation_map_;
324 const std::string space_name_;
325 const std::string default_error_string_;
331 template <
typename ErrorSpaceT>
332 error_internal::AsyloErrorSpaceStaticMap::ValueInserter
333 ErrorSpaceImplementationHelper<ErrorSpaceT>::inserter_(
339 ErrorSpaceAdlTag<::asylo::error::GoogleError> tag);
358 static ErrorSpace const *instance =
new GoogleErrorSpace();
virtual ~ErrorSpace()=default
ErrorSpaceImplementationHelper(const std::string &space_name, const std::string &default_error_string="Unrecognized Code")
Constructs an ErrorSpaceImplementationHelper and registers it as space_name.
Definition: error_space.h:267
virtual std::string String(int code) const =0
Gets a string that describes the error code within the space.
Definition: error_space.h:37
virtual GoogleError GoogleErrorCode(int code) const =0
Converts code to an appropriate value in the GoogleError enum.
All implementations of error spaces are derived from this abstract class.
Definition: error_space.h:204
GoogleErrorSpace & operator=(const GoogleErrorSpace &other)=delete
GoogleError GoogleErrorCode(int code) const override
Converts code to an appropriate value in the GoogleError enum.
Definition: error_space.h:303
ABSL_CONST_INIT const char kStatusMoveAssignmentMsg[]
void AddTranslationMapEntry(int code, const std::string &error_string, GoogleError google_error_code)
Adds an interpretation of an error code as both a string and GoogleError.
Definition: error_space.h:281
The implementation of the ErrorSpace interface for the GoogleError canonical error space...
Definition: error_space.h:346
ErrorSpace const * GetErrorSpace(ErrorSpaceAdlTag<::absl::StatusCode > tag)
Binds the class GoogleErrorSpace to the #absl::StatusCode enum.
static ErrorSpace const * GetInstance()
Gets the singleton instance of GoogleErrorSpace.
Definition: error_space.h:357
virtual std::string SpaceName() const =0
Gets a name that uniquely identifies the error space.
ErrorSpace(const ErrorSpace &other)=delete
GoogleErrorSpace(const GoogleErrorSpace &other)=delete
std::string String(int code) const override
Gets a string that describes the error code within the space.
Definition: error_space.h:292
ErrorSpace & operator=(const ErrorSpace &other)=delete
static ErrorSpace const * Find(const std::string &name)
Finds and returns an ErrorSpace singleton pointer whose SpaceName() equals name.
std::string SpaceName() const override
Gets a name that uniquely identifies the error space.
Definition: error_space.h:290
~GoogleErrorSpace() override=default