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>
35 #include <string>
36 #include <vector>
37 
51 
52 #include <google/protobuf/port_def.inc>
53 
54 namespace google {
55 namespace protobuf {
56 namespace util {
57 namespace converter {
58 
59 class ObjectLocationTracker;
60 
61 // An ObjectWriter that can write protobuf bytes directly from writer events.
62 // This class does not support special types like Struct or Map. However, since
63 // this class supports raw protobuf, it can be used to provide support for
64 // special types by inheriting from it or by wrapping it.
65 //
66 // It also supports streaming.
67 class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
68  public:
69 // Constructor. Does not take ownership of any parameter passed in.
71  strings::ByteSink* output, ErrorListener* listener);
72  ~ProtoWriter() override;
73 
74  // ObjectWriter methods.
75  ProtoWriter* StartObject(StringPiece name) override;
76  ProtoWriter* EndObject() override;
77  ProtoWriter* StartList(StringPiece name) override;
78  ProtoWriter* EndList() override;
80  return RenderDataPiece(name, DataPiece(value));
81  }
83  return RenderDataPiece(name, DataPiece(value));
84  }
86  return RenderDataPiece(name, DataPiece(value));
87  }
89  return RenderDataPiece(name, DataPiece(value));
90  }
92  return RenderDataPiece(name, DataPiece(value));
93  }
95  return RenderDataPiece(name, DataPiece(value));
96  }
98  return RenderDataPiece(name, DataPiece(value));
99  }
101  StringPiece value) override {
102  return RenderDataPiece(name,
103  DataPiece(value, use_strict_base64_decoding()));
104  }
106  return RenderDataPiece(
107  name, DataPiece(value, false, use_strict_base64_decoding()));
108  }
110  return RenderDataPiece(name, DataPiece::NullData());
111  }
112 
113 
114  // Renders a DataPiece 'value' into a field whose wire type is determined
115  // from the given field 'name'.
116  virtual ProtoWriter* RenderDataPiece(StringPiece name,
117  const DataPiece& value);
118 
119  // Returns the location tracker to use for tracking locations for errors.
121  return element_ != nullptr ? *element_ : *tracker_;
122  }
123 
124  // When true, we finished writing to output a complete message.
125  bool done() override { return done_; }
126 
127  // Returns the proto stream object.
128  io::CodedOutputStream* stream() { return stream_.get(); }
129 
130  // Getters and mutators of invalid_depth_.
131  void IncrementInvalidDepth() { ++invalid_depth_; }
132  void DecrementInvalidDepth() { --invalid_depth_; }
133  int invalid_depth() { return invalid_depth_; }
134 
135  ErrorListener* listener() { return listener_; }
136 
137  const TypeInfo* typeinfo() { return typeinfo_; }
138 
139  void set_ignore_unknown_fields(bool ignore_unknown_fields) {
140  ignore_unknown_fields_ = ignore_unknown_fields;
141  }
142 
143  bool ignore_unknown_fields() { return ignore_unknown_fields_; }
144 
145  void set_ignore_unknown_enum_values(bool ignore_unknown_enum_values) {
146  ignore_unknown_enum_values_ = ignore_unknown_enum_values;
147  }
148 
149  void set_use_lower_camel_for_enums(bool use_lower_camel_for_enums) {
150  use_lower_camel_for_enums_ = use_lower_camel_for_enums;
151  }
152 
153  void set_case_insensitive_enum_parsing(bool case_insensitive_enum_parsing) {
154  case_insensitive_enum_parsing_ = case_insensitive_enum_parsing;
155  }
156 
157  protected:
158  class PROTOBUF_EXPORT ProtoElement : public BaseElement,
159  public LocationTrackerInterface {
160  public:
161  // Constructor for the root element. No parent nor field.
162  ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type,
163  ProtoWriter* enclosing);
164 
165  // Constructor for a field of an element.
167  const google::protobuf::Type& type, bool is_list);
168 
169  ~ProtoElement() override {}
170 
171  // Called just before the destructor for clean up:
172  // - reports any missing required fields
173  // - computes the space needed by the size field, and augment the
174  // length of all parent messages by this additional space.
175  // - releases and returns the parent pointer.
176  ProtoElement* pop();
177 
178  // Accessors
179  // parent_field() may be nullptr if we are at root.
181  return parent_field_;
182  }
183  const google::protobuf::Type& type() const { return type_; }
184 
185  // Registers field for accounting required fields.
186  void RegisterField(const google::protobuf::Field* field);
187 
188  // To report location on error messages.
189  std::string ToString() const override;
190 
191  ProtoElement* parent() const override {
192  return static_cast<ProtoElement*>(BaseElement::parent());
193  }
194 
195  // Returns true if the index is already taken by a preceding oneof input.
196  bool IsOneofIndexTaken(int32 index);
197 
198  // Marks the oneof 'index' as taken. Future inputs to this oneof will
199  // generate an error.
200  void TakeOneofIndex(int32 index);
201 
202  bool proto3() { return proto3_; }
203 
204  private:
205  // Used for access to variables of the enclosing instance of
206  // ProtoWriter.
208 
209  // Describes the element as a field in the parent message.
210  // parent_field_ is nullptr if and only if this element is the root element.
212 
213  // TypeInfo to lookup types.
215 
216  // Whether the type_ is proto3 or not.
217  bool proto3_;
218 
219  // Additional variables if this element is a message:
220  // (Root element is always a message).
221  // type_ : the type of this element.
222  // required_fields_ : set of required fields.
223  // size_index_ : index into ProtoWriter::size_insert_
224  // for later insertion of serialized message length.
226  std::set<const google::protobuf::Field*> required_fields_;
227  const int size_index_;
228 
229  // Tracks position in repeated fields, needed for LocationTrackerInterface.
231 
232  // Set of oneof indices already seen for the type_. Used to validate
233  // incoming messages so no more than one oneof is set.
234  std::vector<bool> oneof_indices_;
235 
237  };
238 
239  // Container for inserting 'size' information at the 'pos' position.
240  struct SizeInfo {
241  const int pos;
242  int size;
243  };
244 
245  ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type,
246  strings::ByteSink* output, ErrorListener* listener);
247 
248  ProtoElement* element() override { return element_.get(); }
249 
250  // Helper methods for calling ErrorListener. See error_listener.h.
251  void InvalidName(StringPiece unknown_name, StringPiece message);
252  void InvalidValue(StringPiece type_name, StringPiece value);
253  void MissingField(StringPiece missing_name);
254 
255  // Common code for BeginObject() and BeginList() that does invalid_depth_
256  // bookkeeping associated with name lookup.
257  const google::protobuf::Field* BeginNamed(StringPiece name,
258  bool is_list);
259 
260  // Lookup the field in the current element. Looks in the base descriptor
261  // and in any extension. This will report an error if the field cannot be
262  // found when ignore_unknown_names_ is false or if multiple matching
263  // extensions are found.
265 
266  // Lookup the field type in the type descriptor. Returns nullptr if the type
267  // is not known.
268  const google::protobuf::Type* LookupType(
270 
271  // Write serialized output to the final output ByteSink, inserting all
272  // the size information for nested messages that are missing from the
273  // intermediate Cord buffer.
274  void WriteRootMessage();
275 
276  // Helper method to write proto tags based on the given field.
277  void WriteTag(const google::protobuf::Field& field);
278 
279 
280  // Returns true if the field for type_ can be set as a oneof. If field is not
281  // a oneof type, this function does nothing and returns true.
282  // If another field for this oneof is already set, this function returns
283  // false. It also calls the appropriate error callback.
284  // unnormalized_name is used for error string.
285  bool ValidOneof(const google::protobuf::Field& field,
286  StringPiece unnormalized_name);
287 
288  // Returns true if the field is repeated.
289  bool IsRepeated(const google::protobuf::Field& field);
290 
291  // Starts an object given the field and the enclosing type.
292  ProtoWriter* StartObjectField(const google::protobuf::Field& field,
294 
295  // Starts a list given the field and the enclosing type.
296  ProtoWriter* StartListField(const google::protobuf::Field& field,
298 
299  // Renders a primitve field given the field and the enclosing type.
300  ProtoWriter* RenderPrimitiveField(const google::protobuf::Field& field,
302  const DataPiece& value);
303 
304  private:
305  // Writes an ENUM field, including tag, to the stream.
306  static util::Status WriteEnum(int field_number, const DataPiece& data,
309  bool use_lower_camel_for_enums,
310  bool case_insensitive_enum_parsing,
311  bool ignore_unknown_values);
312 
313  // Variables for describing the structure of the input tree:
314  // master_type_: descriptor for the whole protobuf message.
315  // typeinfo_ : the TypeInfo object to lookup types.
318  // Whether we own the typeinfo_ object.
320 
321  // Indicates whether we finished writing root message completely.
322  bool done_;
323 
324  // If true, don't report unknown field names to the listener.
326 
327  // If true, don't report unknown enum values to the listener.
329 
330  // If true, check if enum name in camel case or without underscore matches the
331  // field name.
333 
334  // If true, check if enum name in UPPER_CASE matches the field name.
336 
337  // Variable for internal state processing:
338  // element_ : the current element.
339  // size_insert_: sizes of nested messages.
340  // pos - position to insert the size field.
341  // size - size value to be inserted.
342  std::unique_ptr<ProtoElement> element_;
343  std::deque<SizeInfo> size_insert_;
344 
345  // Variables for output generation:
346  // output_ : pointer to an external ByteSink for final user-visible output.
347  // buffer_ : buffer holding partial message before being ready for output_.
348  // adapter_ : internal adapter between CodedOutputStream and buffer_.
349  // stream_ : wrapper for writing tags and other encodings in wire format.
350  strings::ByteSink* output_;
353  std::unique_ptr<io::CodedOutputStream> stream_;
354 
355  // Variables for error tracking and reporting:
356  // listener_ : a place to report any errors found.
357  // invalid_depth_: number of enclosing invalid nested messages.
358  // tracker_ : the root location tracker interface.
361  std::unique_ptr<LocationTrackerInterface> tracker_;
362 
364 };
365 
366 } // namespace converter
367 } // namespace util
368 } // namespace protobuf
369 } // namespace google
370 
371 #include <google/protobuf/port_undef.inc>
372 
373 #endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
google::protobuf::util::converter::ProtoWriter::ignore_unknown_fields_
bool ignore_unknown_fields_
Definition: proto_writer.h:325
google::protobuf::util::converter::ProtoWriter::listener
ErrorListener * listener()
Definition: proto_writer.h:135
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::util::converter::ProtoWriter::location
const LocationTrackerInterface & location()
Definition: proto_writer.h:120
google::protobuf::util::converter::ProtoWriter::element
ProtoElement * element() override
Definition: proto_writer.h:248
zero_copy_stream_impl.h
google::protobuf::util::converter::ProtoWriter::ProtoElement
Definition: proto_writer.h:158
google::protobuf::Enum
stream
GLuint GLuint stream
Definition: glcorearb.h:3946
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
google::protobuf::util::converter::ProtoWriter::ProtoElement::proto3
bool proto3()
Definition: proto_writer.h:202
google::protobuf::util::converter::ProtoWriter::RenderBool
ProtoWriter * RenderBool(StringPiece name, bool value) override
Definition: proto_writer.h:79
google::protobuf::util::converter::ProtoWriter::done_
bool done_
Definition: proto_writer.h:322
google::protobuf::util::converter::ProtoWriter::RenderInt64
ProtoWriter * RenderInt64(StringPiece name, int64 value) override
Definition: proto_writer.h:88
google::protobuf::util::converter::ProtoWriter::use_lower_camel_for_enums_
bool use_lower_camel_for_enums_
Definition: proto_writer.h:332
google::protobuf::util::converter::ProtoWriter::ProtoElement::~ProtoElement
~ProtoElement() override
Definition: proto_writer.h:169
error_listener.h
google::protobuf::util::converter::ProtoWriter::RenderFloat
ProtoWriter * RenderFloat(StringPiece name, float value) override
Definition: proto_writer.h:97
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
google::protobuf::util::converter::ProtoWriter::RenderInt32
ProtoWriter * RenderInt32(StringPiece name, int32 value) override
Definition: proto_writer.h:82
google::protobuf::util::converter::ProtoWriter::SizeInfo::size
int size
Definition: proto_writer.h:242
google::protobuf::util::converter::ProtoWriter::set_ignore_unknown_fields
void set_ignore_unknown_fields(bool ignore_unknown_fields)
Definition: proto_writer.h:139
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
enum_type
zend_class_entry * enum_type
Definition: php/ext/google/protobuf/message.c:1904
google::protobuf::util::converter::ProtoWriter::size_insert_
std::deque< SizeInfo > size_insert_
Definition: proto_writer.h:343
type_resolver.h
google::protobuf::util::converter::DataPiece::NullData
static DataPiece NullData()
Definition: datapiece.h:111
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS
#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: macros.h:45
google::protobuf::util::converter::ProtoWriter::set_use_lower_camel_for_enums
void set_use_lower_camel_for_enums(bool use_lower_camel_for_enums)
Definition: proto_writer.h:149
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
google::protobuf::util::converter::ProtoWriter::ignore_unknown_fields
bool ignore_unknown_fields()
Definition: proto_writer.h:143
google::protobuf::util::converter::ProtoWriter::RenderString
ProtoWriter * RenderString(StringPiece name, StringPiece value) override
Definition: proto_writer.h:100
google::protobuf::util::converter::ProtoWriter::SizeInfo::pos
const int pos
Definition: proto_writer.h:241
google::protobuf::util::converter::ProtoWriter::set_case_insensitive_enum_parsing
void set_case_insensitive_enum_parsing(bool case_insensitive_enum_parsing)
Definition: proto_writer.h:153
google::protobuf::util::converter::ProtoWriter::set_ignore_unknown_enum_values
void set_ignore_unknown_enum_values(bool ignore_unknown_enum_values)
Definition: proto_writer.h:145
google::protobuf::util::converter::ProtoWriter::RenderUint64
ProtoWriter * RenderUint64(StringPiece name, uint64 value) override
Definition: proto_writer.h:91
google::protobuf::util::TypeResolver
Definition: type_resolver.h:52
coded_stream.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::array_index_
int array_index_
Definition: proto_writer.h:230
google::protobuf::StringPiece
Definition: stringpiece.h:180
google::protobuf::util::converter::ProtoWriter::ProtoElement::required_fields_
std::set< const google::protobuf::Field * > required_fields_
Definition: proto_writer.h:226
google::protobuf::util::converter::ProtoWriter::DecrementInvalidDepth
void DecrementInvalidDepth()
Definition: proto_writer.h:132
google::protobuf::util::converter::ProtoWriter::RenderUint32
ProtoWriter * RenderUint32(StringPiece name, uint32 value) override
Definition: proto_writer.h:85
google::protobuf::util::converter::ProtoWriter::ProtoElement::oneof_indices_
std::vector< bool > oneof_indices_
Definition: proto_writer.h:234
google::protobuf::util::converter::ProtoWriter::ProtoElement::type_
const google::protobuf::Type & type_
Definition: proto_writer.h:225
google::protobuf::util::converter::TypeInfo
Definition: type_info.h:49
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
google::protobuf::util::converter::ProtoWriter::IncrementInvalidDepth
void IncrementInvalidDepth()
Definition: proto_writer.h:131
google::protobuf::util::converter::ProtoWriter::tracker_
std::unique_ptr< LocationTrackerInterface > tracker_
Definition: proto_writer.h:361
google::protobuf::util::converter::ProtoWriter::ProtoElement::typeinfo_
const TypeInfo * typeinfo_
Definition: proto_writer.h:214
google::protobuf::util::converter::StructuredObjectWriter
Definition: structured_objectwriter.h:58
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent_field_
const google::protobuf::Field * parent_field_
Definition: proto_writer.h:211
type_info.h
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::util::converter::ProtoWriter::invalid_depth
int invalid_depth()
Definition: proto_writer.h:133
google::protobuf::util::converter::LocationTrackerInterface
Definition: location_tracker.h:47
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent_field
const google::protobuf::Field * parent_field() const
Definition: proto_writer.h:180
google::protobuf::util::converter::ProtoWriter::RenderDouble
ProtoWriter * RenderDouble(StringPiece name, double value) override
Definition: proto_writer.h:94
google::protobuf::util::converter::ProtoWriter
Definition: proto_writer.h:67
google::protobuf::util::converter::ProtoWriter::case_insensitive_enum_parsing_
bool case_insensitive_enum_parsing_
Definition: proto_writer.h:335
google::protobuf::util::converter::ProtoWriter::invalid_depth_
int invalid_depth_
Definition: proto_writer.h:360
structured_objectwriter.h
google::protobuf::io::CodedOutputStream
Definition: coded_stream.h:693
datapiece.h
google::protobuf::util::converter::StructuredObjectWriter::BaseElement
Definition: structured_objectwriter.h:68
Field
struct Field Field
Definition: php/ext/google/protobuf/protobuf.h:638
type
GLenum type
Definition: glcorearb.h:2695
google::protobuf::util::converter::ProtoWriter::ProtoElement::ow_
ProtoWriter * ow_
Definition: proto_writer.h:207
google::protobuf::util::converter::ProtoWriter::stream_
std::unique_ptr< io::CodedOutputStream > stream_
Definition: proto_writer.h:353
google::protobuf::io::StringOutputStream
Definition: zero_copy_stream_impl_lite.h:131
google::protobuf::util::converter::ProtoWriter::typeinfo
const TypeInfo * typeinfo()
Definition: proto_writer.h:137
google::protobuf::util::converter::ProtoWriter::stream
io::CodedOutputStream * stream()
Definition: proto_writer.h:128
google::protobuf::util::converter::ProtoWriter::ProtoElement::type
const google::protobuf::Type & type() const
Definition: proto_writer.h:183
google::protobuf::util::converter::ProtoWriter::output_
strings::ByteSink * output_
Definition: proto_writer.h:350
google::protobuf::util::converter::ProtoWriter::SizeInfo
Definition: proto_writer.h:240
common.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::size_index_
const int size_index_
Definition: proto_writer.h:227
pop
static upb_refcounted * pop(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5904
descriptor.h
google::protobuf::util::converter::ProtoWriter::ignore_unknown_enum_values_
bool ignore_unknown_enum_values_
Definition: proto_writer.h:328
google::protobuf::util::Status
Definition: status.h:67
type_resolver
TypeResolver * type_resolver
Definition: conformance_cpp.cc:97
hash.h
google::protobuf::util::converter::ProtoWriter::element_
std::unique_ptr< ProtoElement > element_
Definition: proto_writer.h:342
type.pb.h
google::protobuf::util::converter::ProtoWriter::buffer_
std::string buffer_
Definition: proto_writer.h:351
Type
struct Type Type
Definition: php/ext/google/protobuf/protobuf.h:664
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent
ProtoElement * parent() const override
Definition: proto_writer.h:191
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
google::protobuf::util::converter::ProtoWriter::RenderNull
ProtoWriter * RenderNull(StringPiece name) override
Definition: proto_writer.h:109
google::protobuf::util::converter::ProtoWriter::done
bool done() override
Definition: proto_writer.h:125
google::protobuf::util::converter::ProtoWriter::typeinfo_
const TypeInfo * typeinfo_
Definition: proto_writer.h:317
google::protobuf::util::converter::ProtoWriter::listener_
ErrorListener * listener_
Definition: proto_writer.h:359
google::protobuf::util::converter::ProtoWriter::adapter_
io::StringOutputStream adapter_
Definition: proto_writer.h:352
google::protobuf::util::converter::ProtoWriter::own_typeinfo_
bool own_typeinfo_
Definition: proto_writer.h:319
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf::util::converter::ProtoWriter::ProtoElement::proto3_
bool proto3_
Definition: proto_writer.h:217
google::protobuf::util::converter::ProtoWriter::RenderBytes
ProtoWriter * RenderBytes(StringPiece name, StringPiece value) override
Definition: proto_writer.h:105
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::util::converter::DataPiece
Definition: datapiece.h:59
google::protobuf::util::converter::ProtoWriter::master_type_
const google::protobuf::Type & master_type_
Definition: proto_writer.h:316
bytestream.h
index
GLuint index
Definition: glcorearb.h:3055
google::protobuf::util::converter::ErrorListener
Definition: error_listener.h:53
status.h
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57