31 #include <google/protobuf/util/internal/protostream_objectsource.h>
34 #include <unordered_map>
37 #include <google/protobuf/stubs/logging.h>
38 #include <google/protobuf/stubs/common.h>
39 #include <google/protobuf/stubs/stringprintf.h>
40 #include <google/protobuf/io/coded_stream.h>
41 #include <google/protobuf/io/zero_copy_stream_impl.h>
42 #include <google/protobuf/descriptor.h>
43 #include <google/protobuf/stubs/once.h>
44 #include <google/protobuf/unknown_field_set.h>
45 #include <google/protobuf/wire_format.h>
46 #include <google/protobuf/wire_format_lite.h>
47 #include <google/protobuf/util/internal/field_mask_utility.h>
48 #include <google/protobuf/util/internal/constants.h>
49 #include <google/protobuf/util/internal/utility.h>
50 #include <google/protobuf/stubs/strutil.h>
51 #include <google/protobuf/stubs/casts.h>
52 #include <google/protobuf/stubs/status.h>
53 #include <google/protobuf/stubs/time.h>
54 #include <google/protobuf/stubs/map_util.h>
55 #include <google/protobuf/stubs/status_macros.h>
58 #include <google/protobuf/port_def.inc>
65 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat;
66 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
86 util::StatusOr<std::string> MapKeyDefaultValueAsString(
88 switch (
field.kind()) {
89 case google::protobuf::Field::TYPE_BOOL:
91 case google::protobuf::Field::TYPE_INT32:
92 case google::protobuf::Field::TYPE_INT64:
93 case google::protobuf::Field::TYPE_UINT32:
94 case google::protobuf::Field::TYPE_UINT64:
95 case google::protobuf::Field::TYPE_SINT32:
96 case google::protobuf::Field::TYPE_SINT64:
97 case google::protobuf::Field::TYPE_SFIXED32:
98 case google::protobuf::Field::TYPE_SFIXED64:
99 case google::protobuf::Field::TYPE_FIXED32:
100 case google::protobuf::Field::TYPE_FIXED64:
102 case google::protobuf::Field::TYPE_STRING:
118 render_options_(render_options),
129 own_typeinfo_(
false),
131 render_options_(render_options),
144 ObjectWriter* ow)
const {
154 if (
field !=
nullptr) {
159 if (actual_type != expected_type &&
160 (!IsPackable(*
field) ||
170 const uint32_t end_tag,
bool include_start_and_end,
171 ObjectWriter* ow)
const {
174 if (type_renderer !=
nullptr) {
175 return (*type_renderer)(
this,
type,
name, ow);
185 if (include_start_and_end) {
186 ow->StartObject(
name);
188 while (
tag != end_tag &&
tag != 0) {
189 if (
tag != last_tag) {
192 if (
field !=
nullptr) {
194 field_name =
field->name();
196 field_name =
field->json_name();
200 if (
field ==
nullptr) {
210 if (
field->cardinality() == google::protobuf::Field::CARDINALITY_REPEATED) {
212 ow->StartObject(field_name);
226 if (include_start_and_end) {
234 uint32_t list_tag, ObjectWriter* ow)
const {
237 if (IsPackable(*
field) &&
251 return tag_to_return;
256 uint32_t list_tag, ObjectWriter* ow)
const {
270 if (map_entry_field ==
nullptr) {
275 if (map_entry_field->number() == 1) {
277 }
else if (map_entry_field->number() == 2) {
278 if (map_key.empty()) {
282 if (key_field ==
nullptr) {
298 return tag_to_return;
315 StringPiece field_name, ObjectWriter* ow) {
316 std::pair<int64_t, int32_t>
p = os->ReadSecondsAndNanos(
type);
321 "Timestamp seconds exceeds limit for field: ", field_name));
326 StrCat(
"Timestamp nanos exceeds limit for field: ", field_name));
329 ow->RenderString(field_name,
337 StringPiece field_name, ObjectWriter* ow) {
338 std::pair<int64_t, int32_t>
p = os->ReadSecondsAndNanos(
type);
343 StrCat(
"Duration seconds exceeds limit for field: ", field_name));
348 StrCat(
"Duration nanos exceeds limit for field: ", field_name));
355 StrCat(
"Duration nanos is non-negative, but seconds is "
356 "negative for field: ",
362 }
else if (
seconds == 0 && nanos < 0) {
367 "%s%lld%ss", sign.c_str(),
static_cast<long long>(
seconds),
373 ow->RenderString(field_name, formatted_duration);
379 StringPiece field_name, ObjectWriter* ow) {
383 os->stream_->ReadLittleEndian64(&buffer64);
384 os->stream_->ReadTag();
386 ow->RenderDouble(field_name, bit_cast<double>(buffer64));
392 StringPiece field_name, ObjectWriter* ow) {
396 os->stream_->ReadLittleEndian32(&buffer32);
397 os->stream_->ReadTag();
399 ow->RenderFloat(field_name, bit_cast<float>(buffer32));
405 StringPiece field_name, ObjectWriter* ow) {
409 os->stream_->ReadVarint64(&buffer64);
410 os->stream_->ReadTag();
412 ow->RenderInt64(field_name, bit_cast<int64_t>(buffer64));
418 StringPiece field_name, ObjectWriter* ow) {
422 os->stream_->ReadVarint64(&buffer64);
423 os->stream_->ReadTag();
425 ow->RenderUint64(field_name, bit_cast<uint64_t>(buffer64));
431 StringPiece field_name, ObjectWriter* ow) {
435 os->stream_->ReadVarint32(&buffer32);
436 os->stream_->ReadTag();
438 ow->RenderInt32(field_name, bit_cast<int32_t>(buffer32));
444 StringPiece field_name, ObjectWriter* ow) {
448 os->stream_->ReadVarint32(&buffer32);
449 os->stream_->ReadTag();
451 ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
457 StringPiece field_name, ObjectWriter* ow) {
462 os->stream_->ReadVarint64(&buffer64);
463 os->stream_->ReadTag();
465 ow->RenderBool(field_name, buffer64 != 0);
471 StringPiece field_name, ObjectWriter* ow) {
476 os->stream_->ReadVarint32(&buffer32);
477 os->stream_->ReadString(&
str, buffer32);
478 os->stream_->ReadTag();
480 ow->RenderString(field_name,
str);
486 StringPiece field_name, ObjectWriter* ow) {
491 os->stream_->ReadVarint32(&buffer32);
492 os->stream_->ReadString(&
str, buffer32);
493 os->stream_->ReadTag();
495 ow->RenderBytes(field_name,
str);
501 StringPiece field_name, ObjectWriter* ow) {
504 ow->StartObject(field_name);
507 if (
field ==
nullptr) {
509 tag = os->stream_->ReadTag();
514 if (os->IsMap(*
field)) {
524 StringPiece field_name, ObjectWriter* ow) {
527 tag = os->stream_->ReadTag()) {
529 if (
field ==
nullptr) {
541 StringPiece field_name, ObjectWriter* ow) {
546 ow->StartList(field_name);
553 if (
field ==
nullptr) {
555 tag = os->stream_->ReadTag();
565 StringPiece field_name, ObjectWriter* ow) {
572 for (
tag = os->stream_->ReadTag();
tag != 0;
tag = os->stream_->ReadTag()) {
574 if (
field ==
nullptr) {
580 if (
field->number() == 1) {
583 os->stream_->ReadVarint32(&type_url_size);
584 os->stream_->ReadString(&
type_url, type_url_size);
585 }
else if (
field->number() == 2) {
588 os->stream_->ReadVarint32(&value_size);
589 os->stream_->ReadString(&
value, value_size);
596 ow->StartObject(field_name);
598 ow->RenderString(
"@type",
type_url);
610 util::StatusOr<const google::protobuf::Type*> resolved_type =
611 os->typeinfo_->ResolveTypeUrl(
type_url);
613 if (!resolved_type.ok()) {
621 io::ArrayInputStream zero_copy_stream(
value.data(),
value.size());
626 os->render_options_);
629 ow->StartObject(field_name);
630 ow->RenderString(
"@type",
type_url);
632 nested_os.WriteMessage(nested_os.type_,
"value", 0,
false, ow);
639 StringPiece field_name, ObjectWriter* ow) {
644 tag = os->stream_->ReadTag()) {
645 if (paths_field_tag == 0) {
647 if (
field !=
nullptr &&
field->number() == 1 &&
648 field->name() ==
"paths") {
649 paths_field_tag =
tag;
652 if (paths_field_tag !=
tag) {
656 os->stream_->ReadVarint32(&buffer32);
657 os->stream_->ReadString(&
str, buffer32);
658 if (!combined.empty()) {
659 combined.append(
",");
663 ow->RenderString(field_name, combined);
668 std::unordered_map<std::string, ProtoStreamObjectSource::TypeRenderer>*
676 (*renderers_)[
"google.protobuf.Timestamp"] =
678 (*renderers_)[
"google.protobuf.Duration"] =
680 (*renderers_)[
"google.protobuf.DoubleValue"] =
682 (*renderers_)[
"google.protobuf.FloatValue"] =
684 (*renderers_)[
"google.protobuf.Int64Value"] =
686 (*renderers_)[
"google.protobuf.UInt64Value"] =
688 (*renderers_)[
"google.protobuf.Int32Value"] =
690 (*renderers_)[
"google.protobuf.UInt32Value"] =
692 (*renderers_)[
"google.protobuf.BoolValue"] =
694 (*renderers_)[
"google.protobuf.StringValue"] =
696 (*renderers_)[
"google.protobuf.BytesValue"] =
699 (*renderers_)[
"google.protobuf.Struct"] =
701 (*renderers_)[
"google.protobuf.Value"] =
703 (*renderers_)[
"google.protobuf.ListValue"] =
705 (*renderers_)[
"google.protobuf.FieldMask"] =
725 ObjectWriter* ow)
const {
729 if (
field->kind() == google::protobuf::Field::TYPE_MESSAGE) {
736 if (
type ==
nullptr) {
738 StrCat(
"Invalid configuration. Could not find the type: ",
746 if (type_renderer !=
nullptr) {
755 "Nested protocol message not parsed in its entirety.");
767 ObjectWriter* ow)
const {
772 switch (
field->kind()) {
773 case google::protobuf::Field::TYPE_BOOL: {
775 ow->RenderBool(field_name, buffer64 != 0);
778 case google::protobuf::Field::TYPE_INT32: {
780 ow->RenderInt32(field_name, bit_cast<int32_t>(buffer32));
783 case google::protobuf::Field::TYPE_INT64: {
785 ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
788 case google::protobuf::Field::TYPE_UINT32: {
790 ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
793 case google::protobuf::Field::TYPE_UINT64: {
795 ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
798 case google::protobuf::Field::TYPE_SINT32: {
803 case google::protobuf::Field::TYPE_SINT64: {
808 case google::protobuf::Field::TYPE_SFIXED32: {
810 ow->RenderInt32(field_name, bit_cast<int32_t>(buffer32));
813 case google::protobuf::Field::TYPE_SFIXED64: {
815 ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
818 case google::protobuf::Field::TYPE_FIXED32: {
820 ow->RenderUint32(field_name, bit_cast<uint32_t>(buffer32));
823 case google::protobuf::Field::TYPE_FIXED64: {
825 ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
828 case google::protobuf::Field::TYPE_FLOAT: {
830 ow->RenderFloat(field_name, bit_cast<float>(buffer32));
833 case google::protobuf::Field::TYPE_DOUBLE: {
835 ow->RenderDouble(field_name, bit_cast<double>(buffer64));
838 case google::protobuf::Field::TYPE_ENUM: {
843 ow->RenderNull(field_name);
856 FindEnumValueByNumber(*en, buffer32);
857 if (enum_value !=
nullptr) {
859 ow->RenderInt32(field_name, buffer32);
861 ow->RenderString(field_name,
864 ow->RenderString(field_name, enum_value->name());
867 ow->RenderInt32(field_name, buffer32);
870 ow->RenderInt32(field_name, buffer32);
874 case google::protobuf::Field::TYPE_STRING: {
877 ow->RenderString(field_name, strbuffer);
880 case google::protobuf::Field::TYPE_BYTES: {
883 ow->RenderBytes(field_name, strbuffer);
896 switch (
field.kind()) {
897 case google::protobuf::Field::TYPE_BOOL: {
900 result = buffer64 != 0 ?
"true" :
"false";
903 case google::protobuf::Field::TYPE_INT32: {
909 case google::protobuf::Field::TYPE_INT64: {
915 case google::protobuf::Field::TYPE_UINT32: {
921 case google::protobuf::Field::TYPE_UINT64: {
927 case google::protobuf::Field::TYPE_SINT32: {
933 case google::protobuf::Field::TYPE_SINT64: {
939 case google::protobuf::Field::TYPE_SFIXED32: {
945 case google::protobuf::Field::TYPE_SFIXED64: {
951 case google::protobuf::Field::TYPE_FIXED32: {
957 case google::protobuf::Field::TYPE_FIXED64: {
963 case google::protobuf::Field::TYPE_FLOAT: {
969 case google::protobuf::Field::TYPE_DOUBLE: {
975 case google::protobuf::Field::TYPE_ENUM: {
986 FindEnumValueByNumber(*en, buffer32);
987 if (enum_value !=
nullptr) {
988 result = enum_value->name();
993 case google::protobuf::Field::TYPE_STRING: {
999 case google::protobuf::Field::TYPE_BYTES: {
1017 return field.kind() == google::protobuf::Field::TYPE_MESSAGE &&
1031 if (
field ==
nullptr) {
1037 if (
field->number() == 1) {
1040 signed_seconds = bit_cast<int64_t>(
seconds);
1041 }
else if (
field->number() == 2) {
1044 signed_nanos = bit_cast<int32_t>(nanos);
1047 return std::pair<int64_t, int32_t>(signed_seconds, signed_nanos);
1051 StringPiece
type_name, StringPiece field_name)
const {
1054 StrCat(
"Message too deep. Max recursion depth reached for type '",
1055 type_name,
"', field '", field_name,
"'"));
1064 for (
int i = 0;
i <
type.fields_size(); ++
i) {
1066 return &
type.fields(i);
1075 return field.cardinality() == google::protobuf::Field::CARDINALITY_REPEATED &&
1083 for (
int i = 0;
i < tech_enum.enumvalue_size(); ++
i) {
1085 if (ev.number() ==
number) {
1096 return with_trailing_zeros ?
".000" :
"";
1099 const char*
format = (nanos % 1000 != 0) ?
"%.9f"
1100 : (nanos % 1000000 != 0) ?
"%.6f"
1105 return formatted.substr(1);