24
24
#include " absl/log/absl_check.h"
25
25
#include " absl/strings/cord.h"
26
26
#include " absl/strings/string_view.h"
27
+ #include " absl/types/span.h"
27
28
#include " google/protobuf/arena.h"
28
29
#include " google/protobuf/io/coded_stream.h"
29
30
#include " google/protobuf/io/zero_copy_stream_impl_lite.h"
@@ -47,6 +48,8 @@ class InternalMetadata; // metadata_lite.h
47
48
class WireFormat ; // wire_format.h
48
49
class MessageSetFieldSkipperUsingCord ;
49
50
// extension_set_heavy.cc
51
+ class UnknownFieldParserHelper ;
52
+ struct UnknownFieldSetTestPeer ;
50
53
51
54
#if defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
52
55
using UFSStringView = absl::string_view;
@@ -87,7 +90,13 @@ class PROTOBUF_EXPORT UnknownField {
87
90
inline void set_fixed32 (uint32_t value);
88
91
inline void set_fixed64 (uint64_t value);
89
92
inline void set_length_delimited (absl::string_view value);
93
+ // template to avoid ambiguous overload resolution.
94
+ template <int &...>
95
+ inline void set_length_delimited (std::string&& value);
96
+ inline void set_length_delimited (const absl::Cord& value);
97
+ #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
90
98
inline std::string* mutable_length_delimited ();
99
+ #endif // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
91
100
inline UnknownFieldSet* mutable_group ();
92
101
93
102
inline size_t GetLengthDelimitedSize () const ;
@@ -191,7 +200,14 @@ class PROTOBUF_EXPORT UnknownFieldSet {
191
200
void AddFixed32 (int number, uint32_t value);
192
201
void AddFixed64 (int number, uint64_t value);
193
202
void AddLengthDelimited (int number, absl::string_view value);
203
+ // template to avoid ambiguous overload resolution.
204
+ template <int &...>
205
+ void AddLengthDelimited (int number, std::string&& value);
206
+ void AddLengthDelimited (int number, const absl::Cord& value);
207
+
208
+ #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
194
209
std::string* AddLengthDelimited (int number);
210
+ #endif // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
195
211
UnknownFieldSet* AddGroup (int number);
196
212
197
213
// Adds an unknown field from another set.
@@ -233,6 +249,10 @@ class PROTOBUF_EXPORT UnknownFieldSet {
233
249
: UnknownFieldSet(arena) {}
234
250
235
251
private:
252
+ friend internal::WireFormat;
253
+ friend internal::UnknownFieldParserHelper;
254
+ friend internal::UnknownFieldSetTestPeer;
255
+
236
256
using InternalArenaConstructable_ = void ;
237
257
using DestructorSkippable_ = void ;
238
258
@@ -241,6 +261,14 @@ class PROTOBUF_EXPORT UnknownFieldSet {
241
261
242
262
Arena* arena () { return fields_.GetArena (); }
243
263
264
+ // Returns a buffer of `size` chars for the user to fill in.
265
+ // The buffer is potentially uninitialized memory. Failing to write to it
266
+ // might lead to undefined behavior when reading it later.
267
+ // Prefer the overloads above when possible. Calling this API without
268
+ // validating the `size` parameter can lead to unintentional memory usage and
269
+ // potential OOM.
270
+ absl::Span<char > AddLengthDelimitedUninitialized (int number, size_t size);
271
+
244
272
void ClearFallback ();
245
273
void SwapSlow (UnknownFieldSet* other);
246
274
@@ -275,7 +303,7 @@ inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* unknown) {
275
303
}
276
304
inline void WriteLengthDelimited (uint32_t num, absl::string_view val,
277
305
UnknownFieldSet* unknown) {
278
- unknown->AddLengthDelimited (num)-> assign (val. data () , val. size () );
306
+ unknown->AddLengthDelimited (num, val);
279
307
}
280
308
281
309
PROTOBUF_EXPORT
@@ -331,7 +359,10 @@ inline UnknownField* UnknownFieldSet::mutable_field(int index) {
331
359
332
360
inline void UnknownFieldSet::AddLengthDelimited (int number,
333
361
const absl::string_view value) {
334
- AddLengthDelimited (number)->assign (value.data (), value.size ());
362
+ auto field = AddLengthDelimitedUninitialized (number, value.size ());
363
+ if (!value.empty ()) {
364
+ memcpy (field.data (), value.data (), value.size ());
365
+ }
335
366
}
336
367
337
368
inline int UnknownField::number () const { return static_cast <int >(number_); }
@@ -376,10 +407,21 @@ inline void UnknownField::set_length_delimited(const absl::string_view value) {
376
407
assert (type () == TYPE_LENGTH_DELIMITED);
377
408
data_.string_value ->assign (value.data (), value.size ());
378
409
}
410
+ template <int &...>
411
+ inline void UnknownField::set_length_delimited (std::string&& value) {
412
+ assert (type () == TYPE_LENGTH_DELIMITED);
413
+ *data_.string_value = std::move (value);
414
+ }
415
+ inline void UnknownField::set_length_delimited (const absl::Cord& value) {
416
+ assert (type () == TYPE_LENGTH_DELIMITED);
417
+ absl::CopyCordToString (value, data_.string_value );
418
+ }
419
+ #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
379
420
inline std::string* UnknownField::mutable_length_delimited () {
380
421
assert (type () == TYPE_LENGTH_DELIMITED);
381
422
return data_.string_value ;
382
423
}
424
+ #endif // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
383
425
inline UnknownFieldSet* UnknownField::mutable_group () {
384
426
assert (type () == TYPE_GROUP);
385
427
return data_.group_ ;
@@ -397,6 +439,8 @@ inline size_t UnknownField::GetLengthDelimitedSize() const {
397
439
398
440
inline void UnknownField::SetType (Type type) { type_ = type; }
399
441
442
+ extern template void UnknownFieldSet::AddLengthDelimited (int , std::string&&);
443
+
400
444
namespace internal {
401
445
402
446
// Add specialization of InternalMetadata::Container to provide arena support.
0 commit comments