1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // Contains classes used to keep track of unrecognized fields seen while
36 // parsing a protocol message.
37 
38 #ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
39 #define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
40 
41 #include <assert.h>
42 #include <string>
43 #include <vector>
44 #include <google/protobuf/stubs/common.h>
45 #include <google/protobuf/stubs/logging.h>
46 #include <google/protobuf/parse_context.h>
47 #include <google/protobuf/io/coded_stream.h>
48 #include <google/protobuf/message_lite.h>
49 #include <google/protobuf/port.h>
50 
51 #include <google/protobuf/port_def.inc>
52 
53 #ifdef SWIG
54 #error "You cannot SWIG proto headers"
55 #endif
56 
57 namespace google {
58 namespace protobuf {
59 namespace io {
60 class CodedInputStream;     // coded_stream.h
61 class CodedOutputStream;    // coded_stream.h
62 class ZeroCopyInputStream;  // zero_copy_stream.h
63 }  // namespace io
64 namespace internal {
65 class InternalMetadataWithArena;  // metadata.h
66 class WireFormat;                 // wire_format.h
67 class MessageSetFieldSkipperUsingCord;
68 // extension_set_heavy.cc
69 }  // namespace internal
70 
71 class Message;       // message.h
72 class UnknownField;  // below
73 
74 // An UnknownFieldSet contains fields that were encountered while parsing a
75 // message but were not defined by its type.  Keeping track of these can be
76 // useful, especially in that they may be written if the message is serialized
77 // again without being cleared in between.  This means that software which
78 // simply receives messages and forwards them to other servers does not need
79 // to be updated every time a new field is added to the message definition.
80 //
81 // To get the UnknownFieldSet attached to any message, call
82 // Reflection::GetUnknownFields().
83 //
84 // This class is necessarily tied to the protocol buffer wire format, unlike
85 // the Reflection interface which is independent of any serialization scheme.
86 class PROTOBUF_EXPORT UnknownFieldSet {
87  public:
88   UnknownFieldSet();
89   ~UnknownFieldSet();
90 
91   // Remove all fields.
92   inline void Clear();
93 
94   // Remove all fields and deallocate internal data objects
95   void ClearAndFreeMemory();
96 
97   // Is this set empty?
98   inline bool empty() const;
99 
100   // Merge the contents of some other UnknownFieldSet with this one.
101   void MergeFrom(const UnknownFieldSet& other);
102 
103   // Similar to above, but this function will destroy the contents of other.
104   void MergeFromAndDestroy(UnknownFieldSet* other);
105 
106   // Merge the contents an UnknownFieldSet with the UnknownFieldSet in
107   // *metadata, if there is one.  If *metadata doesn't have an UnknownFieldSet
108   // then add one to it and make it be a copy of the first arg.
109   static void MergeToInternalMetdata(
110       const UnknownFieldSet& other,
111       internal::InternalMetadataWithArena* metadata);
112 
113   // Swaps the contents of some other UnknownFieldSet with this one.
114   inline void Swap(UnknownFieldSet* x);
115 
116   // Computes (an estimate of) the total number of bytes currently used for
117   // storing the unknown fields in memory. Does NOT include
118   // sizeof(*this) in the calculation.
119   size_t SpaceUsedExcludingSelfLong() const;
120 
SpaceUsedExcludingSelf()121   int SpaceUsedExcludingSelf() const {
122     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
123   }
124 
125   // Version of SpaceUsed() including sizeof(*this).
126   size_t SpaceUsedLong() const;
127 
SpaceUsed()128   int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); }
129 
130   // Returns the number of fields present in the UnknownFieldSet.
131   inline int field_count() const;
132   // Get a field in the set, where 0 <= index < field_count().  The fields
133   // appear in the order in which they were added.
134   inline const UnknownField& field(int index) const;
135   // Get a mutable pointer to a field in the set, where
136   // 0 <= index < field_count().  The fields appear in the order in which
137   // they were added.
138   inline UnknownField* mutable_field(int index);
139 
140   // Adding fields ---------------------------------------------------
141 
142   void AddVarint(int number, uint64 value);
143   void AddFixed32(int number, uint32 value);
144   void AddFixed64(int number, uint64 value);
145   void AddLengthDelimited(int number, const std::string& value);
146   std::string* AddLengthDelimited(int number);
147   UnknownFieldSet* AddGroup(int number);
148 
149   // Adds an unknown field from another set.
150   void AddField(const UnknownField& field);
151 
152   // Delete fields with indices in the range [start .. start+num-1].
153   // Caution: implementation moves all fields with indices [start+num .. ].
154   void DeleteSubrange(int start, int num);
155 
156   // Delete all fields with a specific field number. The order of left fields
157   // is preserved.
158   // Caution: implementation moves all fields after the first deleted field.
159   void DeleteByNumber(int number);
160 
161   // Parsing helpers -------------------------------------------------
162   // These work exactly like the similarly-named methods of Message.
163 
164   bool MergeFromCodedStream(io::CodedInputStream* input);
165   bool ParseFromCodedStream(io::CodedInputStream* input);
166   bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
167   bool ParseFromArray(const void* data, int size);
ParseFromString(const std::string & data)168   inline bool ParseFromString(const std::string& data) {
169     return ParseFromArray(data.data(), static_cast<int>(data.size()));
170   }
171 
172   static const UnknownFieldSet* default_instance();
173 
174  private:
175   // For InternalMergeFrom
176   friend class UnknownField;
177   // Merges from other UnknownFieldSet. This method assumes, that this object
178   // is newly created and has no fields.
179   void InternalMergeFrom(const UnknownFieldSet& other);
180   void ClearFallback();
181 
182   std::vector<UnknownField> fields_;
183   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
184 };
185 
186 #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
187 namespace internal {
188 
WriteVarint(uint32 num,uint64 val,UnknownFieldSet * unknown)189 inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* unknown) {
190   unknown->AddVarint(num, val);
191 }
WriteLengthDelimited(uint32 num,StringPiece val,UnknownFieldSet * unknown)192 inline void WriteLengthDelimited(uint32 num, StringPiece val,
193                                  UnknownFieldSet* unknown) {
194   unknown->AddLengthDelimited(num)->assign(val.data(), val.size());
195 }
196 
197 PROTOBUF_EXPORT
198 const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
199                              bool (*is_valid)(int),
200                              InternalMetadataWithArena* unknown, int field_num);
201 PROTOBUF_EXPORT
202 const char* PackedEnumParserArg(void* object, const char* ptr,
203                                 ParseContext* ctx,
204                                 bool (*is_valid)(const void*, int),
205                                 const void* data,
206                                 InternalMetadataWithArena* unknown,
207                                 int field_num);
208 
209 PROTOBUF_EXPORT
210 const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr,
211                               ParseContext* ctx);
212 PROTOBUF_EXPORT
213 const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown,
214                               const char* ptr, ParseContext* ctx);
215 PROTOBUF_EXPORT
216 const char* UnknownFieldParse(uint32 tag, InternalMetadataWithArena* metadata,
217                               const char* ptr, ParseContext* ctx);
218 
219 }  // namespace internal
220 #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
221 
222 // Represents one field in an UnknownFieldSet.
223 class PROTOBUF_EXPORT UnknownField {
224  public:
225   enum Type {
226     TYPE_VARINT,
227     TYPE_FIXED32,
228     TYPE_FIXED64,
229     TYPE_LENGTH_DELIMITED,
230     TYPE_GROUP
231   };
232 
233   // The field's field number, as seen on the wire.
234   inline int number() const;
235 
236   // The field type.
237   inline Type type() const;
238 
239   // Accessors -------------------------------------------------------
240   // Each method works only for UnknownFields of the corresponding type.
241 
242   inline uint64 varint() const;
243   inline uint32 fixed32() const;
244   inline uint64 fixed64() const;
245   inline const std::string& length_delimited() const;
246   inline const UnknownFieldSet& group() const;
247 
248   inline void set_varint(uint64 value);
249   inline void set_fixed32(uint32 value);
250   inline void set_fixed64(uint64 value);
251   inline void set_length_delimited(const std::string& value);
252   inline std::string* mutable_length_delimited();
253   inline UnknownFieldSet* mutable_group();
254 
255   // Serialization API.
256   // These methods can take advantage of the underlying implementation and may
257   // archieve a better performance than using getters to retrieve the data and
258   // do the serialization yourself.
259   void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
260   uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
261 
262   inline size_t GetLengthDelimitedSize() const;
263 
264 
265   // If this UnknownField contains a pointer, delete it.
266   void Delete();
267 
268   // Make a deep copy of any pointers in this UnknownField.
269   void DeepCopy(const UnknownField& other);
270 
271   // Set the wire type of this UnknownField. Should only be used when this
272   // UnknownField is being created.
273   inline void SetType(Type type);
274 
275   union LengthDelimited {
276     std::string* string_value;
277   };
278 
279   uint32 number_;
280   uint32 type_;
281   union {
282     uint64 varint_;
283     uint32 fixed32_;
284     uint64 fixed64_;
285     mutable union LengthDelimited length_delimited_;
286     UnknownFieldSet* group_;
287   } data_;
288 };
289 
290 // ===================================================================
291 // inline implementations
292 
UnknownFieldSet()293 inline UnknownFieldSet::UnknownFieldSet() {}
294 
~UnknownFieldSet()295 inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
296 
ClearAndFreeMemory()297 inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
298 
Clear()299 inline void UnknownFieldSet::Clear() {
300   if (!fields_.empty()) {
301     ClearFallback();
302   }
303 }
304 
empty()305 inline bool UnknownFieldSet::empty() const { return fields_.empty(); }
306 
Swap(UnknownFieldSet * x)307 inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
308   fields_.swap(x->fields_);
309 }
310 
field_count()311 inline int UnknownFieldSet::field_count() const {
312   return static_cast<int>(fields_.size());
313 }
field(int index)314 inline const UnknownField& UnknownFieldSet::field(int index) const {
315   return (fields_)[static_cast<size_t>(index)];
316 }
mutable_field(int index)317 inline UnknownField* UnknownFieldSet::mutable_field(int index) {
318   return &(fields_)[static_cast<size_t>(index)];
319 }
320 
AddLengthDelimited(int number,const std::string & value)321 inline void UnknownFieldSet::AddLengthDelimited(int number,
322                                                 const std::string& value) {
323   AddLengthDelimited(number)->assign(value);
324 }
325 
326 
327 
328 
number()329 inline int UnknownField::number() const { return static_cast<int>(number_); }
type()330 inline UnknownField::Type UnknownField::type() const {
331   return static_cast<Type>(type_);
332 }
333 
varint()334 inline uint64 UnknownField::varint() const {
335   assert(type() == TYPE_VARINT);
336   return data_.varint_;
337 }
fixed32()338 inline uint32 UnknownField::fixed32() const {
339   assert(type() == TYPE_FIXED32);
340   return data_.fixed32_;
341 }
fixed64()342 inline uint64 UnknownField::fixed64() const {
343   assert(type() == TYPE_FIXED64);
344   return data_.fixed64_;
345 }
length_delimited()346 inline const std::string& UnknownField::length_delimited() const {
347   assert(type() == TYPE_LENGTH_DELIMITED);
348   return *data_.length_delimited_.string_value;
349 }
group()350 inline const UnknownFieldSet& UnknownField::group() const {
351   assert(type() == TYPE_GROUP);
352   return *data_.group_;
353 }
354 
set_varint(uint64 value)355 inline void UnknownField::set_varint(uint64 value) {
356   assert(type() == TYPE_VARINT);
357   data_.varint_ = value;
358 }
set_fixed32(uint32 value)359 inline void UnknownField::set_fixed32(uint32 value) {
360   assert(type() == TYPE_FIXED32);
361   data_.fixed32_ = value;
362 }
set_fixed64(uint64 value)363 inline void UnknownField::set_fixed64(uint64 value) {
364   assert(type() == TYPE_FIXED64);
365   data_.fixed64_ = value;
366 }
set_length_delimited(const std::string & value)367 inline void UnknownField::set_length_delimited(const std::string& value) {
368   assert(type() == TYPE_LENGTH_DELIMITED);
369   data_.length_delimited_.string_value->assign(value);
370 }
mutable_length_delimited()371 inline std::string* UnknownField::mutable_length_delimited() {
372   assert(type() == TYPE_LENGTH_DELIMITED);
373   return data_.length_delimited_.string_value;
374 }
mutable_group()375 inline UnknownFieldSet* UnknownField::mutable_group() {
376   assert(type() == TYPE_GROUP);
377   return data_.group_;
378 }
379 
GetLengthDelimitedSize()380 inline size_t UnknownField::GetLengthDelimitedSize() const {
381   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
382   return data_.length_delimited_.string_value->size();
383 }
384 
SetType(Type type)385 inline void UnknownField::SetType(Type type) {
386   type_ = type;
387 }
388 
389 
390 }  // namespace protobuf
391 }  // namespace google
392 
393 #include <google/protobuf/port_undef.inc>
394 #endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
395