• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 //
12 // Contains classes used to keep track of unrecognized fields seen while
13 // parsing a protocol message.
14 
15 #ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
16 #define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
17 
18 #include <assert.h>
19 
20 #include <atomic>
21 #include <string>
22 
23 #include "google/protobuf/stubs/common.h"
24 #include "absl/log/absl_check.h"
25 #include "absl/strings/cord.h"
26 #include "absl/strings/string_view.h"
27 #include "google/protobuf/arena.h"
28 #include "google/protobuf/io/coded_stream.h"
29 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
30 #include "google/protobuf/message_lite.h"
31 #include "google/protobuf/metadata_lite.h"
32 #include "google/protobuf/parse_context.h"
33 #include "google/protobuf/port.h"
34 #include "google/protobuf/repeated_field.h"
35 
36 // Must be included last.
37 #include "google/protobuf/port_def.inc"
38 
39 #ifdef SWIG
40 #error "You cannot SWIG proto headers"
41 #endif
42 
43 namespace google {
44 namespace protobuf {
45 namespace internal {
46 class InternalMetadata;           // metadata_lite.h
47 class WireFormat;                 // wire_format.h
48 class MessageSetFieldSkipperUsingCord;
49 // extension_set_heavy.cc
50 class UnknownFieldParserHelper;
51 struct UnknownFieldSetTestPeer;
52 
53 #if defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
54 using UFSStringView = absl::string_view;
55 #else
56 using UFSStringView = const std::string&;
57 #endif
58 }  // namespace internal
59 
60 class Message;       // message.h
61 
62 // Represents one field in an UnknownFieldSet.
63 class PROTOBUF_EXPORT UnknownField {
64  public:
65   enum Type {
66     TYPE_VARINT,
67     TYPE_FIXED32,
68     TYPE_FIXED64,
69     TYPE_LENGTH_DELIMITED,
70     TYPE_GROUP
71   };
72 
73   // The field's field number, as seen on the wire.
74   inline int number() const;
75 
76   // The field type.
77   inline Type type() const;
78 
79   // Accessors -------------------------------------------------------
80   // Each method works only for UnknownFields of the corresponding type.
81 
82   inline uint64_t varint() const;
83   inline uint32_t fixed32() const;
84   inline uint64_t fixed64() const;
85   inline internal::UFSStringView length_delimited() const;
86   inline const UnknownFieldSet& group() const;
87 
88   inline void set_varint(uint64_t value);
89   inline void set_fixed32(uint32_t value);
90   inline void set_fixed64(uint64_t value);
91   inline void set_length_delimited(absl::string_view value);
92   // template to avoid ambiguous overload resolution.
93   template <int&...>
94   inline void set_length_delimited(std::string&& value);
95   inline void set_length_delimited(const absl::Cord& value);
96 #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
97   inline std::string* mutable_length_delimited();
98 #endif  // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
99   inline UnknownFieldSet* mutable_group();
100 
101   inline size_t GetLengthDelimitedSize() const;
102   uint8_t* InternalSerializeLengthDelimitedNoTag(
103       uint8_t* target, io::EpsCopyOutputStream* stream) const;
104 
105  private:
106   friend class UnknownFieldSet;
107 
108   // If this UnknownField contains a pointer, delete it.
109   void Delete();
110 
111   // Make a deep copy of any pointers in this UnknownField.
112   UnknownField DeepCopy(Arena* arena) const;
113 
114   // Set the wire type of this UnknownField. Should only be used when this
115   // UnknownField is being created.
116   inline void SetType(Type type);
117 
118   uint32_t number_;
119   uint32_t type_;
120   union {
121     uint64_t varint_;
122     uint32_t fixed32_;
123     uint64_t fixed64_;
124     std::string* string_value;
125     UnknownFieldSet* group_;
126   } data_;
127 };
128 
129 // An UnknownFieldSet contains fields that were encountered while parsing a
130 // message but were not defined by its type.  Keeping track of these can be
131 // useful, especially in that they may be written if the message is serialized
132 // again without being cleared in between.  This means that software which
133 // simply receives messages and forwards them to other servers does not need
134 // to be updated every time a new field is added to the message definition.
135 //
136 // To get the UnknownFieldSet attached to any message, call
137 // Reflection::GetUnknownFields().
138 //
139 // This class is necessarily tied to the protocol buffer wire format, unlike
140 // the Reflection interface which is independent of any serialization scheme.
141 class PROTOBUF_EXPORT UnknownFieldSet {
142  public:
143   constexpr UnknownFieldSet();
144   UnknownFieldSet(const UnknownFieldSet&) = delete;
145   UnknownFieldSet& operator=(const UnknownFieldSet&) = delete;
146   ~UnknownFieldSet();
147 
148   // Remove all fields.
149   inline void Clear();
150 
151   // Remove all fields and deallocate internal data objects
152   void ClearAndFreeMemory();
153 
154   // Is this set empty?
155   inline bool empty() const;
156 
157   // Merge the contents of some other UnknownFieldSet with this one.
158   void MergeFrom(const UnknownFieldSet& other);
159 
160   // Similar to above, but this function will destroy the contents of other.
161   void MergeFromAndDestroy(UnknownFieldSet* other);
162 
163   // Merge the contents an UnknownFieldSet with the UnknownFieldSet in
164   // *metadata, if there is one.  If *metadata doesn't have an UnknownFieldSet
165   // then add one to it and make it be a copy of the first arg.
166   static void MergeToInternalMetadata(const UnknownFieldSet& other,
167                                       internal::InternalMetadata* metadata);
168 
169   // Swaps the contents of some other UnknownFieldSet with this one.
170   inline void Swap(UnknownFieldSet* x);
171 
172   // Computes (an estimate of) the total number of bytes currently used for
173   // storing the unknown fields in memory. Does NOT include
174   // sizeof(*this) in the calculation.
175   size_t SpaceUsedExcludingSelfLong() const;
176 
SpaceUsedExcludingSelf()177   int SpaceUsedExcludingSelf() const {
178     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
179   }
180 
181   // Version of SpaceUsed() including sizeof(*this).
182   size_t SpaceUsedLong() const;
183 
SpaceUsed()184   int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); }
185 
186   // Returns the number of fields present in the UnknownFieldSet.
187   inline int field_count() const;
188   // Get a field in the set, where 0 <= index < field_count().  The fields
189   // appear in the order in which they were added.
190   inline const UnknownField& field(int index) const;
191   // Get a mutable pointer to a field in the set, where
192   // 0 <= index < field_count().  The fields appear in the order in which
193   // they were added.
194   inline UnknownField* mutable_field(int index);
195 
196   // Adding fields ---------------------------------------------------
197 
198   void AddVarint(int number, uint64_t value);
199   void AddFixed32(int number, uint32_t value);
200   void AddFixed64(int number, uint64_t value);
201   void AddLengthDelimited(int number, absl::string_view value);
202   // template to avoid ambiguous overload resolution.
203   template <int&...>
204   void AddLengthDelimited(int number, std::string&& value);
205   void AddLengthDelimited(int number, const absl::Cord& value);
206 
207 #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
208   std::string* AddLengthDelimited(int number);
209 #endif  // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
210   UnknownFieldSet* AddGroup(int number);
211 
212   // Adds an unknown field from another set.
213   void AddField(const UnknownField& field);
214 
215   // Delete fields with indices in the range [start .. start+num-1].
216   // Caution: implementation moves all fields with indices [start+num .. ].
217   void DeleteSubrange(int start, int num);
218 
219   // Delete all fields with a specific field number. The order of left fields
220   // is preserved.
221   // Caution: implementation moves all fields after the first deleted field.
222   void DeleteByNumber(int number);
223 
224   // Parsing helpers -------------------------------------------------
225   // These work exactly like the similarly-named methods of Message.
226 
227   bool MergeFromCodedStream(io::CodedInputStream* input);
228   bool ParseFromCodedStream(io::CodedInputStream* input);
229   bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
230   bool ParseFromArray(const void* data, int size);
ParseFromString(const absl::string_view data)231   inline bool ParseFromString(const absl::string_view data) {
232     return ParseFromArray(data.data(), static_cast<int>(data.size()));
233   }
234 
235   // Merges this message's unknown field data (if any).  This works whether
236   // the message is a lite or full proto (for legacy reasons, lite and full
237   // return different types for MessageType::unknown_fields()).
238   template <typename MessageType>
239   bool MergeFromMessage(const MessageType& message);
240 
241   // Serialization.
242   bool SerializeToString(std::string* output) const;
243   bool SerializeToCord(absl::Cord* output) const;
244   bool SerializeToCodedStream(io::CodedOutputStream* output) const;
245   static const UnknownFieldSet& default_instance();
246 
UnknownFieldSet(internal::InternalVisibility,Arena * arena)247   UnknownFieldSet(internal::InternalVisibility, Arena* arena)
248       : UnknownFieldSet(arena) {}
249 
250  private:
251   friend internal::WireFormat;
252   friend internal::UnknownFieldParserHelper;
253   friend internal::UnknownFieldSetTestPeer;
254 
255 #if defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
256   std::string* AddLengthDelimited(int number);
257 #endif  // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
258 
259   using InternalArenaConstructable_ = void;
260   using DestructorSkippable_ = void;
261 
262   friend class google::protobuf::Arena;
UnknownFieldSet(Arena * arena)263   explicit UnknownFieldSet(Arena* arena) : fields_(arena) {}
264 
arena()265   Arena* arena() { return fields_.GetArena(); }
266 
267   void ClearFallback();
268   void SwapSlow(UnknownFieldSet* other);
269 
270   template <typename MessageType,
271             typename std::enable_if<
272                 std::is_base_of<Message, MessageType>::value, int>::type = 0>
InternalMergeFromMessage(const MessageType & message)273   bool InternalMergeFromMessage(const MessageType& message) {
274     MergeFrom(message.GetReflection()->GetUnknownFields(message));
275     return true;
276   }
277 
278   template <typename MessageType,
279             typename std::enable_if<
280                 std::is_base_of<MessageLite, MessageType>::value &&
281                     !std::is_base_of<Message, MessageType>::value,
282                 int>::type = 0>
InternalMergeFromMessage(const MessageType & message)283   bool InternalMergeFromMessage(const MessageType& message) {
284     const auto& unknown_fields = message.unknown_fields();
285     io::ArrayInputStream array_stream(unknown_fields.data(),
286                                       unknown_fields.size());
287     io::CodedInputStream coded_stream(&array_stream);
288     return MergeFromCodedStream(&coded_stream);
289   }
290 
291   RepeatedField<UnknownField> fields_;
292 };
293 
294 namespace internal {
295 
WriteVarint(uint32_t num,uint64_t val,UnknownFieldSet * unknown)296 inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* unknown) {
297   unknown->AddVarint(num, val);
298 }
WriteLengthDelimited(uint32_t num,absl::string_view val,UnknownFieldSet * unknown)299 inline void WriteLengthDelimited(uint32_t num, absl::string_view val,
300                                  UnknownFieldSet* unknown) {
301   unknown->AddLengthDelimited(num, val);
302 }
303 
304 PROTOBUF_EXPORT
305 const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr,
306                               ParseContext* ctx);
307 PROTOBUF_EXPORT
308 const char* UnknownFieldParse(uint64_t tag, UnknownFieldSet* unknown,
309                               const char* ptr, ParseContext* ctx);
310 
311 }  // namespace internal
312 
313 // ===================================================================
314 // inline implementations
315 
316 constexpr UnknownFieldSet::UnknownFieldSet() = default;
317 
~UnknownFieldSet()318 inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
319 
default_instance()320 inline const UnknownFieldSet& UnknownFieldSet::default_instance() {
321   PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT static const UnknownFieldSet
322       instance;
323   return instance;
324 }
325 
ClearAndFreeMemory()326 inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
327 
Clear()328 inline void UnknownFieldSet::Clear() {
329   if (!fields_.empty()) {
330     ClearFallback();
331   }
332 }
333 
empty()334 inline bool UnknownFieldSet::empty() const { return fields_.empty(); }
335 
Swap(UnknownFieldSet * x)336 inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
337   if (arena() == x->arena()) {
338     fields_.Swap(&x->fields_);
339   } else {
340     // We might need to do a deep copy, so use Merge instead
341     SwapSlow(x);
342   }
343 }
344 
field_count()345 inline int UnknownFieldSet::field_count() const {
346   return static_cast<int>(fields_.size());
347 }
field(int index)348 inline const UnknownField& UnknownFieldSet::field(int index) const {
349   return (fields_)[static_cast<size_t>(index)];
350 }
mutable_field(int index)351 inline UnknownField* UnknownFieldSet::mutable_field(int index) {
352   return &(fields_)[static_cast<size_t>(index)];
353 }
354 
AddLengthDelimited(int number,const absl::string_view value)355 inline void UnknownFieldSet::AddLengthDelimited(int number,
356                                                 const absl::string_view value) {
357   AddLengthDelimited(number)->assign(value.data(), value.size());
358 }
359 
number()360 inline int UnknownField::number() const { return static_cast<int>(number_); }
type()361 inline UnknownField::Type UnknownField::type() const {
362   return static_cast<Type>(type_);
363 }
364 
varint()365 inline uint64_t UnknownField::varint() const {
366   assert(type() == TYPE_VARINT);
367   return data_.varint_;
368 }
fixed32()369 inline uint32_t UnknownField::fixed32() const {
370   assert(type() == TYPE_FIXED32);
371   return data_.fixed32_;
372 }
fixed64()373 inline uint64_t UnknownField::fixed64() const {
374   assert(type() == TYPE_FIXED64);
375   return data_.fixed64_;
376 }
length_delimited()377 inline internal::UFSStringView UnknownField::length_delimited() const {
378   assert(type() == TYPE_LENGTH_DELIMITED);
379   return *data_.string_value;
380 }
group()381 inline const UnknownFieldSet& UnknownField::group() const {
382   assert(type() == TYPE_GROUP);
383   return *data_.group_;
384 }
385 
set_varint(uint64_t value)386 inline void UnknownField::set_varint(uint64_t value) {
387   assert(type() == TYPE_VARINT);
388   data_.varint_ = value;
389 }
set_fixed32(uint32_t value)390 inline void UnknownField::set_fixed32(uint32_t value) {
391   assert(type() == TYPE_FIXED32);
392   data_.fixed32_ = value;
393 }
set_fixed64(uint64_t value)394 inline void UnknownField::set_fixed64(uint64_t value) {
395   assert(type() == TYPE_FIXED64);
396   data_.fixed64_ = value;
397 }
set_length_delimited(const absl::string_view value)398 inline void UnknownField::set_length_delimited(const absl::string_view value) {
399   assert(type() == TYPE_LENGTH_DELIMITED);
400   data_.string_value->assign(value.data(), value.size());
401 }
402 template <int&...>
set_length_delimited(std::string && value)403 inline void UnknownField::set_length_delimited(std::string&& value) {
404   assert(type() == TYPE_LENGTH_DELIMITED);
405   *data_.string_value = std::move(value);
406 }
set_length_delimited(const absl::Cord & value)407 inline void UnknownField::set_length_delimited(const absl::Cord& value) {
408   assert(type() == TYPE_LENGTH_DELIMITED);
409   absl::CopyCordToString(value, data_.string_value);
410 }
411 #if !defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)
mutable_length_delimited()412 inline std::string* UnknownField::mutable_length_delimited() {
413   assert(type() == TYPE_LENGTH_DELIMITED);
414   return data_.string_value;
415 }
416 #endif  // PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
mutable_group()417 inline UnknownFieldSet* UnknownField::mutable_group() {
418   assert(type() == TYPE_GROUP);
419   return data_.group_;
420 }
421 template <typename MessageType>
MergeFromMessage(const MessageType & message)422 bool UnknownFieldSet::MergeFromMessage(const MessageType& message) {
423   // SFINAE will route to the right version.
424   return InternalMergeFromMessage(message);
425 }
426 
GetLengthDelimitedSize()427 inline size_t UnknownField::GetLengthDelimitedSize() const {
428   ABSL_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
429   return data_.string_value->size();
430 }
431 
SetType(Type type)432 inline void UnknownField::SetType(Type type) { type_ = type; }
433 
434 extern template void UnknownFieldSet::AddLengthDelimited(int, std::string&&);
435 
436 namespace internal {
437 
438 // Add specialization of InternalMetadata::Container to provide arena support.
439 template <>
440 struct InternalMetadata::Container<UnknownFieldSet>
441     : public InternalMetadata::ContainerBase {
442   UnknownFieldSet unknown_fields;
443 
444   explicit Container(Arena* input_arena)
445       : unknown_fields(InternalVisibility{}, input_arena) {}
446 
447   using InternalArenaConstructable_ = void;
448   using DestructorSkippable_ = void;
449 };
450 }  // namespace internal
451 
452 }  // namespace protobuf
453 }  // namespace google
454 
455 #include "google/protobuf/port_undef.inc"
456 #endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
457