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