31 #include <google/protobuf/util/internal/proto_writer.h>
37 #include <google/protobuf/stubs/once.h>
38 #include <google/protobuf/wire_format_lite.h>
39 #include <google/protobuf/util/internal/field_mask_utility.h>
40 #include <google/protobuf/util/internal/object_location_tracker.h>
41 #include <google/protobuf/util/internal/constants.h>
42 #include <google/protobuf/util/internal/utility.h>
43 #include <google/protobuf/stubs/strutil.h>
44 #include <google/protobuf/stubs/statusor.h>
45 #include <google/protobuf/stubs/time.h>
46 #include <google/protobuf/stubs/map_util.h>
49 #include <google/protobuf/port_def.inc>
57 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
61 strings::ByteSink*
output, ErrorListener* listener)
66 ignore_unknown_fields_(
false),
67 ignore_unknown_enum_values_(
false),
68 use_lower_camel_for_enums_(
false),
69 case_insensitive_enum_parsing_(
true),
70 use_json_name_in_missing_fields_(
false),
79 tracker_(
new ObjectLocationTracker()) {}
83 strings::ByteSink*
output, ErrorListener* listener)
88 ignore_unknown_fields_(
false),
89 ignore_unknown_enum_values_(
false),
90 use_lower_camel_for_enums_(
false),
91 case_insensitive_enum_parsing_(
true),
92 use_json_name_in_missing_fields_(
false),
101 tracker_(
new ObjectLocationTracker()) {}
112 std::unique_ptr<BaseElement>
element(
113 static_cast<BaseElement*
>(
element_.get())->pop<BaseElement>());
124 util::StatusOr<int32_t> i32 =
data.ToInt32();
134 util::StatusOr<int32_t> i32 =
data.ToInt32();
144 util::StatusOr<int32_t> i32 =
data.ToInt32();
154 util::StatusOr<uint32_t> u32 =
data.ToUint32();
164 util::StatusOr<uint32_t> u32 =
data.ToUint32();
174 util::StatusOr<int64_t> i64 =
data.ToInt64();
184 util::StatusOr<int64_t> i64 =
data.ToInt64();
194 util::StatusOr<int64_t> i64 =
data.ToInt64();
204 util::StatusOr<uint64_t> u64 =
data.ToUint64();
214 util::StatusOr<uint64_t> u64 =
data.ToUint64();
224 util::StatusOr<double>
d =
data.ToDouble();
234 util::StatusOr<float>
f =
data.ToFloat();
244 util::StatusOr<bool>
b =
data.ToBool();
254 util::StatusOr<std::string>
c =
data.ToBytes();
264 util::StatusOr<std::string>
s =
data.ToString();
272 std::set<const google::protobuf::Field*> GetRequiredFields(
274 std::set<const google::protobuf::Field*>
required;
275 for (
int i = 0;
i <
type.fields_size();
i++) {
277 if (
field.cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) {
288 ProtoWriter* enclosing)
289 : BaseElement(nullptr),
291 parent_field_(nullptr),
298 oneof_indices_(
type.oneofs_size() + 1) {
300 required_fields_ = GetRequiredFields(
type_);
308 : BaseElement(parent),
309 ow_(this->parent()->ow_),
310 parent_field_(
field),
311 typeinfo_(this->parent()->typeinfo_),
314 size_index_(!is_list &&
316 ? ow_->size_insert_.
size()
318 array_index_(is_list ? 0 : -1),
320 oneof_indices_(
type_.oneofs_size() + 1) {
322 if (ow_->IsRepeated(*
field)) {
324 if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
325 }
else if (!proto3_) {
327 this->parent()->RegisterField(
field);
330 if (
field->kind() == google::protobuf::Field::TYPE_MESSAGE) {
332 required_fields_ = GetRequiredFields(
type_);
334 int start_pos = ow_->stream_->ByteCount();
339 SizeInfo info = {start_pos, -start_pos};
340 ow_->size_insert_.push_back(info);
373 if (
e->size_index_ >= 0) {
378 return BaseElement::pop<ProtoElement>();
383 if (!required_fields_.empty() &&
384 field->cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) {
385 required_fields_.erase(
field);
394 const ProtoWriter::ProtoElement*
now =
this;
395 std::stack<const ProtoWriter::ProtoElement*> element_stack;
396 while (
now->parent() !=
nullptr) {
397 element_stack.push(
now);
402 while (!element_stack.empty()) {
403 now = element_stack.top();
406 if (!ow_->IsRepeated(*(
now->parent_field_)) ||
407 now->parent()->parent_field_ !=
now->parent_field_) {
410 while (i <
name.size() &&
413 if (i > 0 && i ==
name.size()) {
424 int array_index_now =
now->array_index_;
425 if (ow_->IsRepeated(*(
now->parent_field_)) && array_index_now > 0) {
434 return oneof_indices_[
index];
438 oneof_indices_[
index] =
true;
468 if (
field ==
nullptr)
return this;
478 if (
type ==
nullptr) {
513 if (
field ==
nullptr)
return this;
521 if (
type ==
nullptr) {
542 StringPiece
name,
const DataPiece&
data) {
548 if (
field ==
nullptr)
return this;
553 if (
type ==
nullptr) {
563 StringPiece unnormalized_name) {
564 if (
element_ ==
nullptr)
return true;
566 if (
field.oneof_index() > 0) {
571 "oneof field '",
element_->type().oneofs(
field.oneof_index() - 1),
572 "' is already set. Cannot set '", unnormalized_name,
"'"));
581 return field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED;
600 bool use_lower_camel_for_enums,
601 bool case_insensitive_enum_parsing,
602 bool ignore_unknown_values) {
603 bool is_unknown_enum_value =
false;
604 util::StatusOr<int>
e =
data.ToEnum(
605 enum_type, use_lower_camel_for_enums, case_insensitive_enum_parsing,
606 ignore_unknown_values, &is_unknown_enum_value);
607 if (
e.ok() && !is_unknown_enum_value) {
615 const DataPiece&
data) {
627 switch (
field.kind()) {
628 case google::protobuf::Field::TYPE_INT32: {
632 case google::protobuf::Field::TYPE_SFIXED32: {
636 case google::protobuf::Field::TYPE_SINT32: {
640 case google::protobuf::Field::TYPE_FIXED32: {
644 case google::protobuf::Field::TYPE_UINT32: {
648 case google::protobuf::Field::TYPE_INT64: {
652 case google::protobuf::Field::TYPE_SFIXED64: {
656 case google::protobuf::Field::TYPE_SINT64: {
660 case google::protobuf::Field::TYPE_FIXED64: {
664 case google::protobuf::Field::TYPE_UINT64: {
668 case google::protobuf::Field::TYPE_DOUBLE: {
672 case google::protobuf::Field::TYPE_FLOAT: {
676 case google::protobuf::Field::TYPE_BOOL: {
680 case google::protobuf::Field::TYPE_BYTES: {
684 case google::protobuf::Field::TYPE_STRING: {
688 case google::protobuf::Field::TYPE_ENUM: {
724 if (
field ==
nullptr) {
738 StringPiece unnormalized_name) {
741 InvalidName(unnormalized_name,
"Root element must be a message.");
744 if (unnormalized_name.empty()) {
746 if (
e->parent_field() ==
nullptr) {
747 InvalidName(unnormalized_name,
"Proto fields must have a name.");
749 InvalidName(unnormalized_name,
"Proto fields must have a name.");
752 return e->parent_field();
757 InvalidName(unnormalized_name,
"Cannot find field.");
764 return ((
field->kind() == google::protobuf::Field::TYPE_MESSAGE ||
765 field->kind() == google::protobuf::Field::TYPE_GROUP)
778 io::ArrayInputStream input_stream(
buffer_.data(),
buffer_.size());
780 if (
length == 0)
continue;
793 input_stream.BackUp(
length - num_bytes);
795 curr_pos += num_bytes;
805 output_->
Append(
reinterpret_cast<const char*
>(insert_buffer),
806 insert_buffer_pos - insert_buffer);