aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/protobuf/patches/or_throw_methods.patch
blob: 68ba6099b05984faa1a17921c9d0b0883dc73a3f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -514,6 +514,33 @@ TProtoStringType MessageLite::SerializePartialAsString() const {
   return output;
 }
 
+#if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view)
+void MessageLite::ParseFromStringOrThrow(std::string_view s) {
+  const bool isOk = ParseFromArray(s.data(), s.size());
+  if (!isOk) {
+    throw FatalException("message_lite.cc", __LINE__, "Failed to parse protobuf message " + GetTypeName());
+  }
+}
+#endif
+
+#if PROTOBUF_USE_EXCEPTIONS
+TProtoStringType NProtoBuf::MessageLite::SerializeAsStringOrThrow() const {
+  TProtoStringType s;
+  if (!IsInitialized()) {
+    //NOTE: SerializeToString (called inside SerializeAsString too) does not perform this check in release build
+    //    so SerializeToString in release build return false only if result size is greater than 2gb
+    //    but in debug build not properly inited message (without required filds) will lead to an exception
+    //    different control flow in debug and build release look like a bug
+    throw FatalException("message_lite.cc", __LINE__, "Some required fileds are not set in message " + GetTypeName());
+  }
+  const bool isOk = SerializeToString(&s);
+  if (!isOk) {
+    throw FatalException("message_lite.cc", __LINE__, "Failed to serialize protobuf message " + GetTypeName());
+  }
+  return s;
+}
+#endif
+
 
 namespace internal {
 
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -469,6 +469,14 @@ class PROTOBUF_EXPORT MessageLite {
     return false;
   }
 
+  #if PROTOBUF_USE_EXCEPTIONS && defined(__cpp_lib_string_view)
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void ParseFromStringOrThrow(std::string_view s) noexcept(false);
+  #endif
+
+  #if PROTOBUF_USE_EXCEPTIONS
+  TProtoStringType SerializeAsStringOrThrow() const noexcept(false);
+  #endif
+
  private:
   friend class FastReflectionMessageMutator;
   friend class FastReflectionStringSetter;

--- a/src/google/protobuf/stubs/common.cc	(a305e8c438c21585e001abb5ada0122f6e1fc694)
+++ a/src/google/protobuf/stubs/common.cc	(109a04575819756fff3dc3e089008c9b1e971f85)
@@ -159,6 +159,14 @@ arc_ui32 ghtonl(arc_ui32 x) {
   return result;
 }
 
+#if PROTOBUF_USE_EXCEPTIONS
+FatalException::~FatalException() throw() {}
+
+const char* FatalException::what() const throw() {
+  return message_.c_str();
+}
+#endif
+
 }  // namespace protobuf
 }  // namespace google
 
--- a/src/google/protobuf/stubs/common.h	(a305e8c438c21585e001abb5ada0122f6e1fc694)
+++ a/src/google/protobuf/stubs/common.h	(109a04575819756fff3dc3e089008c9b1e971f85)
@@ -45,6 +45,16 @@
 #include "google/protobuf/stubs/platform_macros.h"
 #include "google/protobuf/stubs/port.h"
 
+#ifndef PROTOBUF_USE_EXCEPTIONS
+#if defined(_MSC_VER) && defined(_CPPUNWIND)
+  #define PROTOBUF_USE_EXCEPTIONS 1
+#elif defined(__EXCEPTIONS)
+  #define PROTOBUF_USE_EXCEPTIONS 1
+#else
+  #define PROTOBUF_USE_EXCEPTIONS 0
+#endif
+#endif
+
 #define Y_PROTOBUF_SUPPRESS_NODISCARD [[maybe_unused]] bool Y_GENERATE_UNIQUE_ID(pb_checker)=
 
 #if defined(__APPLE__)
@@ -101,6 +111,26 @@ ProtocVersionString(int version);  // NOLINT(runtime/string)
 
 }  // namespace internal
 
+#if PROTOBUF_USE_EXCEPTIONS
+class FatalException : public std::exception {
+ public:
+  FatalException(const char* filename, int line, const TProtoStringType& message)
+      : filename_(filename), line_(line), message_(message) {}
+  virtual ~FatalException() throw();
+
+  const char* what() const throw() override;
+
+  const char* filename() const { return filename_; }
+  int line() const { return line_; }
+  const TProtoStringType& message() const { return message_; }
+
+ private:
+  const char* filename_;
+  const int line_;
+  const TProtoStringType message_;
+};
+#endif
+
 // Place this macro in your main() function (or somewhere before you attempt
 // to use the protobuf library) to verify that the version you link against
 // matches the headers you compiled against.  If a version mismatch is