File indexing completed on 2026-09-19 09:23:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
0016 #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
0017
0018 #include <atomic>
0019 #include <memory>
0020 #include <string>
0021 #include <vector>
0022
0023 #include "absl/container/flat_hash_map.h"
0024 #include "absl/container/flat_hash_set.h"
0025 #include "absl/strings/cord.h"
0026 #include "absl/strings/string_view.h"
0027 #include "google/protobuf/descriptor.h"
0028 #include "google/protobuf/message.h"
0029 #include "google/protobuf/message_lite.h"
0030 #include "google/protobuf/port.h"
0031
0032
0033
0034 #include "google/protobuf/port_def.inc"
0035
0036 #ifdef SWIG
0037 #error "You cannot SWIG proto headers"
0038 #endif
0039
0040 namespace google {
0041 namespace protobuf {
0042
0043 namespace internal {
0044 PROTOBUF_EXPORT extern const char kDebugStringSilentMarker[1];
0045 PROTOBUF_EXPORT extern const char kDebugStringSilentMarkerForDetection[3];
0046
0047 PROTOBUF_EXPORT int64_t GetRedactedFieldCount();
0048
0049
0050
0051
0052
0053 enum class PROTOBUF_EXPORT FieldReporterLevel {
0054 kNoReport = 0,
0055 kPrintMessage = 1,
0056 kPrintWithGenerator = 2,
0057 kPrintWithStream = 3,
0058 kMemberPrintToString = 4,
0059 kStaticPrintToString = 5,
0060 kAbslStringify = 6,
0061 kShortFormat = 7,
0062 kUtf8Format = 8,
0063 kDebugString = 12,
0064 kShortDebugString = 13,
0065 kUtf8DebugString = 14,
0066 kUnredactedDebugFormatForTest = 15,
0067 kUnredactedShortDebugFormatForTest = 16,
0068 kUnredactedUtf8DebugFormatForTest = 17
0069 };
0070
0071 }
0072
0073 namespace io {
0074 class ErrorCollector;
0075 }
0076
0077 namespace python {
0078 namespace cmessage {
0079 class PythonFieldValuePrinter;
0080 }
0081 }
0082
0083 namespace internal {
0084
0085 PROTOBUF_EXPORT enum class Option;
0086
0087
0088
0089 PROTOBUF_EXPORT std::string StringifyMessage(const Message& message,
0090 Option option,
0091 FieldReporterLevel reporter_level);
0092
0093 class UnsetFieldsMetadataTextFormatTestUtil;
0094 class UnsetFieldsMetadataMessageDifferencerTestUtil;
0095 }
0096
0097
0098
0099
0100
0101
0102 class PROTOBUF_EXPORT TextFormat {
0103 public:
0104 TextFormat(const TextFormat&) = delete;
0105 TextFormat& operator=(const TextFormat&) = delete;
0106
0107
0108
0109 static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
0110
0111
0112
0113
0114 static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
0115 io::ZeroCopyOutputStream* output);
0116
0117
0118
0119
0120 static bool PrintToString(const Message& message, std::string* output);
0121
0122
0123
0124 static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
0125 std::string* output);
0126
0127
0128
0129
0130
0131 static void PrintFieldValueToString(const Message& message,
0132 const FieldDescriptor* field, int index,
0133 std::string* output);
0134
0135
0136
0137 class Printer;
0138
0139 class PROTOBUF_EXPORT BaseTextGenerator {
0140 private:
0141
0142
0143
0144
0145 class MarkerToken {
0146 private:
0147 explicit MarkerToken() = default;
0148 friend class Printer;
0149 };
0150
0151 public:
0152 virtual ~BaseTextGenerator();
0153
0154 virtual void Indent() {}
0155 virtual void Outdent() {}
0156
0157 virtual size_t GetCurrentIndentationSize() const { return 0; }
0158
0159
0160 virtual void Print(const char* text, size_t size) = 0;
0161
0162 void PrintString(absl::string_view str) { Print(str.data(), str.size()); }
0163
0164 template <size_t n>
0165 void PrintLiteral(const char (&text)[n]) {
0166 Print(text, n - 1);
0167 }
0168
0169
0170 virtual void PrintMaybeWithMarker(MarkerToken, absl::string_view text) {
0171 Print(text.data(), text.size());
0172 }
0173
0174
0175 virtual void PrintMaybeWithMarker(MarkerToken, absl::string_view text_head,
0176 absl::string_view text_tail) {
0177 Print(text_head.data(), text_head.size());
0178 Print(text_tail.data(), text_tail.size());
0179 }
0180
0181 friend class Printer;
0182 };
0183
0184
0185
0186
0187
0188 class PROTOBUF_EXPORT FastFieldValuePrinter {
0189 public:
0190 FastFieldValuePrinter();
0191 FastFieldValuePrinter(const FastFieldValuePrinter&) = delete;
0192 FastFieldValuePrinter& operator=(const FastFieldValuePrinter&) = delete;
0193 virtual ~FastFieldValuePrinter();
0194 virtual void PrintBool(bool val, BaseTextGenerator* generator) const;
0195 virtual void PrintInt32(int32_t val, BaseTextGenerator* generator) const;
0196 virtual void PrintUInt32(uint32_t val, BaseTextGenerator* generator) const;
0197 virtual void PrintInt64(int64_t val, BaseTextGenerator* generator) const;
0198 virtual void PrintUInt64(uint64_t val, BaseTextGenerator* generator) const;
0199 virtual void PrintFloat(float val, BaseTextGenerator* generator) const;
0200 virtual void PrintDouble(double val, BaseTextGenerator* generator) const;
0201 virtual void PrintString(const std::string& val,
0202 BaseTextGenerator* generator) const;
0203 virtual void PrintBytes(const std::string& val,
0204 BaseTextGenerator* generator) const;
0205 virtual void PrintEnum(int32_t val, const std::string& name,
0206 BaseTextGenerator* generator) const;
0207 virtual void PrintFieldName(const Message& message, int field_index,
0208 int field_count, const Reflection* reflection,
0209 const FieldDescriptor* field,
0210 BaseTextGenerator* generator) const;
0211 virtual void PrintFieldName(const Message& message,
0212 const Reflection* reflection,
0213 const FieldDescriptor* field,
0214 BaseTextGenerator* generator) const;
0215 virtual void PrintMessageStart(const Message& message, int field_index,
0216 int field_count, bool single_line_mode,
0217 BaseTextGenerator* generator) const;
0218
0219
0220
0221
0222
0223 virtual bool PrintMessageContent(const Message& message, int field_index,
0224 int field_count, bool single_line_mode,
0225 BaseTextGenerator* generator) const;
0226 virtual void PrintMessageEnd(const Message& message, int field_index,
0227 int field_count, bool single_line_mode,
0228 BaseTextGenerator* generator) const;
0229 };
0230
0231
0232 class PROTOBUF_EXPORT FieldValuePrinter {
0233 public:
0234 FieldValuePrinter();
0235 FieldValuePrinter(const FieldValuePrinter&) = delete;
0236 FieldValuePrinter& operator=(const FieldValuePrinter&) = delete;
0237 virtual ~FieldValuePrinter();
0238 virtual std::string PrintBool(bool val) const;
0239 virtual std::string PrintInt32(int32_t val) const;
0240 virtual std::string PrintUInt32(uint32_t val) const;
0241 virtual std::string PrintInt64(int64_t val) const;
0242 virtual std::string PrintUInt64(uint64_t val) const;
0243 virtual std::string PrintFloat(float val) const;
0244 virtual std::string PrintDouble(double val) const;
0245 virtual std::string PrintString(const std::string& val) const;
0246 virtual std::string PrintBytes(const std::string& val) const;
0247 virtual std::string PrintEnum(int32_t val, const std::string& name) const;
0248 virtual std::string PrintFieldName(const Message& message,
0249 const Reflection* reflection,
0250 const FieldDescriptor* field) const;
0251 virtual std::string PrintMessageStart(const Message& message,
0252 int field_index, int field_count,
0253 bool single_line_mode) const;
0254 virtual std::string PrintMessageEnd(const Message& message, int field_index,
0255 int field_count,
0256 bool single_line_mode) const;
0257
0258 private:
0259 FastFieldValuePrinter delegate_;
0260 };
0261
0262 class PROTOBUF_EXPORT MessagePrinter {
0263 public:
0264 MessagePrinter() {}
0265 MessagePrinter(const MessagePrinter&) = delete;
0266 MessagePrinter& operator=(const MessagePrinter&) = delete;
0267 virtual ~MessagePrinter() {}
0268 virtual void Print(const Message& message, bool single_line_mode,
0269 BaseTextGenerator* generator) const = 0;
0270 };
0271
0272
0273
0274 class PROTOBUF_EXPORT Finder {
0275 public:
0276 virtual ~Finder();
0277
0278
0279
0280
0281 virtual const FieldDescriptor* FindExtension(Message* message,
0282 const std::string& name) const;
0283
0284
0285
0286 virtual const FieldDescriptor* FindExtensionByNumber(
0287 const Descriptor* descriptor, int number) const;
0288
0289
0290
0291
0292
0293
0294 virtual const Descriptor* FindAnyType(const Message& message,
0295 const std::string& prefix,
0296 const std::string& name) const;
0297
0298
0299
0300
0301 virtual MessageFactory* FindExtensionFactory(
0302 const FieldDescriptor* field) const;
0303 };
0304
0305
0306
0307 class PROTOBUF_EXPORT Printer {
0308 public:
0309 Printer();
0310
0311
0312 bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
0313
0314
0315 bool Print(const Message& message, io::ZeroCopyOutputStream* output,
0316 internal::FieldReporterLevel reporter) const;
0317
0318 bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
0319 io::ZeroCopyOutputStream* output) const;
0320
0321 bool PrintToString(const Message& message, std::string* output) const;
0322
0323 bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
0324 std::string* output) const;
0325
0326 void PrintFieldValueToString(const Message& message,
0327 const FieldDescriptor* field, int index,
0328 std::string* output) const;
0329
0330
0331
0332 void SetInitialIndentLevel(int indent_level) {
0333 initial_indent_level_ = indent_level;
0334 }
0335
0336
0337
0338 void SetSingleLineMode(bool single_line_mode) {
0339 single_line_mode_ = single_line_mode;
0340 }
0341
0342 bool IsInSingleLineMode() const { return single_line_mode_; }
0343
0344
0345 void SetUseFieldNumber(bool use_field_number) {
0346 use_field_number_ = use_field_number;
0347 }
0348
0349
0350
0351
0352
0353
0354 void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
0355 use_short_repeated_primitives_ = use_short_repeated_primitives;
0356 }
0357
0358
0359
0360
0361
0362 void SetUseUtf8StringEscaping(bool as_utf8);
0363
0364
0365
0366
0367 void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer);
0368
0369 [[deprecated("Please use FastFieldValuePrinter")]] void
0370 SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
0371
0372
0373
0374
0375
0376
0377
0378 void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; }
0379
0380
0381
0382
0383
0384
0385 void SetPrintMessageFieldsInIndexOrder(
0386 bool print_message_fields_in_index_order) {
0387 print_message_fields_in_index_order_ =
0388 print_message_fields_in_index_order;
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398 void SetExpandAny(bool expand) { expand_any_ = expand; }
0399
0400
0401 void SetFinder(const Finder* finder) { finder_ = finder; }
0402
0403
0404
0405
0406
0407
0408
0409
0410 void SetTruncateStringFieldLongerThan(
0411 const int64_t truncate_string_field_longer_than) {
0412 truncate_string_field_longer_than_ = truncate_string_field_longer_than;
0413 }
0414
0415
0416
0417 void SetReportSensitiveFields(internal::FieldReporterLevel reporter) {
0418 if (report_sensitive_fields_ < reporter) {
0419 report_sensitive_fields_ = reporter;
0420 }
0421 }
0422
0423
0424 void SetRedactDebugString(bool redact) { redact_debug_string_ = redact; }
0425
0426
0427
0428
0429
0430
0431 bool RegisterFieldValuePrinter(const FieldDescriptor* field,
0432 const FastFieldValuePrinter* printer);
0433
0434 [[deprecated("Please use FastFieldValuePrinter")]] bool
0435 RegisterFieldValuePrinter(const FieldDescriptor* field,
0436 const FieldValuePrinter* printer);
0437
0438
0439
0440
0441
0442
0443 bool RegisterMessagePrinter(const Descriptor* descriptor,
0444 const MessagePrinter* printer);
0445
0446
0447
0448
0449
0450
0451 void PrintMessage(const Message& message,
0452 BaseTextGenerator* generator) const;
0453
0454 private:
0455 friend std::string Message::DebugString() const;
0456 friend std::string Message::ShortDebugString() const;
0457 friend std::string Message::Utf8DebugString() const;
0458 friend std::string internal::StringifyMessage(
0459 const Message& message, internal::Option option,
0460 internal::FieldReporterLevel reporter_level);
0461
0462
0463 void SetInsertSilentMarker(bool v) { insert_silent_marker_ = v; }
0464
0465
0466
0467 void SetRandomizeDebugString(bool randomize) {
0468 randomize_debug_string_ = randomize;
0469 }
0470
0471
0472
0473 class TextGenerator;
0474 using MarkerToken = BaseTextGenerator::MarkerToken;
0475
0476
0477
0478 class DebugStringFieldValuePrinter;
0479
0480
0481
0482 class FastFieldValuePrinterUtf8Escaping;
0483
0484
0485
0486 void Print(const Message& message, BaseTextGenerator* generator) const;
0487
0488
0489 void PrintField(const Message& message, const Reflection* reflection,
0490 const FieldDescriptor* field,
0491 BaseTextGenerator* generator) const;
0492
0493
0494 void PrintShortRepeatedField(const Message& message,
0495 const Reflection* reflection,
0496 const FieldDescriptor* field,
0497 BaseTextGenerator* generator) const;
0498
0499
0500
0501 void PrintFieldName(const Message& message, int field_index,
0502 int field_count, const Reflection* reflection,
0503 const FieldDescriptor* field,
0504 BaseTextGenerator* generator) const;
0505
0506
0507
0508 void PrintFieldValue(const Message& message, const Reflection* reflection,
0509 const FieldDescriptor* field, int index,
0510 BaseTextGenerator* generator) const;
0511
0512
0513
0514
0515 void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
0516 BaseTextGenerator* generator,
0517 int recursion_budget) const;
0518
0519 bool PrintAny(const Message& message, BaseTextGenerator* generator) const;
0520
0521
0522
0523 bool TryRedactFieldValue(const Message& message,
0524 const FieldDescriptor* field,
0525 BaseTextGenerator* generator,
0526 bool insert_value_separator) const;
0527
0528 const FastFieldValuePrinter* GetFieldPrinter(
0529 const FieldDescriptor* field) const {
0530 auto it = custom_printers_.find(field);
0531 return it == custom_printers_.end() ? default_field_value_printer_.get()
0532 : it->second.get();
0533 }
0534
0535 friend class google::protobuf::python::cmessage::PythonFieldValuePrinter;
0536 static void HardenedPrintString(absl::string_view src,
0537 TextFormat::BaseTextGenerator* generator);
0538
0539 int initial_indent_level_;
0540 bool single_line_mode_;
0541 bool use_field_number_;
0542 bool use_short_repeated_primitives_;
0543 bool insert_silent_marker_;
0544 bool redact_debug_string_;
0545 bool randomize_debug_string_;
0546 internal::FieldReporterLevel report_sensitive_fields_;
0547 bool hide_unknown_fields_;
0548 bool print_message_fields_in_index_order_;
0549 bool expand_any_;
0550 int64_t truncate_string_field_longer_than_;
0551
0552 std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_;
0553 absl::flat_hash_map<const FieldDescriptor*,
0554 std::unique_ptr<const FastFieldValuePrinter>>
0555 custom_printers_;
0556
0557 absl::flat_hash_map<const Descriptor*,
0558 std::unique_ptr<const MessagePrinter>>
0559 custom_message_printers_;
0560
0561 const Finder* finder_;
0562 };
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 static bool Parse(io::ZeroCopyInputStream* input, Message* output);
0579
0580 static bool ParseFromString(absl::string_view input, Message* output);
0581
0582 static bool ParseFromCord(const absl::Cord& input, Message* output);
0583
0584
0585
0586 static bool Merge(io::ZeroCopyInputStream* input, Message* output);
0587
0588 static bool MergeFromString(absl::string_view input, Message* output);
0589
0590
0591
0592
0593 static bool ParseFieldValueFromString(absl::string_view input,
0594 const FieldDescriptor* field,
0595 Message* message);
0596
0597
0598 struct ParseLocation {
0599 int line;
0600 int column;
0601
0602 ParseLocation() : line(-1), column(-1) {}
0603 ParseLocation(int line_param, int column_param)
0604 : line(line_param), column(column_param) {}
0605 };
0606
0607
0608
0609 struct ParseLocationRange {
0610 ParseLocation start;
0611 ParseLocation end;
0612 ParseLocationRange() : start(), end() {}
0613 ParseLocationRange(ParseLocation start_param, ParseLocation end_param)
0614 : start(start_param), end(end_param) {}
0615 };
0616
0617 struct RedactionState {
0618 bool redact;
0619 bool report;
0620 };
0621
0622 static TextFormat::RedactionState GetRedactionState(
0623 const FieldDescriptor* field);
0624
0625 static TextFormat::RedactionState IsOptionSensitive(
0626 const Message& opts, const Reflection* reflection,
0627 const FieldDescriptor* option);
0628
0629
0630 class PROTOBUF_EXPORT ParseInfoTree {
0631 public:
0632 ParseInfoTree() = default;
0633 ParseInfoTree(const ParseInfoTree&) = delete;
0634 ParseInfoTree& operator=(const ParseInfoTree&) = delete;
0635
0636
0637
0638
0639 ParseLocationRange GetLocationRange(const FieldDescriptor* field,
0640 int index) const;
0641
0642
0643
0644
0645 ParseLocation GetLocation(const FieldDescriptor* field, int index) const {
0646 return GetLocationRange(field, index).start;
0647 }
0648
0649
0650
0651
0652 ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
0653 int index) const;
0654
0655 private:
0656
0657 friend class TextFormat;
0658
0659
0660 void RecordLocation(const FieldDescriptor* field, ParseLocationRange range);
0661
0662
0663 ParseInfoTree* CreateNested(const FieldDescriptor* field);
0664
0665
0666 absl::flat_hash_map<const FieldDescriptor*, std::vector<ParseLocationRange>>
0667 locations_;
0668
0669
0670 absl::flat_hash_map<const FieldDescriptor*,
0671 std::vector<std::unique_ptr<ParseInfoTree>>>
0672 nested_;
0673 };
0674
0675
0676 class PROTOBUF_EXPORT Parser {
0677 public:
0678 Parser();
0679 ~Parser();
0680
0681
0682 bool Parse(io::ZeroCopyInputStream* input, Message* output);
0683
0684 bool ParseFromString(absl::string_view input, Message* output);
0685
0686 bool ParseFromCord(const absl::Cord& input, Message* output);
0687
0688 bool Merge(io::ZeroCopyInputStream* input, Message* output);
0689
0690 bool MergeFromString(absl::string_view input, Message* output);
0691
0692
0693
0694 void RecordErrorsTo(io::ErrorCollector* error_collector) {
0695 error_collector_ = error_collector;
0696 }
0697
0698
0699
0700
0701 void SetFinder(const Finder* finder) { finder_ = finder; }
0702
0703
0704
0705
0706 void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; }
0707
0708
0709
0710 void AllowPartialMessage(bool allow) { allow_partial_ = allow; }
0711
0712
0713
0714
0715
0716 void AllowCaseInsensitiveField(bool allow) {
0717 allow_case_insensitive_field_ = allow;
0718 }
0719
0720
0721 bool ParseFieldValueFromString(absl::string_view input,
0722 const FieldDescriptor* field,
0723 Message* output);
0724
0725
0726
0727
0728
0729
0730
0731
0732 void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; }
0733
0734
0735
0736
0737
0738
0739
0740
0741 void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
0742
0743
0744 void AllowFieldNumber(bool allow) { allow_field_number_ = allow; }
0745
0746
0747
0748 void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
0749
0750
0751
0752
0753
0754
0755
0756
0757 class UnsetFieldsMetadata {
0758 public:
0759 UnsetFieldsMetadata() = default;
0760
0761 private:
0762 using Id = std::pair<const Message*, const FieldDescriptor*>;
0763
0764 static Id GetUnsetFieldId(const Message& message,
0765 const FieldDescriptor& fd);
0766
0767
0768 absl::flat_hash_set<Id> ids_;
0769
0770 friend class ::google::protobuf::internal::
0771 UnsetFieldsMetadataMessageDifferencerTestUtil;
0772 friend class ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil;
0773 friend class ::google::protobuf::util::MessageDifferencer;
0774 friend class ::google::protobuf::TextFormat::Parser;
0775 };
0776
0777
0778
0779
0780
0781
0782 void OutputNoOpFields(UnsetFieldsMetadata* no_op_fields) {
0783 no_op_fields_ = no_op_fields;
0784 }
0785
0786 private:
0787
0788
0789 class ParserImpl;
0790
0791
0792
0793 bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output,
0794 ParserImpl* parser_impl);
0795
0796 io::ErrorCollector* error_collector_;
0797 const Finder* finder_;
0798 ParseInfoTree* parse_info_tree_;
0799 bool allow_partial_;
0800 bool allow_case_insensitive_field_;
0801 bool allow_unknown_field_;
0802 bool allow_unknown_extension_;
0803 bool allow_unknown_enum_;
0804 bool allow_field_number_;
0805 bool allow_relaxed_whitespace_;
0806 bool allow_singular_overwrites_;
0807 int recursion_limit_;
0808 UnsetFieldsMetadata* no_op_fields_ = nullptr;
0809 };
0810
0811
0812 private:
0813
0814
0815
0816
0817 static inline void RecordLocation(ParseInfoTree* info_tree,
0818 const FieldDescriptor* field,
0819 ParseLocationRange location);
0820 static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
0821 const FieldDescriptor* field);
0822
0823
0824 template <typename... T>
0825 static void OutOfLinePrintString(BaseTextGenerator* generator,
0826 const T&... values);
0827 };
0828
0829 namespace internal {
0830 void PrintTextMarker(TextFormat::BaseTextGenerator* generator, bool redact,
0831 bool randomize, bool single_line_mode);
0832 }
0833
0834 inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
0835 const FieldDescriptor* field,
0836 ParseLocationRange location) {
0837 info_tree->RecordLocation(field, location);
0838 }
0839
0840 inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
0841 ParseInfoTree* info_tree, const FieldDescriptor* field) {
0842 return info_tree->CreateNested(field);
0843 }
0844
0845 }
0846 }
0847
0848 #include "google/protobuf/port_undef.inc"
0849
0850 #endif