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