text: // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc.  All rights reserved.
  // https://developers.google.com/protocol-buffers/
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  //     * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  //     * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  //     * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  // Author: jschorr@google.com (Joseph Schorr)
  //  Based on original Protocol Buffers design by
  //  Sanjay Ghemawat, Jeff Dean, and others.
  //
  // Utilities for printing and parsing protocol messages in a human-readable,
  // text-based format.
  
  #ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
  #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
  
  #include <map>
  #include <memory>
  #include <string>
  #include <vector>
  
  #include <google/protobuf/stubs/common.h>
  #include <google/protobuf/descriptor.h>
  #include <google/protobuf/message.h>
  #include <google/protobuf/message_lite.h>
  #include <google/protobuf/port.h>
  
  #include <google/protobuf/port_def.inc>
  
  #ifdef SWIG
  #error "You cannot SWIG proto headers"
  #endif
  
  namespace google {
  namespace protobuf {
  
  namespace io {
    class ErrorCollector;      // tokenizer.h
  }
  
  // This class implements protocol buffer text format.  Printing and parsing
  // protocol messages in text format is useful for debugging and human editing
  // of messages.
  //
  // This class is really a namespace that contains only static methods.
  class PROTOBUF_EXPORT TextFormat {
   public:
    // Outputs a textual representation of the given message to the given
    // output stream. Returns false if printing fails.
    static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
  
    // Print the fields in an UnknownFieldSet.  They are printed by tag number
    // only.  Embedded messages are heuristically identified by attempting to
    // parse them. Returns false if printing fails.
    static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
                                   io::ZeroCopyOutputStream* output);
  
    // Like Print(), but outputs directly to a string.
    // Note: output will be cleared prior to printing, and will be left empty
    // even if printing fails. Returns false if printing fails.
    static bool PrintToString(const Message& message, std::string* output);
  
    // Like PrintUnknownFields(), but outputs directly to a string. Returns false
    // if printing fails.
    static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
                                           std::string* output);
  
    // Outputs a textual representation of the value of the field supplied on
    // the message supplied. For non-repeated fields, an index of -1 must
    // be supplied. Note that this method will print the default value for a
    // field if it is not set.
    static void PrintFieldValueToString(const Message& message,
                                        const FieldDescriptor* field,
                                        int index,
                                        std::string* output);
  
    class PROTOBUF_EXPORT BaseTextGenerator {
     public:
      virtual ~BaseTextGenerator();
  
      virtual void Indent() {}
      virtual void Outdent() {}
  
      // Print text to the output stream.
      virtual void Print(const char* text, size_t size) = 0;
  
      void PrintString(const std::string& str) { Print(str.data(), str.size()); }
  
      template <size_t n>
      void PrintLiteral(const char (&text)[n]) {
        Print(text, n - 1);  // n includes the terminating zero character.
      }
    };
  
    // The default printer that converts scalar values from fields into their
    // string representation.
    // You can derive from this FastFieldValuePrinter if you want to have fields
    // to be printed in a different way and register it at the Printer.
    class PROTOBUF_EXPORT FastFieldValuePrinter {
     public:
      FastFieldValuePrinter();
      virtual ~FastFieldValuePrinter();
      virtual void PrintBool(bool val, BaseTextGenerator* generator) const;
      virtual void PrintInt32(int32 val, BaseTextGenerator* generator) const;
      virtual void PrintUInt32(uint32 val, BaseTextGenerator* generator) const;
      virtual void PrintInt64(int64 val, BaseTextGenerator* generator) const;
      virtual void PrintUInt64(uint64 val, BaseTextGenerator* generator) const;
      virtual void PrintFloat(float val, BaseTextGenerator* generator) const;
      virtual void PrintDouble(double val, BaseTextGenerator* generator) const;
      virtual void PrintString(const std::string& val,
                               BaseTextGenerator* generator) const;
      virtual void PrintBytes(const std::string& val,
                              BaseTextGenerator* generator) const;
      virtual void PrintEnum(int32 val, const std::string& name,
                             BaseTextGenerator* generator) const;
      virtual void PrintFieldName(const Message& message, int field_index,
                                  int field_count, const Reflection* reflection,
                                  const FieldDescriptor* field,
                                  BaseTextGenerator* generator) const;
      virtual void PrintFieldName(const Message& message,
                                  const Reflection* reflection,
                                  const FieldDescriptor* field,
                                  BaseTextGenerator* generator) const;
      virtual void PrintMessageStart(const Message& message, int field_index,
                                     int field_count, bool single_line_mode,
                                     BaseTextGenerator* generator) const;
      virtual void PrintMessageEnd(const Message& message, int field_index,
                                   int field_count, bool single_line_mode,
                                   BaseTextGenerator* generator) const;
  
     private:
      GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter);
    };
  
    class PROTOBUF_EXPORT PROTOBUF_DEPRECATED_MSG(
        "Please use FastFieldValuePrinter") FieldValuePrinter {
     public:
      FieldValuePrinter();
      virtual ~FieldValuePrinter();
      virtual std::string PrintBool(bool val) const;
      virtual std::string PrintInt32(int32 val) const;
      virtual std::string PrintUInt32(uint32 val) const;
      virtual std::string PrintInt64(int64 val) const;
      virtual std::string PrintUInt64(uint64 val) const;
      virtual std::string PrintFloat(float val) const;
      virtual std::string PrintDouble(double val) const;
      virtual std::string PrintString(const std::string& val) const;
      virtual std::string PrintBytes(const std::string& val) const;
      virtual std::string PrintEnum(int32 val, const std::string& name) const;
      virtual std::string PrintFieldName(const Message& message,
                                    const Reflection* reflection,
                                    const FieldDescriptor* field) const;
      virtual std::string PrintMessageStart(const Message& message,
                                       int field_index,
                                       int field_count,
                                       bool single_line_mode) const;
      virtual std::string PrintMessageEnd(const Message& message,
                                     int field_index,
                                     int field_count,
                                     bool single_line_mode) const;
  
     private:
      FastFieldValuePrinter delegate_;
      GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
    };
  
    class PROTOBUF_EXPORT MessagePrinter {
     public:
      MessagePrinter() {}
      virtual ~MessagePrinter() {}
      virtual void Print(const Message& message, bool single_line_mode,
                         BaseTextGenerator* generator) const = 0;
  
     private:
      GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessagePrinter);
    };
  
    // Interface that Printers or Parsers can use to find extensions, or types
    // referenced in Any messages.
    class PROTOBUF_EXPORT Finder {
     public:
      virtual ~Finder();
  
      // Try to find an extension of *message by fully-qualified field
      // name.  Returns NULL if no extension is known for this name or number.
      // The base implementation uses the extensions already known by the message.
      virtual const FieldDescriptor* FindExtension(
          Message* message,
          const std::string& name) const;
  
      // Find the message type for an Any proto.
      // Returns NULL if no message is known for this name.
      // The base implementation only accepts prefixes of type.googleprod.com/ or
      // type.googleapis.com/, and searches the DescriptorPool of the parent
      // message.
      virtual const Descriptor* FindAnyType(const Message& message,
                                            const std::string& prefix,
                                            const std::string& name) const;
    };
  
    // Class for those users which require more fine-grained control over how
    // a protobuffer message is printed out.
    class PROTOBUF_EXPORT Printer {
     public:
      Printer();
      ~Printer();
  
      // Like TextFormat::Print
      bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
      // Like TextFormat::PrintUnknownFields
      bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
                              io::ZeroCopyOutputStream* output) const;
      // Like TextFormat::PrintToString
      bool PrintToString(const Message& message, std::string* output) const;
      // Like TextFormat::PrintUnknownFieldsToString
      bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
                                      std::string* output) const;
      // Like TextFormat::PrintFieldValueToString
      void PrintFieldValueToString(const Message& message,
                                   const FieldDescriptor* field,
                                   int index,
                                   std::string* output) const;
  
      // Adjust the initial indent level of all output.  Each indent level is
      // equal to two spaces.
      void SetInitialIndentLevel(int indent_level) {
        initial_indent_level_ = indent_level;
      }
  
      // If printing in single line mode, then the entire message will be output
      // on a single line with no line breaks.
      void SetSingleLineMode(bool single_line_mode) {
        single_line_mode_ = single_line_mode;
      }
  
      bool IsInSingleLineMode() const {
        return single_line_mode_;
      }
  
      // If use_field_number is true, uses field number instead of field name.
      void SetUseFieldNumber(bool use_field_number) {
        use_field_number_ = use_field_number;
      }
  
      // Set true to print repeated primitives in a format like:
      //   field_name: [1, 2, 3, 4]
      // instead of printing each value on its own line.  Short format applies
      // only to primitive values -- i.e. everything except strings and
      // sub-messages/groups.
      void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
        use_short_repeated_primitives_ = use_short_repeated_primitives;
      }
  
      // Set true to output UTF-8 instead of ASCII.  The only difference
      // is that bytes >= 0x80 in string fields will not be escaped,
      // because they are assumed to be part of UTF-8 multi-byte
      // sequences. This will change the default FastFieldValuePrinter.
      void SetUseUtf8StringEscaping(bool as_utf8);
  
      // Set the default (Fast)FieldValuePrinter that is used for all fields that
      // don't have a field-specific printer registered.
      // Takes ownership of the printer.
      void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer);
      void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
  
      // Sets whether we want to hide unknown fields or not.
      // Usually unknown fields are printed in a generic way that includes the
      // tag number of the field instead of field name. However, sometimes it
      // is useful to be able to print the message without unknown fields (e.g.
      // for the python protobuf version to maintain consistency between its pure
      // python and c++ implementations).
      void SetHideUnknownFields(bool hide) {
        hide_unknown_fields_ = hide;
      }
  
      // If print_message_fields_in_index_order is true, fields of a proto message
      // will be printed using the order defined in source code instead of the
      // field number, extensions will be printed at the end of the message
      // and their relative order is determined by the extension number.
      // By default, use the field number order.
      void SetPrintMessageFieldsInIndexOrder(
          bool print_message_fields_in_index_order) {
        print_message_fields_in_index_order_ =
            print_message_fields_in_index_order;
      }
  
      // If expand==true, expand google.protobuf.Any payloads. The output
      // will be of form
      //    [type_url] { <value_printed_in_text> }
      //
      // If expand==false, print Any using the default printer. The output will
      // look like
      //    type_url: "<type_url>"  value: "serialized_content"
      void SetExpandAny(bool expand) {
        expand_any_ = expand;
      }
  
      // Set how parser finds message for Any payloads.
      void SetFinder(const Finder* finder) { finder_ = finder; }
  
      // If non-zero, we truncate all string fields that are  longer than this
      // threshold.  This is useful when the proto message has very long strings,
      // e.g., dump of encoded image file.
      //
      // NOTE(hfgong):  Setting a non-zero value breaks round-trip safe
      // property of TextFormat::Printer.  That is, from the printed message, we
      // cannot fully recover the original string field any more.
      void SetTruncateStringFieldLongerThan(
          const int64 truncate_string_field_longer_than) {
        truncate_string_field_longer_than_ = truncate_string_field_longer_than;
      }
  
      // Register a custom field-specific (Fast)FieldValuePrinter for fields
      // with a particular FieldDescriptor.
      // Returns "true" if the registration succeeded, or "false", if there is
      // already a printer for that FieldDescriptor.
      // Takes ownership of the printer on successful registration.
      bool RegisterFieldValuePrinter(const FieldDescriptor* field,
                                     const FieldValuePrinter* printer);
      bool RegisterFieldValuePrinter(const FieldDescriptor* field,
                                     const FastFieldValuePrinter* printer);
  
      // Register a custom message-specific MessagePrinter for messages with a
      // particular Descriptor.
      // Returns "true" if the registration succeeded, or "false" if there is
      // already a printer for that Descriptor.
      bool RegisterMessagePrinter(const Descriptor* descriptor,
                                  const MessagePrinter* printer);
  
     private:
      // Forward declaration of an internal class used to print the text
      // output to the OutputStream (see text_format.cc for implementation).
      class TextGenerator;
  
      // Internal Print method, used for writing to the OutputStream via
      // the TextGenerator class.
      void Print(const Message& message, TextGenerator* generator) const;
  
      // Print a single field.
      void PrintField(const Message& message, const Reflection* reflection,
                      const FieldDescriptor* field,
                      TextGenerator* generator) const;
  
      // Print a repeated primitive field in short form.
      void PrintShortRepeatedField(const Message& message,
                                   const Reflection* reflection,
                                   const FieldDescriptor* field,
                                   TextGenerator* generator) const;
  
      // Print the name of a field -- i.e. everything that comes before the
      // ':' for a single name/value pair.
      void PrintFieldName(const Message& message, int field_index,
                          int field_count, const Reflection* reflection,
                          const FieldDescriptor* field,
                          TextGenerator* generator) const;
  
      // Outputs a textual representation of the value of the field supplied on
      // the message supplied or the default value if not set.
      void PrintFieldValue(const Message& message, const Reflection* reflection,
                           const FieldDescriptor* field, int index,
                           TextGenerator* generator) const;
  
      // Print the fields in an UnknownFieldSet.  They are printed by tag number
      // only.  Embedded messages are heuristically identified by attempting to
      // parse them.
      void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
                              TextGenerator* generator) const;
  
      bool PrintAny(const Message& message, TextGenerator* generator) const;
  
      int initial_indent_level_;
  
      bool single_line_mode_;
  
      bool use_field_number_;
  
      bool use_short_repeated_primitives_;
  
      bool hide_unknown_fields_;
  
      bool print_message_fields_in_index_order_;
  
      bool expand_any_;
  
      int64 truncate_string_field_longer_than_;
  
      std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_;
      typedef std::map<const FieldDescriptor*, const FastFieldValuePrinter*>
          CustomPrinterMap;
      CustomPrinterMap custom_printers_;
  
      typedef std::map<const Descriptor*, const MessagePrinter*>
          CustomMessagePrinterMap;
      CustomMessagePrinterMap custom_message_printers_;
  
      const Finder* finder_;
    };
  
    // Parses a text-format protocol message from the given input stream to
    // the given message object. This function parses the human-readable format
    // written by Print(). Returns true on success. The message is cleared first,
    // even if the function fails -- See Merge() to avoid this behavior.
    //
    // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"
    //
    // One use for this function is parsing handwritten strings in test code.
    // Another use is to parse the output from google::protobuf::Message::DebugString()
    // (or ShortDebugString()), because these functions output using
    // google::protobuf::TextFormat::Print().
    //
    // If you would like to read a protocol buffer serialized in the
    // (non-human-readable) binary wire format, see
    // google::protobuf::MessageLite::ParseFromString().
    static bool Parse(io::ZeroCopyInputStream* input, Message* output);
    // Like Parse(), but reads directly from a string.
    static bool ParseFromString(const std::string& input, Message* output);
  
    // Like Parse(), but the data is merged into the given message, as if
    // using Message::MergeFrom().
    static bool Merge(io::ZeroCopyInputStream* input, Message* output);
    // Like Merge(), but reads directly from a string.
    static bool MergeFromString(const std::string& input, Message* output);
  
    // Parse the given text as a single field value and store it into the
    // given field of the given message. If the field is a repeated field,
    // the new value will be added to the end
    static bool ParseFieldValueFromString(const std::string& input,
                                          const FieldDescriptor* field,
                                          Message* message);
  
    // A location in the parsed text.
    struct ParseLocation {
      int line;
      int column;
  
      ParseLocation() : line(-1), column(-1) {}
      ParseLocation(int line_param, int column_param)
          : line(line_param), column(column_param) {}
    };
  
    // Data structure which is populated with the locations of each field
    // value parsed from the text.
    class PROTOBUF_EXPORT ParseInfoTree {
     public:
      ParseInfoTree();
      ~ParseInfoTree();
  
      // Returns the parse location for index-th value of the field in the parsed
      // text. If none exists, returns a location with line = -1. Index should be
      // -1 for not-repeated fields.
      ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
  
      // Returns the parse info tree for the given field, which must be a message
      // type. The nested information tree is owned by the root tree and will be
      // deleted when it is deleted.
      ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
                                      int index) const;
  
     private:
      // Allow the text format parser to record information into the tree.
      friend class TextFormat;
  
      // Records the starting location of a single value for a field.
      void RecordLocation(const FieldDescriptor* field, ParseLocation location);
  
      // Create and records a nested tree for a nested message field.
      ParseInfoTree* CreateNested(const FieldDescriptor* field);
  
      // Defines the map from the index-th field descriptor to its parse location.
      typedef std::map<const FieldDescriptor*,
                       std::vector<ParseLocation> > LocationMap;
  
      // Defines the map from the index-th field descriptor to the nested parse
      // info tree.
      typedef std::map<const FieldDescriptor*,
                       std::vector<ParseInfoTree*> > NestedMap;
  
      LocationMap locations_;
      NestedMap nested_;
  
      GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
    };
  
    // For more control over parsing, use this class.
    class PROTOBUF_EXPORT Parser {
     public:
      Parser();
      ~Parser();
  
      // Like TextFormat::Parse().
      bool Parse(io::ZeroCopyInputStream* input, Message* output);
      // Like TextFormat::ParseFromString().
      bool ParseFromString(const std::string& input, Message* output);
      // Like TextFormat::Merge().
      bool Merge(io::ZeroCopyInputStream* input, Message* output);
      // Like TextFormat::MergeFromString().
      bool MergeFromString(const std::string& input, Message* output);
  
      // Set where to report parse errors.  If NULL (the default), errors will
      // be printed to stderr.
      void RecordErrorsTo(io::ErrorCollector* error_collector) {
        error_collector_ = error_collector;
      }
  
      // Set how parser finds extensions.  If NULL (the default), the
      // parser will use the standard Reflection object associated with
      // the message being parsed.
      void SetFinder(const Finder* finder) { finder_ = finder; }
  
      // Sets where location information about the parse will be written. If NULL
      // (the default), then no location will be written.
      void WriteLocationsTo(ParseInfoTree* tree) {
        parse_info_tree_ = tree;
      }
  
      // Normally parsing fails if, after parsing, output->IsInitialized()
      // returns false.  Call AllowPartialMessage(true) to skip this check.
      void AllowPartialMessage(bool allow) {
        allow_partial_ = allow;
      }
  
      // Allow field names to be matched case-insensitively.
      // This is not advisable if there are fields that only differ in case, or
      // if you want to enforce writing in the canonical form.
      // This is 'false' by default.
      void AllowCaseInsensitiveField(bool allow) {
        allow_case_insensitive_field_ = allow;
      }
  
      // Like TextFormat::ParseFieldValueFromString
      bool ParseFieldValueFromString(const std::string& input,
                                     const FieldDescriptor* field,
                                     Message* output);
  
      // When an unknown extension is met, parsing will fail if this option is set
      // to false (the default). If true, unknown extensions will be ignored and
      // a warning message will be generated.
      void AllowUnknownExtension(bool allow) {
        allow_unknown_extension_ = allow;
      }
  
  
      void AllowFieldNumber(bool allow) {
        allow_field_number_ = allow;
      }
  
     private:
      // Forward declaration of an internal class used to parse text
      // representations (see text_format.cc for implementation).
      class ParserImpl;
  
      // Like TextFormat::Merge().  The provided implementation is used
      // to do the parsing.
      bool MergeUsingImpl(io::ZeroCopyInputStream* input,
                          Message* output,
                          ParserImpl* parser_impl);
  
      io::ErrorCollector* error_collector_;
      const Finder* finder_;
      ParseInfoTree* parse_info_tree_;
      bool allow_partial_;
      bool allow_case_insensitive_field_;
      bool allow_unknown_field_;
      bool allow_unknown_extension_;
      bool allow_unknown_enum_;
      bool allow_field_number_;
      bool allow_relaxed_whitespace_;
      bool allow_singular_overwrites_;
    };
  
  
   private:
    // Hack: ParseInfoTree declares TextFormat as a friend which should extend
    // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
    // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
    // helpers for ParserImpl to call methods of ParseInfoTree.
    static inline void RecordLocation(ParseInfoTree* info_tree,
                                      const FieldDescriptor* field,
                                      ParseLocation location);
    static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
                                              const FieldDescriptor* field);
  
    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
  };
  
  inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
                                         const FieldDescriptor* field,
                                         ParseLocation location) {
    info_tree->RecordLocation(field, location);
  }
  
  
  inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
      ParseInfoTree* info_tree, const FieldDescriptor* field) {
    return info_tree->CreateNested(field);
  }
  
  }  // namespace protobuf
  }  // namespace google
  
  #include <google/protobuf/port_undef.inc>
  
  #endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
  