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: [email protected] (Joseph Schorr) |
32 | // Based on original Protocol Buffers design by |
33 | // Sanjay Ghemawat, Jeff Dean, and others. |
34 | // |
35 | // Utilities for printing and parsing protocol messages in a human-readable, |
36 | // text-based format. |
37 | |
38 | #ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ |
39 | #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ |
40 | |
41 | #include <map> |
42 | #include <memory> |
43 | #include <string> |
44 | #include <vector> |
45 | |
46 | #include <google/protobuf/stubs/common.h> |
47 | #include <google/protobuf/descriptor.h> |
48 | #include <google/protobuf/message.h> |
49 | #include <google/protobuf/message_lite.h> |
50 | #include <google/protobuf/port.h> |
51 | |
52 | #include <google/protobuf/port_def.inc> |
53 | |
54 | #ifdef SWIG |
55 | #error "You cannot SWIG proto headers" |
56 | #endif |
57 | |
58 | namespace google { |
59 | namespace protobuf { |
60 | |
61 | namespace io { |
62 | class ErrorCollector; // tokenizer.h |
63 | } |
64 | |
65 | // This class implements protocol buffer text format. Printing and parsing |
66 | // protocol messages in text format is useful for debugging and human editing |
67 | // of messages. |
68 | // |
69 | // This class is really a namespace that contains only static methods. |
70 | class PROTOBUF_EXPORT TextFormat { |
71 | public: |
72 | // Outputs a textual representation of the given message to the given |
73 | // output stream. Returns false if printing fails. |
74 | static bool Print(const Message& message, io::ZeroCopyOutputStream* output); |
75 | |
76 | // Print the fields in an UnknownFieldSet. They are printed by tag number |
77 | // only. Embedded messages are heuristically identified by attempting to |
78 | // parse them. Returns false if printing fails. |
79 | static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
80 | io::ZeroCopyOutputStream* output); |
81 | |
82 | // Like Print(), but outputs directly to a string. |
83 | // Note: output will be cleared prior to printing, and will be left empty |
84 | // even if printing fails. Returns false if printing fails. |
85 | static bool PrintToString(const Message& message, std::string* output); |
86 | |
87 | // Like PrintUnknownFields(), but outputs directly to a string. Returns |
88 | // false if printing fails. |
89 | static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, |
90 | std::string* output); |
91 | |
92 | // Outputs a textual representation of the value of the field supplied on |
93 | // the message supplied. For non-repeated fields, an index of -1 must |
94 | // be supplied. Note that this method will print the default value for a |
95 | // field if it is not set. |
96 | static void PrintFieldValueToString(const Message& message, |
97 | const FieldDescriptor* field, int index, |
98 | std::string* output); |
99 | |
100 | class PROTOBUF_EXPORT BaseTextGenerator { |
101 | public: |
102 | virtual ~BaseTextGenerator(); |
103 | |
104 | virtual void Indent() {} |
105 | virtual void Outdent() {} |
106 | |
107 | // Print text to the output stream. |
108 | virtual void Print(const char* text, size_t size) = 0; |
109 | |
110 | void PrintString(const std::string& str) { Print(str.data(), str.size()); } |
111 | |
112 | template <size_t n> |
113 | void PrintLiteral(const char (&text)[n]) { |
114 | Print(text, n - 1); // n includes the terminating zero character. |
115 | } |
116 | }; |
117 | |
118 | // The default printer that converts scalar values from fields into their |
119 | // string representation. |
120 | // You can derive from this FastFieldValuePrinter if you want to have fields |
121 | // to be printed in a different way and register it at the Printer. |
122 | class PROTOBUF_EXPORT FastFieldValuePrinter { |
123 | public: |
124 | FastFieldValuePrinter(); |
125 | virtual ~FastFieldValuePrinter(); |
126 | virtual void PrintBool(bool val, BaseTextGenerator* generator) const; |
127 | virtual void PrintInt32(int32 val, BaseTextGenerator* generator) const; |
128 | virtual void PrintUInt32(uint32 val, BaseTextGenerator* generator) const; |
129 | virtual void PrintInt64(int64 val, BaseTextGenerator* generator) const; |
130 | virtual void PrintUInt64(uint64 val, BaseTextGenerator* generator) const; |
131 | virtual void PrintFloat(float val, BaseTextGenerator* generator) const; |
132 | virtual void PrintDouble(double val, BaseTextGenerator* generator) const; |
133 | virtual void PrintString(const std::string& val, |
134 | BaseTextGenerator* generator) const; |
135 | virtual void PrintBytes(const std::string& val, |
136 | BaseTextGenerator* generator) const; |
137 | virtual void PrintEnum(int32 val, const std::string& name, |
138 | BaseTextGenerator* generator) const; |
139 | virtual void PrintFieldName(const Message& message, int field_index, |
140 | int field_count, const Reflection* reflection, |
141 | const FieldDescriptor* field, |
142 | BaseTextGenerator* generator) const; |
143 | virtual void PrintFieldName(const Message& message, |
144 | const Reflection* reflection, |
145 | const FieldDescriptor* field, |
146 | BaseTextGenerator* generator) const; |
147 | virtual void PrintMessageStart(const Message& message, int field_index, |
148 | int field_count, bool single_line_mode, |
149 | BaseTextGenerator* generator) const; |
150 | virtual void PrintMessageEnd(const Message& message, int field_index, |
151 | int field_count, bool single_line_mode, |
152 | BaseTextGenerator* generator) const; |
153 | |
154 | private: |
155 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter); |
156 | }; |
157 | |
158 | class PROTOBUF_EXPORT PROTOBUF_DEPRECATED_MSG( |
159 | "Please use FastFieldValuePrinter" ) FieldValuePrinter { |
160 | public: |
161 | FieldValuePrinter(); |
162 | virtual ~FieldValuePrinter(); |
163 | virtual std::string PrintBool(bool val) const; |
164 | virtual std::string PrintInt32(int32 val) const; |
165 | virtual std::string PrintUInt32(uint32 val) const; |
166 | virtual std::string PrintInt64(int64 val) const; |
167 | virtual std::string PrintUInt64(uint64 val) const; |
168 | virtual std::string PrintFloat(float val) const; |
169 | virtual std::string PrintDouble(double val) const; |
170 | virtual std::string PrintString(const std::string& val) const; |
171 | virtual std::string PrintBytes(const std::string& val) const; |
172 | virtual std::string PrintEnum(int32 val, const std::string& name) const; |
173 | virtual std::string PrintFieldName(const Message& message, |
174 | const Reflection* reflection, |
175 | const FieldDescriptor* field) const; |
176 | virtual std::string PrintMessageStart(const Message& message, |
177 | int field_index, int field_count, |
178 | bool single_line_mode) const; |
179 | virtual std::string PrintMessageEnd(const Message& message, int field_index, |
180 | int field_count, |
181 | bool single_line_mode) const; |
182 | |
183 | private: |
184 | FastFieldValuePrinter delegate_; |
185 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter); |
186 | }; |
187 | |
188 | class PROTOBUF_EXPORT MessagePrinter { |
189 | public: |
190 | MessagePrinter() {} |
191 | virtual ~MessagePrinter() {} |
192 | virtual void Print(const Message& message, bool single_line_mode, |
193 | BaseTextGenerator* generator) const = 0; |
194 | |
195 | private: |
196 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessagePrinter); |
197 | }; |
198 | |
199 | // Interface that Printers or Parsers can use to find extensions, or types |
200 | // referenced in Any messages. |
201 | class PROTOBUF_EXPORT Finder { |
202 | public: |
203 | virtual ~Finder(); |
204 | |
205 | // Try to find an extension of *message by fully-qualified field |
206 | // name. Returns NULL if no extension is known for this name or number. |
207 | // The base implementation uses the extensions already known by the message. |
208 | virtual const FieldDescriptor* FindExtension(Message* message, |
209 | const std::string& name) const; |
210 | |
211 | // Similar to FindExtension, but uses a Descriptor and the extension number |
212 | // instead of using a Message and the name when doing the look up. |
213 | virtual const FieldDescriptor* FindExtensionByNumber( |
214 | const Descriptor* descriptor, int number) const; |
215 | |
216 | // Find the message type for an Any proto. |
217 | // Returns NULL if no message is known for this name. |
218 | // The base implementation only accepts prefixes of type.googleprod.com/ or |
219 | // type.googleapis.com/, and searches the DescriptorPool of the parent |
220 | // message. |
221 | virtual const Descriptor* FindAnyType(const Message& message, |
222 | const std::string& prefix, |
223 | const std::string& name) const; |
224 | |
225 | // Find the message factory for the given extension field. This can be used |
226 | // to generalize the Parser to add extension fields to a message in the same |
227 | // way as the "input" message for the Parser. |
228 | virtual MessageFactory* FindExtensionFactory( |
229 | const FieldDescriptor* field) const; |
230 | }; |
231 | |
232 | // Class for those users which require more fine-grained control over how |
233 | // a protobuffer message is printed out. |
234 | class PROTOBUF_EXPORT Printer { |
235 | public: |
236 | Printer(); |
237 | ~Printer(); |
238 | |
239 | // Like TextFormat::Print |
240 | bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; |
241 | // Like TextFormat::PrintUnknownFields |
242 | bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
243 | io::ZeroCopyOutputStream* output) const; |
244 | // Like TextFormat::PrintToString |
245 | bool PrintToString(const Message& message, std::string* output) const; |
246 | // Like TextFormat::PrintUnknownFieldsToString |
247 | bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, |
248 | std::string* output) const; |
249 | // Like TextFormat::PrintFieldValueToString |
250 | void PrintFieldValueToString(const Message& message, |
251 | const FieldDescriptor* field, int index, |
252 | std::string* output) const; |
253 | |
254 | // Adjust the initial indent level of all output. Each indent level is |
255 | // equal to two spaces. |
256 | void SetInitialIndentLevel(int indent_level) { |
257 | initial_indent_level_ = indent_level; |
258 | } |
259 | |
260 | // If printing in single line mode, then the entire message will be output |
261 | // on a single line with no line breaks. |
262 | void SetSingleLineMode(bool single_line_mode) { |
263 | single_line_mode_ = single_line_mode; |
264 | } |
265 | |
266 | bool IsInSingleLineMode() const { return single_line_mode_; } |
267 | |
268 | // If use_field_number is true, uses field number instead of field name. |
269 | void SetUseFieldNumber(bool use_field_number) { |
270 | use_field_number_ = use_field_number; |
271 | } |
272 | |
273 | // Set true to print repeated primitives in a format like: |
274 | // field_name: [1, 2, 3, 4] |
275 | // instead of printing each value on its own line. Short format applies |
276 | // only to primitive values -- i.e. everything except strings and |
277 | // sub-messages/groups. |
278 | void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { |
279 | use_short_repeated_primitives_ = use_short_repeated_primitives; |
280 | } |
281 | |
282 | // Set true to output UTF-8 instead of ASCII. The only difference |
283 | // is that bytes >= 0x80 in string fields will not be escaped, |
284 | // because they are assumed to be part of UTF-8 multi-byte |
285 | // sequences. This will change the default FastFieldValuePrinter. |
286 | void SetUseUtf8StringEscaping(bool as_utf8); |
287 | |
288 | // Set the default (Fast)FieldValuePrinter that is used for all fields that |
289 | // don't have a field-specific printer registered. |
290 | // Takes ownership of the printer. |
291 | void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer); |
292 | void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer); |
293 | |
294 | // Sets whether we want to hide unknown fields or not. |
295 | // Usually unknown fields are printed in a generic way that includes the |
296 | // tag number of the field instead of field name. However, sometimes it |
297 | // is useful to be able to print the message without unknown fields (e.g. |
298 | // for the python protobuf version to maintain consistency between its pure |
299 | // python and c++ implementations). |
300 | void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; } |
301 | |
302 | // If print_message_fields_in_index_order is true, fields of a proto message |
303 | // will be printed using the order defined in source code instead of the |
304 | // field number, extensions will be printed at the end of the message |
305 | // and their relative order is determined by the extension number. |
306 | // By default, use the field number order. |
307 | void SetPrintMessageFieldsInIndexOrder( |
308 | bool print_message_fields_in_index_order) { |
309 | print_message_fields_in_index_order_ = |
310 | print_message_fields_in_index_order; |
311 | } |
312 | |
313 | // If expand==true, expand google.protobuf.Any payloads. The output |
314 | // will be of form |
315 | // [type_url] { <value_printed_in_text> } |
316 | // |
317 | // If expand==false, print Any using the default printer. The output will |
318 | // look like |
319 | // type_url: "<type_url>" value: "serialized_content" |
320 | void SetExpandAny(bool expand) { expand_any_ = expand; } |
321 | |
322 | // Set how parser finds message for Any payloads. |
323 | void SetFinder(const Finder* finder) { finder_ = finder; } |
324 | |
325 | // If non-zero, we truncate all string fields that are longer than |
326 | // this threshold. This is useful when the proto message has very long |
327 | // strings, e.g., dump of encoded image file. |
328 | // |
329 | // NOTE(hfgong): Setting a non-zero value breaks round-trip safe |
330 | // property of TextFormat::Printer. That is, from the printed message, we |
331 | // cannot fully recover the original string field any more. |
332 | void SetTruncateStringFieldLongerThan( |
333 | const int64 truncate_string_field_longer_than) { |
334 | truncate_string_field_longer_than_ = truncate_string_field_longer_than; |
335 | } |
336 | |
337 | // Register a custom field-specific (Fast)FieldValuePrinter for fields |
338 | // with a particular FieldDescriptor. |
339 | // Returns "true" if the registration succeeded, or "false", if there is |
340 | // already a printer for that FieldDescriptor. |
341 | // Takes ownership of the printer on successful registration. |
342 | bool RegisterFieldValuePrinter(const FieldDescriptor* field, |
343 | const FieldValuePrinter* printer); |
344 | bool RegisterFieldValuePrinter(const FieldDescriptor* field, |
345 | const FastFieldValuePrinter* printer); |
346 | |
347 | // Register a custom message-specific MessagePrinter for messages with a |
348 | // particular Descriptor. |
349 | // Returns "true" if the registration succeeded, or "false" if there is |
350 | // already a printer for that Descriptor. |
351 | bool RegisterMessagePrinter(const Descriptor* descriptor, |
352 | const MessagePrinter* printer); |
353 | |
354 | private: |
355 | // Forward declaration of an internal class used to print the text |
356 | // output to the OutputStream (see text_format.cc for implementation). |
357 | class TextGenerator; |
358 | |
359 | // Internal Print method, used for writing to the OutputStream via |
360 | // the TextGenerator class. |
361 | void Print(const Message& message, TextGenerator* generator) const; |
362 | |
363 | // Print a single field. |
364 | void PrintField(const Message& message, const Reflection* reflection, |
365 | const FieldDescriptor* field, |
366 | TextGenerator* generator) const; |
367 | |
368 | // Print a repeated primitive field in short form. |
369 | void PrintShortRepeatedField(const Message& message, |
370 | const Reflection* reflection, |
371 | const FieldDescriptor* field, |
372 | TextGenerator* generator) const; |
373 | |
374 | // Print the name of a field -- i.e. everything that comes before the |
375 | // ':' for a single name/value pair. |
376 | void PrintFieldName(const Message& message, int field_index, |
377 | int field_count, const Reflection* reflection, |
378 | const FieldDescriptor* field, |
379 | TextGenerator* generator) const; |
380 | |
381 | // Outputs a textual representation of the value of the field supplied on |
382 | // the message supplied or the default value if not set. |
383 | void PrintFieldValue(const Message& message, const Reflection* reflection, |
384 | const FieldDescriptor* field, int index, |
385 | TextGenerator* generator) const; |
386 | |
387 | // Print the fields in an UnknownFieldSet. They are printed by tag number |
388 | // only. Embedded messages are heuristically identified by attempting to |
389 | // parse them. |
390 | void PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
391 | TextGenerator* generator) const; |
392 | |
393 | bool PrintAny(const Message& message, TextGenerator* generator) const; |
394 | |
395 | int initial_indent_level_; |
396 | |
397 | bool single_line_mode_; |
398 | |
399 | bool use_field_number_; |
400 | |
401 | bool use_short_repeated_primitives_; |
402 | |
403 | bool hide_unknown_fields_; |
404 | |
405 | bool print_message_fields_in_index_order_; |
406 | |
407 | bool expand_any_; |
408 | |
409 | int64 truncate_string_field_longer_than_; |
410 | |
411 | std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_; |
412 | typedef std::map<const FieldDescriptor*, const FastFieldValuePrinter*> |
413 | CustomPrinterMap; |
414 | CustomPrinterMap custom_printers_; |
415 | |
416 | typedef std::map<const Descriptor*, const MessagePrinter*> |
417 | CustomMessagePrinterMap; |
418 | CustomMessagePrinterMap custom_message_printers_; |
419 | |
420 | const Finder* finder_; |
421 | }; |
422 | |
423 | // Parses a text-format protocol message from the given input stream to |
424 | // the given message object. This function parses the human-readable format |
425 | // written by Print(). Returns true on success. The message is cleared first, |
426 | // even if the function fails -- See Merge() to avoid this behavior. |
427 | // |
428 | // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}" |
429 | // |
430 | // One use for this function is parsing handwritten strings in test code. |
431 | // Another use is to parse the output from google::protobuf::Message::DebugString() |
432 | // (or ShortDebugString()), because these functions output using |
433 | // google::protobuf::TextFormat::Print(). |
434 | // |
435 | // If you would like to read a protocol buffer serialized in the |
436 | // (non-human-readable) binary wire format, see |
437 | // google::protobuf::MessageLite::ParseFromString(). |
438 | static bool Parse(io::ZeroCopyInputStream* input, Message* output); |
439 | // Like Parse(), but reads directly from a string. |
440 | static bool ParseFromString(const std::string& input, Message* output); |
441 | |
442 | // Like Parse(), but the data is merged into the given message, as if |
443 | // using Message::MergeFrom(). |
444 | static bool Merge(io::ZeroCopyInputStream* input, Message* output); |
445 | // Like Merge(), but reads directly from a string. |
446 | static bool MergeFromString(const std::string& input, Message* output); |
447 | |
448 | // Parse the given text as a single field value and store it into the |
449 | // given field of the given message. If the field is a repeated field, |
450 | // the new value will be added to the end |
451 | static bool ParseFieldValueFromString(const std::string& input, |
452 | const FieldDescriptor* field, |
453 | Message* message); |
454 | |
455 | // A location in the parsed text. |
456 | struct ParseLocation { |
457 | int line; |
458 | int column; |
459 | |
460 | ParseLocation() : line(-1), column(-1) {} |
461 | ParseLocation(int line_param, int column_param) |
462 | : line(line_param), column(column_param) {} |
463 | }; |
464 | |
465 | // Data structure which is populated with the locations of each field |
466 | // value parsed from the text. |
467 | class PROTOBUF_EXPORT ParseInfoTree { |
468 | public: |
469 | ParseInfoTree(); |
470 | ~ParseInfoTree(); |
471 | |
472 | // Returns the parse location for index-th value of the field in the parsed |
473 | // text. If none exists, returns a location with line = -1. Index should be |
474 | // -1 for not-repeated fields. |
475 | ParseLocation GetLocation(const FieldDescriptor* field, int index) const; |
476 | |
477 | // Returns the parse info tree for the given field, which must be a message |
478 | // type. The nested information tree is owned by the root tree and will be |
479 | // deleted when it is deleted. |
480 | ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, |
481 | int index) const; |
482 | |
483 | private: |
484 | // Allow the text format parser to record information into the tree. |
485 | friend class TextFormat; |
486 | |
487 | // Records the starting location of a single value for a field. |
488 | void RecordLocation(const FieldDescriptor* field, ParseLocation location); |
489 | |
490 | // Create and records a nested tree for a nested message field. |
491 | ParseInfoTree* CreateNested(const FieldDescriptor* field); |
492 | |
493 | // Defines the map from the index-th field descriptor to its parse location. |
494 | typedef std::map<const FieldDescriptor*, std::vector<ParseLocation> > |
495 | LocationMap; |
496 | |
497 | // Defines the map from the index-th field descriptor to the nested parse |
498 | // info tree. |
499 | typedef std::map<const FieldDescriptor*, std::vector<ParseInfoTree*> > |
500 | NestedMap; |
501 | |
502 | LocationMap locations_; |
503 | NestedMap nested_; |
504 | |
505 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree); |
506 | }; |
507 | |
508 | // For more control over parsing, use this class. |
509 | class PROTOBUF_EXPORT Parser { |
510 | public: |
511 | Parser(); |
512 | ~Parser(); |
513 | |
514 | // Like TextFormat::Parse(). |
515 | bool Parse(io::ZeroCopyInputStream* input, Message* output); |
516 | // Like TextFormat::ParseFromString(). |
517 | bool ParseFromString(const std::string& input, Message* output); |
518 | // Like TextFormat::Merge(). |
519 | bool Merge(io::ZeroCopyInputStream* input, Message* output); |
520 | // Like TextFormat::MergeFromString(). |
521 | bool MergeFromString(const std::string& input, Message* output); |
522 | |
523 | // Set where to report parse errors. If NULL (the default), errors will |
524 | // be printed to stderr. |
525 | void RecordErrorsTo(io::ErrorCollector* error_collector) { |
526 | error_collector_ = error_collector; |
527 | } |
528 | |
529 | // Set how parser finds extensions. If NULL (the default), the |
530 | // parser will use the standard Reflection object associated with |
531 | // the message being parsed. |
532 | void SetFinder(const Finder* finder) { finder_ = finder; } |
533 | |
534 | // Sets where location information about the parse will be written. If NULL |
535 | // (the default), then no location will be written. |
536 | void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; } |
537 | |
538 | // Normally parsing fails if, after parsing, output->IsInitialized() |
539 | // returns false. Call AllowPartialMessage(true) to skip this check. |
540 | void AllowPartialMessage(bool allow) { allow_partial_ = allow; } |
541 | |
542 | // Allow field names to be matched case-insensitively. |
543 | // This is not advisable if there are fields that only differ in case, or |
544 | // if you want to enforce writing in the canonical form. |
545 | // This is 'false' by default. |
546 | void AllowCaseInsensitiveField(bool allow) { |
547 | allow_case_insensitive_field_ = allow; |
548 | } |
549 | |
550 | // Like TextFormat::ParseFieldValueFromString |
551 | bool ParseFieldValueFromString(const std::string& input, |
552 | const FieldDescriptor* field, |
553 | Message* output); |
554 | |
555 | // When an unknown extension is met, parsing will fail if this option is set |
556 | // to false (the default). If true, unknown extensions will be ignored and |
557 | // a warning message will be generated. |
558 | void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; } |
559 | |
560 | // When an unknown field is met, parsing will fail if this option is set |
561 | // to false(the default). If true, unknown fields will be ignored and |
562 | // a warning message will be generated. |
563 | // Please aware that set this option true may hide some errors (e.g. |
564 | // spelling error on field name). Avoid to use this option if possible. |
565 | void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; } |
566 | |
567 | |
568 | void AllowFieldNumber(bool allow) { allow_field_number_ = allow; } |
569 | |
570 | // Sets maximum recursion depth which parser can use. This is effectively |
571 | // the maximum allowed nesting of proto messages. |
572 | void SetRecursionLimit(int limit) { recursion_limit_ = limit; } |
573 | |
574 | private: |
575 | // Forward declaration of an internal class used to parse text |
576 | // representations (see text_format.cc for implementation). |
577 | class ParserImpl; |
578 | |
579 | // Like TextFormat::Merge(). The provided implementation is used |
580 | // to do the parsing. |
581 | bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output, |
582 | ParserImpl* parser_impl); |
583 | |
584 | io::ErrorCollector* error_collector_; |
585 | const Finder* finder_; |
586 | ParseInfoTree* parse_info_tree_; |
587 | bool allow_partial_; |
588 | bool allow_case_insensitive_field_; |
589 | bool allow_unknown_field_; |
590 | bool allow_unknown_extension_; |
591 | bool allow_unknown_enum_; |
592 | bool allow_field_number_; |
593 | bool allow_relaxed_whitespace_; |
594 | bool allow_singular_overwrites_; |
595 | int recursion_limit_; |
596 | }; |
597 | |
598 | |
599 | private: |
600 | // Hack: ParseInfoTree declares TextFormat as a friend which should extend |
601 | // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some |
602 | // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide |
603 | // helpers for ParserImpl to call methods of ParseInfoTree. |
604 | static inline void RecordLocation(ParseInfoTree* info_tree, |
605 | const FieldDescriptor* field, |
606 | ParseLocation location); |
607 | static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, |
608 | const FieldDescriptor* field); |
609 | |
610 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); |
611 | }; |
612 | |
613 | inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, |
614 | const FieldDescriptor* field, |
615 | ParseLocation location) { |
616 | info_tree->RecordLocation(field, location); |
617 | } |
618 | |
619 | inline TextFormat::ParseInfoTree* TextFormat::CreateNested( |
620 | ParseInfoTree* info_tree, const FieldDescriptor* field) { |
621 | return info_tree->CreateNested(field); |
622 | } |
623 | |
624 | } // namespace protobuf |
625 | } // namespace google |
626 | |
627 | #include <google/protobuf/port_undef.inc> |
628 | |
629 | #endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ |
630 | |