Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      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: jschorr (at) google.com (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 <string>
     42 #include <google/protobuf/message.h>
     43 #include <google/protobuf/descriptor.h>
     44 
     45 namespace google {
     46 namespace protobuf {
     47 
     48 namespace io {
     49   class ErrorCollector;      // tokenizer.h
     50 }
     51 
     52 // This class implements protocol buffer text format.  Printing and parsing
     53 // protocol messages in text format is useful for debugging and human editing
     54 // of messages.
     55 //
     56 // This class is really a namespace that contains only static methods.
     57 class LIBPROTOBUF_EXPORT TextFormat {
     58  public:
     59   // Outputs a textual representation of the given message to the given
     60   // output stream.
     61   static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
     62 
     63   // Print the fields in an UnknownFieldSet.  They are printed by tag number
     64   // only.  Embedded messages are heuristically identified by attempting to
     65   // parse them.
     66   static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
     67                                  io::ZeroCopyOutputStream* output);
     68 
     69   // Like Print(), but outputs directly to a string.
     70   static bool PrintToString(const Message& message, string* output);
     71 
     72   // Like PrintUnknownFields(), but outputs directly to a string.
     73   static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
     74                                          string* output);
     75 
     76   // Outputs a textual representation of the value of the field supplied on
     77   // the message supplied. For non-repeated fields, an index of -1 must
     78   // be supplied. Note that this method will print the default value for a
     79   // field if it is not set.
     80   static void PrintFieldValueToString(const Message& message,
     81                                       const FieldDescriptor* field,
     82                                       int index,
     83                                       string* output);
     84 
     85   // Class for those users which require more fine-grained control over how
     86   // a protobuffer message is printed out.
     87   class LIBPROTOBUF_EXPORT Printer {
     88    public:
     89     Printer();
     90     ~Printer();
     91 
     92     // Like TextFormat::Print
     93     bool Print(const Message& message, io::ZeroCopyOutputStream* output);
     94     // Like TextFormat::PrintUnknownFields
     95     bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
     96                             io::ZeroCopyOutputStream* output);
     97     // Like TextFormat::PrintToString
     98     bool PrintToString(const Message& message, string* output);
     99     // Like TextFormat::PrintUnknownFieldsToString
    100     bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
    101                                     string* output);
    102     // Like TextFormat::PrintFieldValueToString
    103     void PrintFieldValueToString(const Message& message,
    104                                  const FieldDescriptor* field,
    105                                  int index,
    106                                  string* output);
    107 
    108     // Adjust the initial indent level of all output.  Each indent level is
    109     // equal to two spaces.
    110     void SetInitialIndentLevel(int indent_level) {
    111       initial_indent_level_ = indent_level;
    112     }
    113 
    114     // If printing in single line mode, then the entire message will be output
    115     // on a single line with no line breaks.
    116     void SetSingleLineMode(bool single_line_mode) {
    117       single_line_mode_ = single_line_mode;
    118     }
    119 
    120     // Set true to print repeated primitives in a format like:
    121     //   field_name: [1, 2, 3, 4]
    122     // instead of printing each value on its own line.  Short format applies
    123     // only to primitive values -- i.e. everything except strings and
    124     // sub-messages/groups.  Note that at present this format is not recognized
    125     // by the parser.
    126     void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
    127       use_short_repeated_primitives_ = use_short_repeated_primitives;
    128     }
    129 
    130     // Set true to output UTF-8 instead of ASCII.  The only difference
    131     // is that bytes >= 0x80 in string fields will not be escaped,
    132     // because they are assumed to be part of UTF-8 multi-byte
    133     // sequences.
    134     void SetUseUtf8StringEscaping(bool as_utf8) {
    135       utf8_string_escaping_ = as_utf8;
    136     }
    137 
    138    private:
    139     // Forward declaration of an internal class used to print the text
    140     // output to the OutputStream (see text_format.cc for implementation).
    141     class TextGenerator;
    142 
    143     // Internal Print method, used for writing to the OutputStream via
    144     // the TextGenerator class.
    145     void Print(const Message& message,
    146                TextGenerator& generator);
    147 
    148     // Print a single field.
    149     void PrintField(const Message& message,
    150                     const Reflection* reflection,
    151                     const FieldDescriptor* field,
    152                     TextGenerator& generator);
    153 
    154     // Print a repeated primitive field in short form.
    155     void PrintShortRepeatedField(const Message& message,
    156                                  const Reflection* reflection,
    157                                  const FieldDescriptor* field,
    158                                  TextGenerator& generator);
    159 
    160     // Print the name of a field -- i.e. everything that comes before the
    161     // ':' for a single name/value pair.
    162     void PrintFieldName(const Message& message,
    163                         const Reflection* reflection,
    164                         const FieldDescriptor* field,
    165                         TextGenerator& generator);
    166 
    167     // Outputs a textual representation of the value of the field supplied on
    168     // the message supplied or the default value if not set.
    169     void PrintFieldValue(const Message& message,
    170                          const Reflection* reflection,
    171                          const FieldDescriptor* field,
    172                          int index,
    173                          TextGenerator& generator);
    174 
    175     // Print the fields in an UnknownFieldSet.  They are printed by tag number
    176     // only.  Embedded messages are heuristically identified by attempting to
    177     // parse them.
    178     void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
    179                             TextGenerator& generator);
    180 
    181     int initial_indent_level_;
    182 
    183     bool single_line_mode_;
    184 
    185     bool use_short_repeated_primitives_;
    186 
    187     bool utf8_string_escaping_;
    188   };
    189 
    190   // Parses a text-format protocol message from the given input stream to
    191   // the given message object.  This function parses the format written
    192   // by Print().
    193   static bool Parse(io::ZeroCopyInputStream* input, Message* output);
    194   // Like Parse(), but reads directly from a string.
    195   static bool ParseFromString(const string& input, Message* output);
    196 
    197   // Like Parse(), but the data is merged into the given message, as if
    198   // using Message::MergeFrom().
    199   static bool Merge(io::ZeroCopyInputStream* input, Message* output);
    200   // Like Merge(), but reads directly from a string.
    201   static bool MergeFromString(const string& input, Message* output);
    202 
    203   // Parse the given text as a single field value and store it into the
    204   // given field of the given message. If the field is a repeated field,
    205   // the new value will be added to the end
    206   static bool ParseFieldValueFromString(const string& input,
    207                                         const FieldDescriptor* field,
    208                                         Message* message);
    209 
    210   // For more control over parsing, use this class.
    211   class LIBPROTOBUF_EXPORT Parser {
    212    public:
    213     Parser();
    214     ~Parser();
    215 
    216     // Like TextFormat::Parse().
    217     bool Parse(io::ZeroCopyInputStream* input, Message* output);
    218     // Like TextFormat::ParseFromString().
    219     bool ParseFromString(const string& input, Message* output);
    220     // Like TextFormat::Merge().
    221     bool Merge(io::ZeroCopyInputStream* input, Message* output);
    222     // Like TextFormat::MergeFromString().
    223     bool MergeFromString(const string& input, Message* output);
    224 
    225     // Set where to report parse errors.  If NULL (the default), errors will
    226     // be printed to stderr.
    227     void RecordErrorsTo(io::ErrorCollector* error_collector) {
    228       error_collector_ = error_collector;
    229     }
    230 
    231     // Normally parsing fails if, after parsing, output->IsInitialized()
    232     // returns false.  Call AllowPartialMessage(true) to skip this check.
    233     void AllowPartialMessage(bool allow) {
    234       allow_partial_ = allow;
    235     }
    236 
    237     // Like TextFormat::ParseFieldValueFromString
    238     bool ParseFieldValueFromString(const string& input,
    239                                    const FieldDescriptor* field,
    240                                    Message* output);
    241 
    242    private:
    243     // Forward declaration of an internal class used to parse text
    244     // representations (see text_format.cc for implementation).
    245     class ParserImpl;
    246 
    247     // Like TextFormat::Merge().  The provided implementation is used
    248     // to do the parsing.
    249     bool MergeUsingImpl(io::ZeroCopyInputStream* input,
    250                         Message* output,
    251                         ParserImpl* parser_impl);
    252 
    253     io::ErrorCollector* error_collector_;
    254     bool allow_partial_;
    255   };
    256 
    257  private:
    258   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
    259 };
    260 
    261 }  // namespace protobuf
    262 
    263 }  // namespace google
    264 #endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
    265