OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 14 matching lines...) Expand all Loading... |
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | 30 |
31 #ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ | 31 #ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ |
32 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ | 32 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ |
33 | 33 |
34 #include <deque> | 34 #include <deque> |
35 #include <google/protobuf/stubs/hash.h> | |
36 #include <string> | 35 #include <string> |
| 36 #include <vector> |
37 | 37 |
38 #include <google/protobuf/stubs/common.h> | 38 #include <google/protobuf/stubs/common.h> |
39 #include <google/protobuf/io/coded_stream.h> | 39 #include <google/protobuf/io/coded_stream.h> |
40 #include <google/protobuf/io/zero_copy_stream_impl.h> | 40 #include <google/protobuf/io/zero_copy_stream_impl.h> |
41 #include <google/protobuf/descriptor.h> | 41 #include <google/protobuf/descriptor.h> |
42 #include <google/protobuf/util/internal/type_info.h> | 42 #include <google/protobuf/util/internal/type_info.h> |
43 #include <google/protobuf/util/internal/datapiece.h> | 43 #include <google/protobuf/util/internal/datapiece.h> |
44 #include <google/protobuf/util/internal/error_listener.h> | 44 #include <google/protobuf/util/internal/error_listener.h> |
45 #include <google/protobuf/util/internal/structured_objectwriter.h> | 45 #include <google/protobuf/util/internal/structured_objectwriter.h> |
46 #include <google/protobuf/util/type_resolver.h> | 46 #include <google/protobuf/util/type_resolver.h> |
47 #include <google/protobuf/stubs/bytestream.h> | 47 #include <google/protobuf/stubs/bytestream.h> |
| 48 #include <google/protobuf/stubs/hash.h> |
48 | 49 |
49 namespace google { | 50 namespace google { |
50 namespace protobuf { | 51 namespace protobuf { |
51 namespace io { | 52 namespace io { |
52 class CodedOutputStream; | 53 class CodedOutputStream; |
53 } // namespace io | 54 } // namespace io |
54 } // namespace protobuf | 55 } // namespace protobuf |
55 | 56 |
56 | 57 |
57 namespace protobuf { | 58 namespace protobuf { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 DataPiece(value, use_strict_base64_decoding())); | 111 DataPiece(value, use_strict_base64_decoding())); |
111 } | 112 } |
112 virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) { | 113 virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) { |
113 return RenderDataPiece( | 114 return RenderDataPiece( |
114 name, DataPiece(value, false, use_strict_base64_decoding())); | 115 name, DataPiece(value, false, use_strict_base64_decoding())); |
115 } | 116 } |
116 virtual ProtoWriter* RenderNull(StringPiece name) { | 117 virtual ProtoWriter* RenderNull(StringPiece name) { |
117 return RenderDataPiece(name, DataPiece::NullData()); | 118 return RenderDataPiece(name, DataPiece::NullData()); |
118 } | 119 } |
119 | 120 |
| 121 |
120 // Renders a DataPiece 'value' into a field whose wire type is determined | 122 // Renders a DataPiece 'value' into a field whose wire type is determined |
121 // from the given field 'name'. | 123 // from the given field 'name'. |
122 virtual ProtoWriter* RenderDataPiece(StringPiece name, | 124 virtual ProtoWriter* RenderDataPiece(StringPiece name, |
123 const DataPiece& value); | 125 const DataPiece& value); |
124 | 126 |
125 // Returns the location tracker to use for tracking locations for errors. | 127 // Returns the location tracker to use for tracking locations for errors. |
126 const LocationTrackerInterface& location() { | 128 const LocationTrackerInterface& location() { |
127 return element_ != NULL ? *element_ : *tracker_; | 129 return element_ != NULL ? *element_ : *tracker_; |
128 } | 130 } |
129 | 131 |
130 // When true, we finished writing to output a complete message. | 132 // When true, we finished writing to output a complete message. |
131 bool done() { return done_; } | 133 bool done() { return done_; } |
132 | 134 |
133 // Returns the proto stream object. | 135 // Returns the proto stream object. |
134 google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); } | 136 google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); } |
135 | 137 |
136 // Getters and mutators of invalid_depth_. | 138 // Getters and mutators of invalid_depth_. |
137 void IncrementInvalidDepth() { ++invalid_depth_; } | 139 void IncrementInvalidDepth() { ++invalid_depth_; } |
138 void DecrementInvalidDepth() { --invalid_depth_; } | 140 void DecrementInvalidDepth() { --invalid_depth_; } |
139 int invalid_depth() { return invalid_depth_; } | 141 int invalid_depth() { return invalid_depth_; } |
140 | 142 |
141 ErrorListener* listener() { return listener_; } | 143 ErrorListener* listener() { return listener_; } |
142 | 144 |
143 const TypeInfo* typeinfo() { return typeinfo_; } | 145 const TypeInfo* typeinfo() { return typeinfo_; } |
144 | 146 |
| 147 void set_ignore_unknown_fields(bool ignore_unknown_fields) { |
| 148 ignore_unknown_fields_ = ignore_unknown_fields; |
| 149 } |
| 150 |
| 151 void set_use_lower_camel_for_enums(bool use_lower_camel_for_enums) { |
| 152 use_lower_camel_for_enums_ = use_lower_camel_for_enums; |
| 153 } |
| 154 |
145 protected: | 155 protected: |
146 class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTra
ckerInterface { | 156 class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTra
ckerInterface { |
147 public: | 157 public: |
148 // Constructor for the root element. No parent nor field. | 158 // Constructor for the root element. No parent nor field. |
149 ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, | 159 ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, |
150 ProtoWriter* enclosing); | 160 ProtoWriter* enclosing); |
151 | 161 |
152 // Constructor for a field of an element. | 162 // Constructor for a field of an element. |
153 ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, | 163 ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, |
154 const google::protobuf::Type& type, bool is_list); | 164 const google::protobuf::Type& type, bool is_list); |
(...skipping 17 matching lines...) Expand all Loading... |
172 // Registers field for accounting required fields. | 182 // Registers field for accounting required fields. |
173 void RegisterField(const google::protobuf::Field* field); | 183 void RegisterField(const google::protobuf::Field* field); |
174 | 184 |
175 // To report location on error messages. | 185 // To report location on error messages. |
176 virtual string ToString() const; | 186 virtual string ToString() const; |
177 | 187 |
178 virtual ProtoElement* parent() const { | 188 virtual ProtoElement* parent() const { |
179 return static_cast<ProtoElement*>(BaseElement::parent()); | 189 return static_cast<ProtoElement*>(BaseElement::parent()); |
180 } | 190 } |
181 | 191 |
182 // Returns true if the index is already taken by a preceeding oneof input. | 192 // Returns true if the index is already taken by a preceding oneof input. |
183 bool IsOneofIndexTaken(int32 index); | 193 bool IsOneofIndexTaken(int32 index); |
184 | 194 |
185 // Marks the oneof 'index' as taken. Future inputs to this oneof will | 195 // Marks the oneof 'index' as taken. Future inputs to this oneof will |
186 // generate an error. | 196 // generate an error. |
187 void TakeOneofIndex(int32 index); | 197 void TakeOneofIndex(int32 index); |
188 | 198 |
| 199 bool proto3() { return proto3_; } |
| 200 |
189 private: | 201 private: |
190 // Used for access to variables of the enclosing instance of | 202 // Used for access to variables of the enclosing instance of |
191 // ProtoWriter. | 203 // ProtoWriter. |
192 ProtoWriter* ow_; | 204 ProtoWriter* ow_; |
193 | 205 |
194 // Describes the element as a field in the parent message. | 206 // 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. | 207 // parent_field_ is NULL if and only if this element is the root element. |
196 const google::protobuf::Field* parent_field_; | 208 const google::protobuf::Field* parent_field_; |
197 | 209 |
198 // TypeInfo to lookup types. | 210 // TypeInfo to lookup types. |
199 const TypeInfo* typeinfo_; | 211 const TypeInfo* typeinfo_; |
200 | 212 |
| 213 // Whether the type_ is proto3 or not. |
| 214 bool proto3_; |
| 215 |
201 // Additional variables if this element is a message: | 216 // Additional variables if this element is a message: |
202 // (Root element is always a message). | 217 // (Root element is always a message). |
203 // type_ : the type of this element. | 218 // type_ : the type of this element. |
204 // required_fields_ : set of required fields. | 219 // required_fields_ : set of required fields. |
205 // size_index_ : index into ProtoWriter::size_insert_ | 220 // size_index_ : index into ProtoWriter::size_insert_ |
206 // for later insertion of serialized message length. | 221 // for later insertion of serialized message length. |
207 const google::protobuf::Type& type_; | 222 const google::protobuf::Type& type_; |
208 std::set<const google::protobuf::Field*> required_fields_; | 223 std::set<const google::protobuf::Field*> required_fields_; |
209 const int size_index_; | 224 const int size_index_; |
210 | 225 |
211 // Tracks position in repeated fields, needed for LocationTrackerInterface. | 226 // Tracks position in repeated fields, needed for LocationTrackerInterface. |
212 int array_index_; | 227 int array_index_; |
213 | 228 |
214 // Set of oneof indices already seen for the type_. Used to validate | 229 // Set of oneof indices already seen for the type_. Used to validate |
215 // incoming messages so no more than one oneof is set. | 230 // incoming messages so no more than one oneof is set. |
216 hash_set<int32> oneof_indices_; | 231 std::vector<bool> oneof_indices_; |
217 | 232 |
218 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement); | 233 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement); |
219 }; | 234 }; |
220 | 235 |
221 // Container for inserting 'size' information at the 'pos' position. | 236 // Container for inserting 'size' information at the 'pos' position. |
222 struct SizeInfo { | 237 struct SizeInfo { |
223 const int pos; | 238 const int pos; |
224 int size; | 239 int size; |
225 }; | 240 }; |
226 | 241 |
227 ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, | 242 ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, |
228 strings::ByteSink* output, ErrorListener* listener); | 243 strings::ByteSink* output, ErrorListener* listener); |
229 | 244 |
230 virtual ProtoElement* element() { return element_.get(); } | 245 virtual ProtoElement* element() { return element_.get(); } |
231 | 246 |
232 // Helper methods for calling ErrorListener. See error_listener.h. | 247 // Helper methods for calling ErrorListener. See error_listener.h. |
233 void InvalidName(StringPiece unknown_name, StringPiece message); | 248 void InvalidName(StringPiece unknown_name, StringPiece message); |
234 void InvalidValue(StringPiece type_name, StringPiece value); | 249 void InvalidValue(StringPiece type_name, StringPiece value); |
235 void MissingField(StringPiece missing_name); | 250 void MissingField(StringPiece missing_name); |
236 | 251 |
237 // Common code for BeginObject() and BeginList() that does invalid_depth_ | 252 // Common code for BeginObject() and BeginList() that does invalid_depth_ |
238 // bookkeeping associated with name lookup. | 253 // bookkeeping associated with name lookup. |
239 const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list); | 254 const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list); |
240 | 255 |
241 // Lookup the field in the current element. Looks in the base descriptor | 256 // 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 | 257 // and in any extension. This will report an error if the field cannot be |
243 // found or if multiple matching extensions are found. | 258 // found when ignore_unknown_names_ is false or if multiple matching |
| 259 // extensions are found. |
244 const google::protobuf::Field* Lookup(StringPiece name); | 260 const google::protobuf::Field* Lookup(StringPiece name); |
245 | 261 |
246 // Lookup the field type in the type descriptor. Returns NULL if the type | 262 // Lookup the field type in the type descriptor. Returns NULL if the type |
247 // is not known. | 263 // is not known. |
248 const google::protobuf::Type* LookupType( | 264 const google::protobuf::Type* LookupType( |
249 const google::protobuf::Field* field); | 265 const google::protobuf::Field* field); |
250 | 266 |
251 // Write serialized output to the final output ByteSink, inserting all | 267 // Write serialized output to the final output ByteSink, inserting all |
252 // the size information for nested messages that are missing from the | 268 // the size information for nested messages that are missing from the |
253 // intermediate Cord buffer. | 269 // intermediate Cord buffer. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 // master_type_: descriptor for the whole protobuf message. | 302 // master_type_: descriptor for the whole protobuf message. |
287 // typeinfo_ : the TypeInfo object to lookup types. | 303 // typeinfo_ : the TypeInfo object to lookup types. |
288 const google::protobuf::Type& master_type_; | 304 const google::protobuf::Type& master_type_; |
289 const TypeInfo* typeinfo_; | 305 const TypeInfo* typeinfo_; |
290 // Whether we own the typeinfo_ object. | 306 // Whether we own the typeinfo_ object. |
291 bool own_typeinfo_; | 307 bool own_typeinfo_; |
292 | 308 |
293 // Indicates whether we finished writing root message completely. | 309 // Indicates whether we finished writing root message completely. |
294 bool done_; | 310 bool done_; |
295 | 311 |
| 312 // If true, don't report unknown field names to the listener. |
| 313 bool ignore_unknown_fields_; |
| 314 |
| 315 // If true, check if enum name in camel case or without underscore matches the |
| 316 // field name. |
| 317 bool use_lower_camel_for_enums_; |
| 318 |
296 // Variable for internal state processing: | 319 // Variable for internal state processing: |
297 // element_ : the current element. | 320 // element_ : the current element. |
298 // size_insert_: sizes of nested messages. | 321 // size_insert_: sizes of nested messages. |
299 // pos - position to insert the size field. | 322 // pos - position to insert the size field. |
300 // size - size value to be inserted. | 323 // size - size value to be inserted. |
301 google::protobuf::scoped_ptr<ProtoElement> element_; | 324 google::protobuf::scoped_ptr<ProtoElement> element_; |
302 std::deque<SizeInfo> size_insert_; | 325 std::deque<SizeInfo> size_insert_; |
303 | 326 |
304 // Variables for output generation: | 327 // Variables for output generation: |
305 // output_ : pointer to an external ByteSink for final user-visible output. | 328 // output_ : pointer to an external ByteSink for final user-visible output. |
(...skipping 15 matching lines...) Expand all Loading... |
321 | 344 |
322 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); | 345 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); |
323 }; | 346 }; |
324 | 347 |
325 } // namespace converter | 348 } // namespace converter |
326 } // namespace util | 349 } // namespace util |
327 } // namespace protobuf | 350 } // namespace protobuf |
328 | 351 |
329 } // namespace google | 352 } // namespace google |
330 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ | 353 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ |
OLD | NEW |