or_throw_methods.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. --- a/src/google/protobuf/message_lite.cc
  2. +++ b/src/google/protobuf/message_lite.cc
  3. @@ -514,6 +514,33 @@ TProtoStringType MessageLite::SerializePartialAsString() const {
  4. return output;
  5. }
  6. +#if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view)
  7. +void MessageLite::ParseFromStringOrThrow(std::string_view s) {
  8. + const bool isOk = ParseFromArray(s.data(), s.size());
  9. + if (!isOk) {
  10. + throw FatalException("message_lite.cc", __LINE__, "Failed to parse protobuf message " + GetTypeName());
  11. + }
  12. +}
  13. +#endif
  14. +
  15. +#if PROTOBUF_USE_EXCEPTIONS
  16. +TProtoStringType NProtoBuf::MessageLite::SerializeAsStringOrThrow() const {
  17. + TProtoStringType s;
  18. + if (!IsInitialized()) {
  19. + //NOTE: SerializeToString (called inside SerializeAsString too) does not perform this check in release build
  20. + // so SerializeToString in release build return false only if result size is greater than 2gb
  21. + // but in debug build not properly inited message (without required filds) will lead to an exception
  22. + // different control flow in debug and build release look like a bug
  23. + throw FatalException("message_lite.cc", __LINE__, "Some required fileds are not set in message " + GetTypeName());
  24. + }
  25. + const bool isOk = SerializeToString(&s);
  26. + if (!isOk) {
  27. + throw FatalException("message_lite.cc", __LINE__, "Failed to serialize protobuf message " + GetTypeName());
  28. + }
  29. + return s;
  30. +}
  31. +#endif
  32. +
  33. namespace internal {
  34. --- a/src/google/protobuf/message_lite.h
  35. +++ b/src/google/protobuf/message_lite.h
  36. @@ -469,6 +469,14 @@ class PROTOBUF_EXPORT MessageLite {
  37. return false;
  38. }
  39. + #if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view)
  40. + PROTOBUF_ATTRIBUTE_REINITIALIZES void ParseFromStringOrThrow(std::string_view s) noexcept(false);
  41. + #endif
  42. +
  43. + #if PROTOBUF_USE_EXCEPTIONS
  44. + TProtoStringType SerializeAsStringOrThrow() const noexcept(false);
  45. + #endif
  46. +
  47. private:
  48. friend class FastReflectionMessageMutator;
  49. friend class FastReflectionStringSetter;
  50. --- a/src/google/protobuf/stubs/common.cc (a305e8c438c21585e001abb5ada0122f6e1fc694)
  51. +++ a/src/google/protobuf/stubs/common.cc (109a04575819756fff3dc3e089008c9b1e971f85)
  52. @@ -159,6 +159,14 @@ arc_ui32 ghtonl(arc_ui32 x) {
  53. return result;
  54. }
  55. +#if PROTOBUF_USE_EXCEPTIONS
  56. +FatalException::~FatalException() throw() {}
  57. +
  58. +const char* FatalException::what() const throw() {
  59. + return message_.c_str();
  60. +}
  61. +#endif
  62. +
  63. } // namespace protobuf
  64. } // namespace google
  65. --- a/src/google/protobuf/stubs/common.h (a305e8c438c21585e001abb5ada0122f6e1fc694)
  66. +++ a/src/google/protobuf/stubs/common.h (109a04575819756fff3dc3e089008c9b1e971f85)
  67. @@ -45,6 +45,16 @@
  68. #include "google/protobuf/stubs/platform_macros.h"
  69. #include "google/protobuf/stubs/port.h"
  70. +#ifndef PROTOBUF_USE_EXCEPTIONS
  71. +#if defined(_MSC_VER) && defined(_CPPUNWIND)
  72. + #define PROTOBUF_USE_EXCEPTIONS 1
  73. +#elif defined(__EXCEPTIONS)
  74. + #define PROTOBUF_USE_EXCEPTIONS 1
  75. +#else
  76. + #define PROTOBUF_USE_EXCEPTIONS 0
  77. +#endif
  78. +#endif
  79. +
  80. #define Y_PROTOBUF_SUPPRESS_NODISCARD [[maybe_unused]] bool Y_GENERATE_UNIQUE_ID(pb_checker)=
  81. #if defined(__APPLE__)
  82. @@ -101,6 +111,26 @@ ProtocVersionString(int version); // NOLINT(runtime/string)
  83. } // namespace internal
  84. +#if PROTOBUF_USE_EXCEPTIONS
  85. +class FatalException : public std::exception {
  86. + public:
  87. + FatalException(const char* filename, int line, const TProtoStringType& message)
  88. + : filename_(filename), line_(line), message_(message) {}
  89. + virtual ~FatalException() throw();
  90. +
  91. + const char* what() const throw() override;
  92. +
  93. + const char* filename() const { return filename_; }
  94. + int line() const { return line_; }
  95. + const TProtoStringType& message() const { return message_; }
  96. +
  97. + private:
  98. + const char* filename_;
  99. + const int line_;
  100. + const TProtoStringType message_;
  101. +};
  102. +#endif
  103. +
  104. // Place this macro in your main() function (or somewhere before you attempt
  105. // to use the protobuf library) to verify that the version you link against
  106. // matches the headers you compiled against. If a version mismatch is