webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
protostream_objectwriter.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_PROTOSTREAM_OBJECTWRITER_H__
32 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
33 
34 #include <deque>
36 #include <string>
37 
49 
50 namespace google {
51 namespace protobuf {
52 namespace io {
53 class CodedOutputStream;
54 } // namespace io
55 } // namespace protobuf
56 
57 
58 namespace protobuf {
59 class Type;
60 class Field;
61 } // namespace protobuf
62 
63 
64 namespace protobuf {
65 namespace util {
66 namespace converter {
67 
68 class ObjectLocationTracker;
69 
70 // An ObjectWriter that can write protobuf bytes directly from writer events.
71 // This class supports all special types like Struct and Map. It uses
72 // the ProtoWriter class to write raw proto bytes.
73 //
74 // It also supports streaming.
76  public:
77  // Options that control ProtoStreamObjectWriter class's behavior.
78  struct Options {
79  // Treats integer inputs in google.protobuf.Struct as strings. Normally,
80  // integer values are returned in double field "number_value" of
81  // google.protobuf.Struct. However, this can cause precision loss for
82  // int64/uint64 inputs. This option is provided for cases that want to
83  // preserve integer precision.
85 
86  Options() : struct_integers_as_strings(false) {}
87 
88  // Default instance of Options with all options set to defaults.
89  static const Options& Defaults() {
90  static Options defaults;
91  return defaults;
92  }
93  };
94 
95 // Constructor. Does not take ownership of any parameter passed in.
98  strings::ByteSink* output, ErrorListener* listener,
100  ProtoStreamObjectWriter::Options::Defaults());
101  virtual ~ProtoStreamObjectWriter();
102 
103  // ObjectWriter methods.
104  virtual ProtoStreamObjectWriter* StartObject(StringPiece name);
105  virtual ProtoStreamObjectWriter* EndObject();
106  virtual ProtoStreamObjectWriter* StartList(StringPiece name);
107  virtual ProtoStreamObjectWriter* EndList();
108 
109  // Renders a DataPiece 'value' into a field whose wire type is determined
110  // from the given field 'name'.
111  virtual ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
112  const DataPiece& value);
113 
114  protected:
115  // Function that renders a well known type with modified behavior.
116  typedef util::Status (*TypeRenderer)(ProtoStreamObjectWriter*,
117  const DataPiece&);
118 
119  // Handles writing Anys out using nested object writers and the like.
121  public:
122  explicit AnyWriter(ProtoStreamObjectWriter* parent);
123  ~AnyWriter();
124 
125  // Passes a StartObject call through to the Any writer.
126  void StartObject(StringPiece name);
127 
128  // Passes an EndObject call through to the Any. Returns true if the any
129  // handled the EndObject call, false if the Any is now all done and is no
130  // longer needed.
131  bool EndObject();
132 
133  // Passes a StartList call through to the Any writer.
134  void StartList(StringPiece name);
135 
136  // Passes an EndList call through to the Any writer.
137  void EndList();
138 
139  // Renders a data piece on the any.
140  void RenderDataPiece(StringPiece name, const DataPiece& value);
141 
142  private:
143  // Handles starting up the any once we have a type.
144  void StartAny(const DataPiece& value);
145 
146  // Writes the Any out to the parent writer in its serialized form.
147  void WriteAny();
148 
149  // The parent of this writer, needed for various bits such as type info and
150  // the listeners.
151  ProtoStreamObjectWriter* parent_;
152 
153  // The nested object writer, used to write events.
155 
156  // The type_url_ that this Any represents.
157  string type_url_;
158 
159  // Whether this any is invalid. This allows us to only report an invalid
160  // Any message a single time rather than every time we get a nested field.
161  bool invalid_;
162 
163  // The output data and wrapping ByteSink.
164  string data_;
165  strings::StringByteSink output_;
166 
167  // The depth within the Any, so we can track when we're done.
168  int depth_;
169 
170  // True if the type is a well-known type. Well-known types in Any
171  // has a special formating:
172  // {
173  // "@type": "type.googleapis.com/google.protobuf.XXX",
174  // "value": <JSON representation of the type>,
175  // }
176  bool is_well_known_type_;
177  TypeRenderer* well_known_type_render_;
178  };
179 
180  // Represents an item in a stack of items used to keep state between
181  // ObjectWrier events.
183  public:
184  // Indicates the type of item.
185  enum ItemType {
186  MESSAGE, // Simple message
187  MAP, // Proto3 map type
188  ANY, // Proto3 Any type
189  };
190 
191  // Constructor for the root item.
192  Item(ProtoStreamObjectWriter* enclosing, ItemType item_type,
193  bool is_placeholder, bool is_list);
194 
195  // Constructor for a field of a message.
196  Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list);
197 
198  virtual ~Item() {}
199 
200  // These functions return true if the element type is corresponding to the
201  // type in function name.
202  bool IsMap() { return item_type_ == MAP; }
203  bool IsAny() { return item_type_ == ANY; }
204 
205  AnyWriter* any() const { return any_.get(); }
206 
207  virtual Item* parent() const {
208  return static_cast<Item*>(BaseElement::parent());
209  }
210 
211  // Inserts map key into hash set if and only if the key did NOT already
212  // exist in hash set.
213  // The hash set (map_keys_) is ONLY used to keep track of map keys.
214  // Return true if insert successfully; returns false if the map key was
215  // already present.
216  bool InsertMapKeyIfNotPresent(StringPiece map_key);
217 
218  bool is_placeholder() const { return is_placeholder_; }
219  bool is_list() const { return is_list_; }
220 
221  private:
222  // Used for access to variables of the enclosing instance of
223  // ProtoStreamObjectWriter.
224  ProtoStreamObjectWriter* ow_;
225 
226  // A writer for Any objects, handles all Any-related nonsense.
228 
229  // The type of this element, see enum for permissible types.
230  ItemType item_type_;
231 
232  // Set of map keys already seen for the type_. Used to validate incoming
233  // messages so no map key appears more than once.
234  hash_set<string> map_keys_;
235 
236  // Conveys whether this Item is a placeholder or not. Placeholder items are
237  // pushed to stack to account for special types.
238  bool is_placeholder_;
239 
240  // Conveys whether this Item is a list or not. This is used to send
241  // StartList or EndList calls to underlying ObjectWriter.
242  bool is_list_;
243 
245  };
246 
247  ProtoStreamObjectWriter(const TypeInfo* typeinfo,
248  const google::protobuf::Type& type,
249  strings::ByteSink* output, ErrorListener* listener);
250 
251  // Returns true if the field is a map.
252  bool IsMap(const google::protobuf::Field& field);
253 
254  // Returns true if the field is an any.
255  bool IsAny(const google::protobuf::Field& field);
256 
257  // Returns true if the field is google.protobuf.Struct.
258  bool IsStruct(const google::protobuf::Field& field);
259 
260  // Returns true if the field is google.protobuf.Value.
261  bool IsStructValue(const google::protobuf::Field& field);
262 
263  // Returns true if the field is google.protobuf.ListValue.
264  bool IsStructListValue(const google::protobuf::Field& field);
265 
266  // Renders google.protobuf.Value in struct.proto. It picks the right oneof
267  // type based on value's type.
268  static util::Status RenderStructValue(ProtoStreamObjectWriter* ow,
269  const DataPiece& value);
270 
271  // Renders google.protobuf.Timestamp value.
272  static util::Status RenderTimestamp(ProtoStreamObjectWriter* ow,
273  const DataPiece& value);
274 
275  // Renders google.protobuf.FieldMask value.
276  static util::Status RenderFieldMask(ProtoStreamObjectWriter* ow,
277  const DataPiece& value);
278 
279  // Renders google.protobuf.Duration value.
280  static util::Status RenderDuration(ProtoStreamObjectWriter* ow,
281  const DataPiece& value);
282 
283  // Renders wrapper message types for primitive types in
284  // google/protobuf/wrappers.proto.
285  static util::Status RenderWrapperType(ProtoStreamObjectWriter* ow,
286  const DataPiece& value);
287 
288  static void InitRendererMap();
289  static void DeleteRendererMap();
290  static TypeRenderer* FindTypeRenderer(const string& type_url);
291 
292  // Returns true if the map key for type_ is not duplicated key.
293  // If map key is duplicated key, this function returns false.
294  // Note that caller should make sure that the current proto element (current_)
295  // is of element type MAP or STRUCT_MAP.
296  // It also calls the appropriate error callback and unnormalzied_name is used
297  // for error string.
298  bool ValidMapKey(StringPiece unnormalized_name);
299 
300  // Pushes an item on to the stack. Also calls either StartObject or StartList
301  // on the underlying ObjectWriter depending on whether is_list is false or
302  // not.
303  // is_placeholder conveys whether the item is a placeholder item or not.
304  // Placeholder items are pushed when adding auxillary types' StartObject or
305  // StartList calls.
306  void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder,
307  bool is_list);
308 
309  // Pops items from the stack. All placeholder items are popped until a
310  // non-placeholder item is found.
311  void Pop();
312 
313  // Pops one element from the stack. Calls EndObject() or EndList() on the
314  // underlying ObjectWriter depending on the value of is_list_.
315  void PopOneElement();
316 
317  private:
318  // Helper functions to create the map and find functions responsible for
319  // rendering well known types, keyed by type URL.
320  static hash_map<string, TypeRenderer>* renderers_;
321 
322  // Variables for describing the structure of the input tree:
323  // master_type_: descriptor for the whole protobuf message.
324  const google::protobuf::Type& master_type_;
325 
326  // The current element, variable for internal state processing.
328 
329  // Reference to the options that control this class's behavior.
330  const ProtoStreamObjectWriter::Options options_;
331 
332  GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectWriter);
333 };
334 
335 } // namespace converter
336 } // namespace util
337 } // namespace protobuf
338 
339 } // namespace google
340 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
int Pop(int s)
Definition: towers.c:169
Definition: util.py:1
virtual Item * parent() const
Definition: protostream_objectwriter.h:207
const FieldDescriptor * field
Definition: parser_unittest.cc:2279
Definition: protostream_objectwriter.h:75
string * type_url
Definition: conformance_cpp.cc:61
options
Definition: CodeGeneratorReplayInputs.py:1046
virtual ~Item()
Definition: protostream_objectwriter.h:198
ItemType
Definition: protostream_objectwriter.h:185
AnyWriter * any() const
Definition: protostream_objectwriter.h:205
static const Options & Defaults()
Definition: protostream_objectwriter.h:89
bool is_placeholder() const
Definition: protostream_objectwriter.h:218
#define output
Definition: wire_format_lite.h:418
Definition: type_resolver.h:54
Definition: stringpiece.h:178
#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: macros.h:45
EGLAttrib * value
Definition: eglext.h:120
EGLImageKHR EGLint * name
Definition: eglext.h:851
Definition: __init__.py:1
Definition: type.pb.h:276
bool IsMap()
Definition: protostream_objectwriter.h:202
bool IsMap(const google::protobuf::Field &field, const google::protobuf::Type &type)
Definition: utility.cc:312
Definition: type.pb.h:133
EGLenum type
Definition: eglext.h:63
Definition: scoped_ptr.h:48
Definition: hash.h:215
#define false
Definition: float-mm.c:5
bool IsAny()
Definition: protostream_objectwriter.h:203
TypeResolver * type_resolver
Definition: conformance_cpp.cc:60
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
Definition: gflags_completions.h:115
bool is_list() const
Definition: protostream_objectwriter.h:219
Type
Type of JSON value.
Definition: rapidjson.h:616
bool struct_integers_as_strings
Definition: protostream_objectwriter.h:84
Inspector::Protocol::Array< String > Item
Definition: InspectorProtocolObjects.h:251
Definition: status.h:69
void Push(int i, int s)
Definition: towers.c:146