webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
proto_writer.h
Go to the documentation of this file.
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 #ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
32 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
33 
34 #include <deque>
36 #include <string>
37 
48 
49 namespace google {
50 namespace protobuf {
51 namespace io {
52 class CodedOutputStream;
53 } // namespace io
54 } // namespace protobuf
55 
56 
57 namespace protobuf {
58 class Type;
59 class Field;
60 } // namespace protobuf
61 
62 
63 namespace protobuf {
64 namespace util {
65 namespace converter {
66 
67 class ObjectLocationTracker;
68 
69 // An ObjectWriter that can write protobuf bytes directly from writer events.
70 // This class does not support special types like Struct or Map. However, since
71 // this class supports raw protobuf, it can be used to provide support for
72 // special types by inheriting from it or by wrapping it.
73 //
74 // It also supports streaming.
76  public:
77 // Constructor. Does not take ownership of any parameter passed in.
79  strings::ByteSink* output, ErrorListener* listener);
80  virtual ~ProtoWriter();
81 
82  // ObjectWriter methods.
83  virtual ProtoWriter* StartObject(StringPiece name);
84  virtual ProtoWriter* EndObject();
85  virtual ProtoWriter* StartList(StringPiece name);
86  virtual ProtoWriter* EndList();
87  virtual ProtoWriter* RenderBool(StringPiece name, bool value) {
88  return RenderDataPiece(name, DataPiece(value));
89  }
91  return RenderDataPiece(name, DataPiece(value));
92  }
94  return RenderDataPiece(name, DataPiece(value));
95  }
97  return RenderDataPiece(name, DataPiece(value));
98  }
100  return RenderDataPiece(name, DataPiece(value));
101  }
102  virtual ProtoWriter* RenderDouble(StringPiece name, double value) {
103  return RenderDataPiece(name, DataPiece(value));
104  }
105  virtual ProtoWriter* RenderFloat(StringPiece name, float value) {
106  return RenderDataPiece(name, DataPiece(value));
107  }
109  return RenderDataPiece(name,
110  DataPiece(value, use_strict_base64_decoding()));
111  }
113  return RenderDataPiece(
114  name, DataPiece(value, false, use_strict_base64_decoding()));
115  }
117  return RenderDataPiece(name, DataPiece::NullData());
118  }
119 
120  // Renders a DataPiece 'value' into a field whose wire type is determined
121  // from the given field 'name'.
122  virtual ProtoWriter* RenderDataPiece(StringPiece name,
123  const DataPiece& value);
124 
125  // Returns the location tracker to use for tracking locations for errors.
127  return element_ != NULL ? *element_ : *tracker_;
128  }
129 
130  // When true, we finished writing to output a complete message.
131  bool done() { return done_; }
132 
133  // Returns the proto stream object.
134  google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); }
135 
136  // Getters and mutators of invalid_depth_.
137  void IncrementInvalidDepth() { ++invalid_depth_; }
138  void DecrementInvalidDepth() { --invalid_depth_; }
139  int invalid_depth() { return invalid_depth_; }
140 
141  ErrorListener* listener() { return listener_; }
142 
143  const TypeInfo* typeinfo() { return typeinfo_; }
144 
145  protected:
147  public:
148  // Constructor for the root element. No parent nor field.
149  ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type,
150  ProtoWriter* enclosing);
151 
152  // Constructor for a field of an element.
154  const google::protobuf::Type& type, bool is_list);
155 
156  virtual ~ProtoElement() {}
157 
158  // Called just before the destructor for clean up:
159  // - reports any missing required fields
160  // - computes the space needed by the size field, and augment the
161  // length of all parent messages by this additional space.
162  // - releases and returns the parent pointer.
163  ProtoElement* pop();
164 
165  // Accessors
166  // parent_field() may be NULL if we are at root.
168  return parent_field_;
169  }
170  const google::protobuf::Type& type() const { return type_; }
171 
172  // Registers field for accounting required fields.
173  void RegisterField(const google::protobuf::Field* field);
174 
175  // To report location on error messages.
176  virtual string ToString() const;
177 
178  virtual ProtoElement* parent() const {
179  return static_cast<ProtoElement*>(BaseElement::parent());
180  }
181 
182  // Returns true if the index is already taken by a preceeding oneof input.
183  bool IsOneofIndexTaken(int32 index);
184 
185  // Marks the oneof 'index' as taken. Future inputs to this oneof will
186  // generate an error.
187  void TakeOneofIndex(int32 index);
188 
189  private:
190  // Used for access to variables of the enclosing instance of
191  // ProtoWriter.
192  ProtoWriter* ow_;
193 
194  // Describes the element as a field in the parent message.
195  // parent_field_ is NULL if and only if this element is the root element.
196  const google::protobuf::Field* parent_field_;
197 
198  // TypeInfo to lookup types.
199  const TypeInfo* typeinfo_;
200 
201  // Additional variables if this element is a message:
202  // (Root element is always a message).
203  // type_ : the type of this element.
204  // required_fields_ : set of required fields.
205  // size_index_ : index into ProtoWriter::size_insert_
206  // for later insertion of serialized message length.
207  const google::protobuf::Type& type_;
208  std::set<const google::protobuf::Field*> required_fields_;
209  const int size_index_;
210 
211  // Tracks position in repeated fields, needed for LocationTrackerInterface.
212  int array_index_;
213 
214  // Set of oneof indices already seen for the type_. Used to validate
215  // incoming messages so no more than one oneof is set.
216  hash_set<int32> oneof_indices_;
217 
219  };
220 
221  // Container for inserting 'size' information at the 'pos' position.
222  struct SizeInfo {
223  const int pos;
224  int size;
225  };
226 
227  ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type,
228  strings::ByteSink* output, ErrorListener* listener);
229 
230  virtual ProtoElement* element() { return element_.get(); }
231 
232  // Helper methods for calling ErrorListener. See error_listener.h.
233  void InvalidName(StringPiece unknown_name, StringPiece message);
234  void InvalidValue(StringPiece type_name, StringPiece value);
235  void MissingField(StringPiece missing_name);
236 
237  // Common code for BeginObject() and BeginList() that does invalid_depth_
238  // bookkeeping associated with name lookup.
239  const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list);
240 
241  // Lookup the field in the current element. Looks in the base descriptor
242  // and in any extension. This will report an error if the field cannot be
243  // found or if multiple matching extensions are found.
244  const google::protobuf::Field* Lookup(StringPiece name);
245 
246  // Lookup the field type in the type descriptor. Returns NULL if the type
247  // is not known.
248  const google::protobuf::Type* LookupType(
250 
251  // Write serialized output to the final output ByteSink, inserting all
252  // the size information for nested messages that are missing from the
253  // intermediate Cord buffer.
254  void WriteRootMessage();
255 
256  // Helper method to write proto tags based on the given field.
257  void WriteTag(const google::protobuf::Field& field);
258 
259 
260  // Returns true if the field for type_ can be set as a oneof. If field is not
261  // a oneof type, this function does nothing and returns true.
262  // If another field for this oneof is already set, this function returns
263  // false. It also calls the appropriate error callback.
264  // unnormalized_name is used for error string.
265  bool ValidOneof(const google::protobuf::Field& field,
266  StringPiece unnormalized_name);
267 
268  // Returns true if the field is repeated.
269  bool IsRepeated(const google::protobuf::Field& field);
270 
271  // Starts an object given the field and the enclosing type.
272  ProtoWriter* StartObjectField(const google::protobuf::Field& field,
273  const google::protobuf::Type& type);
274 
275  // Starts a list given the field and the enclosing type.
276  ProtoWriter* StartListField(const google::protobuf::Field& field,
277  const google::protobuf::Type& type);
278 
279  // Renders a primitve field given the field and the enclosing type.
280  ProtoWriter* RenderPrimitiveField(const google::protobuf::Field& field,
281  const google::protobuf::Type& type,
282  const DataPiece& value);
283 
284  private:
285  // Variables for describing the structure of the input tree:
286  // master_type_: descriptor for the whole protobuf message.
287  // typeinfo_ : the TypeInfo object to lookup types.
288  const google::protobuf::Type& master_type_;
289  const TypeInfo* typeinfo_;
290  // Whether we own the typeinfo_ object.
291  bool own_typeinfo_;
292 
293  // Indicates whether we finished writing root message completely.
294  bool done_;
295 
296  // Variable for internal state processing:
297  // element_ : the current element.
298  // size_insert_: sizes of nested messages.
299  // pos - position to insert the size field.
300  // size - size value to be inserted.
302  std::deque<SizeInfo> size_insert_;
303 
304  // Variables for output generation:
305  // output_ : pointer to an external ByteSink for final user-visible output.
306  // buffer_ : buffer holding partial message before being ready for output_.
307  // adapter_ : internal adapter between CodedOutputStream and buffer_.
308  // stream_ : wrapper for writing tags and other encodings in wire format.
309  strings::ByteSink* output_;
310  string buffer_;
313 
314  // Variables for error tracking and reporting:
315  // listener_ : a place to report any errors found.
316  // invalid_depth_: number of enclosing invalid nested messages.
317  // tracker_ : the root location tracker interface.
318  ErrorListener* listener_;
319  int invalid_depth_;
321 
323 };
324 
325 } // namespace converter
326 } // namespace util
327 } // namespace protobuf
328 
329 } // namespace google
330 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
virtual ProtoWriter * RenderBytes(StringPiece name, StringPiece value)
Definition: proto_writer.h:112
ErrorListener * listener()
Definition: proto_writer.h:141
virtual ProtoWriter * RenderInt64(StringPiece name, int64 value)
Definition: proto_writer.h:96
Definition: zero_copy_stream_impl_lite.h:133
Definition: util.py:1
const FieldDescriptor * field
Definition: parser_unittest.cc:2279
void IncrementInvalidDepth()
Definition: proto_writer.h:137
NSMutableData * buffer_
Definition: GPBCodedOutputStream.m:49
virtual ProtoWriter * RenderDouble(StringPiece name, double value)
Definition: proto_writer.h:102
void DecrementInvalidDepth()
Definition: proto_writer.h:138
const TypeInfo * typeinfo()
Definition: proto_writer.h:143
cricket::VideoAdapter adapter_
Definition: vie_encoder_unittest.cc:169
virtual ProtoWriter * RenderUint64(StringPiece name, uint64 value)
Definition: proto_writer.h:99
virtual ProtoWriter * RenderBool(StringPiece name, bool value)
Definition: proto_writer.h:87
#define output
Definition: wire_format_lite.h:418
Definition: type_resolver.h:54
int32_t int32
Definition: port.h:130
virtual ProtoWriter * RenderUint32(StringPiece name, uint32 value)
Definition: proto_writer.h:93
Definition: stringpiece.h:178
#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: macros.h:45
virtual ProtoElement * parent() const
Definition: proto_writer.h:178
int invalid_depth()
Definition: proto_writer.h:139
GLuint index
Definition: gl2.h:383
EGLAttrib * value
Definition: eglext.h:120
virtual ProtoWriter * RenderString(StringPiece name, StringPiece value)
Definition: proto_writer.h:108
virtual ProtoWriter * RenderInt32(StringPiece name, int32 value)
Definition: proto_writer.h:90
const LocationTrackerInterface & location()
Definition: proto_writer.h:126
google::protobuf::io::CodedOutputStream * stream()
Definition: proto_writer.h:134
const google::protobuf::Type & type() const
Definition: proto_writer.h:170
const int pos
Definition: proto_writer.h:223
uint32_t uint32
Definition: port.h:135
bool done()
Definition: proto_writer.h:131
EGLImageKHR EGLint * name
Definition: eglext.h:851
Definition: __init__.py:1
uint64_t uint64
Definition: port.h:136
std::string ToString(const T &value)
Definition: angleutils.h:163
Definition: type.pb.h:276
Definition: type.pb.h:133
Definition: structured_objectwriter.h:59
EGLenum type
Definition: eglext.h:63
Definition: scoped_ptr.h:48
const google::protobuf::Field * parent_field() const
Definition: proto_writer.h:167
virtual ProtoElement * element()
Definition: proto_writer.h:230
int64_t int64
Definition: port.h:131
#define NULL
Definition: common_types.h:41
TypeResolver * type_resolver
Definition: conformance_cpp.cc:60
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
Definition: gflags_completions.h:115
Definition: coded_stream.h:665
Type
Type of JSON value.
Definition: rapidjson.h:616
virtual ProtoWriter * RenderNull(StringPiece name)
Definition: proto_writer.h:116
GLuint GLsizei const GLchar * message
Definition: gl2ext.h:137
virtual ProtoWriter * RenderFloat(StringPiece name, float value)
Definition: proto_writer.h:105
virtual ~ProtoElement()
Definition: proto_writer.h:156