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> |
35 #include <string> | 36 #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> | |
49 | 48 |
50 namespace google { | 49 namespace google { |
51 namespace protobuf { | 50 namespace protobuf { |
52 namespace io { | 51 namespace io { |
53 class CodedOutputStream; | 52 class CodedOutputStream; |
54 } // namespace io | 53 } // namespace io |
55 } // namespace protobuf | 54 } // namespace protobuf |
56 | 55 |
57 | 56 |
58 namespace protobuf { | 57 namespace protobuf { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 DataPiece(value, use_strict_base64_decoding())); | 110 DataPiece(value, use_strict_base64_decoding())); |
112 } | 111 } |
113 virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) { | 112 virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) { |
114 return RenderDataPiece( | 113 return RenderDataPiece( |
115 name, DataPiece(value, false, use_strict_base64_decoding())); | 114 name, DataPiece(value, false, use_strict_base64_decoding())); |
116 } | 115 } |
117 virtual ProtoWriter* RenderNull(StringPiece name) { | 116 virtual ProtoWriter* RenderNull(StringPiece name) { |
118 return RenderDataPiece(name, DataPiece::NullData()); | 117 return RenderDataPiece(name, DataPiece::NullData()); |
119 } | 118 } |
120 | 119 |
121 | |
122 // Renders a DataPiece 'value' into a field whose wire type is determined | 120 // Renders a DataPiece 'value' into a field whose wire type is determined |
123 // from the given field 'name'. | 121 // from the given field 'name'. |
124 virtual ProtoWriter* RenderDataPiece(StringPiece name, | 122 virtual ProtoWriter* RenderDataPiece(StringPiece name, |
125 const DataPiece& value); | 123 const DataPiece& value); |
126 | 124 |
127 // Returns the location tracker to use for tracking locations for errors. | 125 // Returns the location tracker to use for tracking locations for errors. |
128 const LocationTrackerInterface& location() { | 126 const LocationTrackerInterface& location() { |
129 return element_ != NULL ? *element_ : *tracker_; | 127 return element_ != NULL ? *element_ : *tracker_; |
130 } | 128 } |
131 | 129 |
132 // When true, we finished writing to output a complete message. | 130 // When true, we finished writing to output a complete message. |
133 bool done() { return done_; } | 131 bool done() { return done_; } |
134 | 132 |
135 // Returns the proto stream object. | 133 // Returns the proto stream object. |
136 google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); } | 134 google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); } |
137 | 135 |
138 // Getters and mutators of invalid_depth_. | 136 // Getters and mutators of invalid_depth_. |
139 void IncrementInvalidDepth() { ++invalid_depth_; } | 137 void IncrementInvalidDepth() { ++invalid_depth_; } |
140 void DecrementInvalidDepth() { --invalid_depth_; } | 138 void DecrementInvalidDepth() { --invalid_depth_; } |
141 int invalid_depth() { return invalid_depth_; } | 139 int invalid_depth() { return invalid_depth_; } |
142 | 140 |
143 ErrorListener* listener() { return listener_; } | 141 ErrorListener* listener() { return listener_; } |
144 | 142 |
145 const TypeInfo* typeinfo() { return typeinfo_; } | 143 const TypeInfo* typeinfo() { return typeinfo_; } |
146 | 144 |
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 | |
155 protected: | 145 protected: |
156 class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTra
ckerInterface { | 146 class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTra
ckerInterface { |
157 public: | 147 public: |
158 // Constructor for the root element. No parent nor field. | 148 // Constructor for the root element. No parent nor field. |
159 ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, | 149 ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, |
160 ProtoWriter* enclosing); | 150 ProtoWriter* enclosing); |
161 | 151 |
162 // Constructor for a field of an element. | 152 // Constructor for a field of an element. |
163 ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, | 153 ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, |
164 const google::protobuf::Type& type, bool is_list); | 154 const google::protobuf::Type& type, bool is_list); |
(...skipping 17 matching lines...) Expand all Loading... |
182 // Registers field for accounting required fields. | 172 // Registers field for accounting required fields. |
183 void RegisterField(const google::protobuf::Field* field); | 173 void RegisterField(const google::protobuf::Field* field); |
184 | 174 |
185 // To report location on error messages. | 175 // To report location on error messages. |
186 virtual string ToString() const; | 176 virtual string ToString() const; |
187 | 177 |
188 virtual ProtoElement* parent() const { | 178 virtual ProtoElement* parent() const { |
189 return static_cast<ProtoElement*>(BaseElement::parent()); | 179 return static_cast<ProtoElement*>(BaseElement::parent()); |
190 } | 180 } |
191 | 181 |
192 // Returns true if the index is already taken by a preceding oneof input. | 182 // Returns true if the index is already taken by a preceeding oneof input. |
193 bool IsOneofIndexTaken(int32 index); | 183 bool IsOneofIndexTaken(int32 index); |
194 | 184 |
195 // Marks the oneof 'index' as taken. Future inputs to this oneof will | 185 // Marks the oneof 'index' as taken. Future inputs to this oneof will |
196 // generate an error. | 186 // generate an error. |
197 void TakeOneofIndex(int32 index); | 187 void TakeOneofIndex(int32 index); |
198 | 188 |
199 bool proto3() { return proto3_; } | |
200 | |
201 private: | 189 private: |
202 // Used for access to variables of the enclosing instance of | 190 // Used for access to variables of the enclosing instance of |
203 // ProtoWriter. | 191 // ProtoWriter. |
204 ProtoWriter* ow_; | 192 ProtoWriter* ow_; |
205 | 193 |
206 // Describes the element as a field in the parent message. | 194 // Describes the element as a field in the parent message. |
207 // parent_field_ is NULL if and only if this element is the root element. | 195 // parent_field_ is NULL if and only if this element is the root element. |
208 const google::protobuf::Field* parent_field_; | 196 const google::protobuf::Field* parent_field_; |
209 | 197 |
210 // TypeInfo to lookup types. | 198 // TypeInfo to lookup types. |
211 const TypeInfo* typeinfo_; | 199 const TypeInfo* typeinfo_; |
212 | 200 |
213 // Whether the type_ is proto3 or not. | |
214 bool proto3_; | |
215 | |
216 // Additional variables if this element is a message: | 201 // Additional variables if this element is a message: |
217 // (Root element is always a message). | 202 // (Root element is always a message). |
218 // type_ : the type of this element. | 203 // type_ : the type of this element. |
219 // required_fields_ : set of required fields. | 204 // required_fields_ : set of required fields. |
220 // size_index_ : index into ProtoWriter::size_insert_ | 205 // size_index_ : index into ProtoWriter::size_insert_ |
221 // for later insertion of serialized message length. | 206 // for later insertion of serialized message length. |
222 const google::protobuf::Type& type_; | 207 const google::protobuf::Type& type_; |
223 std::set<const google::protobuf::Field*> required_fields_; | 208 std::set<const google::protobuf::Field*> required_fields_; |
224 const int size_index_; | 209 const int size_index_; |
225 | 210 |
226 // Tracks position in repeated fields, needed for LocationTrackerInterface. | 211 // Tracks position in repeated fields, needed for LocationTrackerInterface. |
227 int array_index_; | 212 int array_index_; |
228 | 213 |
229 // Set of oneof indices already seen for the type_. Used to validate | 214 // Set of oneof indices already seen for the type_. Used to validate |
230 // incoming messages so no more than one oneof is set. | 215 // incoming messages so no more than one oneof is set. |
231 std::vector<bool> oneof_indices_; | 216 hash_set<int32> oneof_indices_; |
232 | 217 |
233 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement); | 218 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement); |
234 }; | 219 }; |
235 | 220 |
236 // Container for inserting 'size' information at the 'pos' position. | 221 // Container for inserting 'size' information at the 'pos' position. |
237 struct SizeInfo { | 222 struct SizeInfo { |
238 const int pos; | 223 const int pos; |
239 int size; | 224 int size; |
240 }; | 225 }; |
241 | 226 |
242 ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, | 227 ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, |
243 strings::ByteSink* output, ErrorListener* listener); | 228 strings::ByteSink* output, ErrorListener* listener); |
244 | 229 |
245 virtual ProtoElement* element() { return element_.get(); } | 230 virtual ProtoElement* element() { return element_.get(); } |
246 | 231 |
247 // Helper methods for calling ErrorListener. See error_listener.h. | 232 // Helper methods for calling ErrorListener. See error_listener.h. |
248 void InvalidName(StringPiece unknown_name, StringPiece message); | 233 void InvalidName(StringPiece unknown_name, StringPiece message); |
249 void InvalidValue(StringPiece type_name, StringPiece value); | 234 void InvalidValue(StringPiece type_name, StringPiece value); |
250 void MissingField(StringPiece missing_name); | 235 void MissingField(StringPiece missing_name); |
251 | 236 |
252 // Common code for BeginObject() and BeginList() that does invalid_depth_ | 237 // Common code for BeginObject() and BeginList() that does invalid_depth_ |
253 // bookkeeping associated with name lookup. | 238 // bookkeeping associated with name lookup. |
254 const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list); | 239 const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list); |
255 | 240 |
256 // Lookup the field in the current element. Looks in the base descriptor | 241 // Lookup the field in the current element. Looks in the base descriptor |
257 // and in any extension. This will report an error if the field cannot be | 242 // and in any extension. This will report an error if the field cannot be |
258 // found when ignore_unknown_names_ is false or if multiple matching | 243 // found or if multiple matching extensions are found. |
259 // extensions are found. | |
260 const google::protobuf::Field* Lookup(StringPiece name); | 244 const google::protobuf::Field* Lookup(StringPiece name); |
261 | 245 |
262 // Lookup the field type in the type descriptor. Returns NULL if the type | 246 // Lookup the field type in the type descriptor. Returns NULL if the type |
263 // is not known. | 247 // is not known. |
264 const google::protobuf::Type* LookupType( | 248 const google::protobuf::Type* LookupType( |
265 const google::protobuf::Field* field); | 249 const google::protobuf::Field* field); |
266 | 250 |
267 // Write serialized output to the final output ByteSink, inserting all | 251 // Write serialized output to the final output ByteSink, inserting all |
268 // the size information for nested messages that are missing from the | 252 // the size information for nested messages that are missing from the |
269 // intermediate Cord buffer. | 253 // intermediate Cord buffer. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 // master_type_: descriptor for the whole protobuf message. | 286 // master_type_: descriptor for the whole protobuf message. |
303 // typeinfo_ : the TypeInfo object to lookup types. | 287 // typeinfo_ : the TypeInfo object to lookup types. |
304 const google::protobuf::Type& master_type_; | 288 const google::protobuf::Type& master_type_; |
305 const TypeInfo* typeinfo_; | 289 const TypeInfo* typeinfo_; |
306 // Whether we own the typeinfo_ object. | 290 // Whether we own the typeinfo_ object. |
307 bool own_typeinfo_; | 291 bool own_typeinfo_; |
308 | 292 |
309 // Indicates whether we finished writing root message completely. | 293 // Indicates whether we finished writing root message completely. |
310 bool done_; | 294 bool done_; |
311 | 295 |
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 | |
319 // Variable for internal state processing: | 296 // Variable for internal state processing: |
320 // element_ : the current element. | 297 // element_ : the current element. |
321 // size_insert_: sizes of nested messages. | 298 // size_insert_: sizes of nested messages. |
322 // pos - position to insert the size field. | 299 // pos - position to insert the size field. |
323 // size - size value to be inserted. | 300 // size - size value to be inserted. |
324 google::protobuf::scoped_ptr<ProtoElement> element_; | 301 google::protobuf::scoped_ptr<ProtoElement> element_; |
325 std::deque<SizeInfo> size_insert_; | 302 std::deque<SizeInfo> size_insert_; |
326 | 303 |
327 // Variables for output generation: | 304 // Variables for output generation: |
328 // output_ : pointer to an external ByteSink for final user-visible output. | 305 // output_ : pointer to an external ByteSink for final user-visible output. |
(...skipping 15 matching lines...) Expand all Loading... |
344 | 321 |
345 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); | 322 GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); |
346 }; | 323 }; |
347 | 324 |
348 } // namespace converter | 325 } // namespace converter |
349 } // namespace util | 326 } // namespace util |
350 } // namespace protobuf | 327 } // namespace protobuf |
351 | 328 |
352 } // namespace google | 329 } // namespace google |
353 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ | 330 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__ |
OLD | NEW |