in src/json2pb/pb_to_json.cpp [180:298]
bool PbToJsonConverter::_PbFieldToJson(
const google::protobuf::Message& message,
const google::protobuf::FieldDescriptor* field,
Handler& handler) {
const google::protobuf::Reflection* reflection = message.GetReflection();
switch (field->cpp_type()) {
#define CASE_FIELD_TYPE(cpptype, method, valuetype, handle) \
case google::protobuf::FieldDescriptor::CPPTYPE_##cpptype: { \
if (field->is_repeated()) { \
int field_size = reflection->FieldSize(message, field); \
handler.StartArray(); \
for (int index = 0; index < field_size; ++index) { \
handler.handle(static_cast<valuetype>( \
reflection->GetRepeated##method( \
message, field, index))); \
} \
handler.EndArray(field_size); \
\
} else { \
handler.handle(static_cast<valuetype>( \
reflection->Get##method(message, field))); \
} \
break; \
}
CASE_FIELD_TYPE(BOOL, Bool, bool, Bool);
CASE_FIELD_TYPE(INT32, Int32, int, AddInt);
CASE_FIELD_TYPE(UINT32, UInt32, unsigned int, AddUint);
CASE_FIELD_TYPE(INT64, Int64, int64_t, AddInt64);
CASE_FIELD_TYPE(UINT64, UInt64, uint64_t, AddUint64);
CASE_FIELD_TYPE(FLOAT, Float, double, Double);
CASE_FIELD_TYPE(DOUBLE, Double, double, Double);
#undef CASE_FIELD_TYPE
case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
std::string value;
if (field->is_repeated()) {
int field_size = reflection->FieldSize(message, field);
handler.StartArray();
for (int index = 0; index < field_size; ++index) {
value = reflection->GetRepeatedStringReference(
message, field, index, &value);
if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES
&& _option.bytes_to_base64) {
std::string value_decoded;
butil::Base64Encode(value, &value_decoded);
handler.String(value_decoded.data(), value_decoded.size(), false);
} else {
handler.String(value.data(), value.size(), false);
}
}
handler.EndArray(field_size);
} else {
value = reflection->GetStringReference(message, field, &value);
if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES
&& _option.bytes_to_base64) {
std::string value_decoded;
butil::Base64Encode(value, &value_decoded);
handler.String(value_decoded.data(), value_decoded.size(), false);
} else {
handler.String(value.data(), value.size(), false);
}
}
break;
}
case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
if (field->is_repeated()) {
int field_size = reflection->FieldSize(message, field);
handler.StartArray();
if (_option.enum_option == OUTPUT_ENUM_BY_NAME) {
for (int index = 0; index < field_size; ++index) {
const std::string& enum_name = reflection->GetRepeatedEnum(
message, field, index)->name();
handler.String(enum_name.data(), enum_name.size(), false);
}
} else {
for (int index = 0; index < field_size; ++index) {
handler.AddInt(reflection->GetRepeatedEnum(
message, field, index)->number());
}
}
handler.EndArray();
} else {
if (_option.enum_option == OUTPUT_ENUM_BY_NAME) {
const std::string& enum_name =
reflection->GetEnum(message, field)->name();
handler.String(enum_name.data(), enum_name.size(), false);
} else {
handler.AddInt(reflection->GetEnum(message, field)->number());
}
}
break;
}
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
if (field->is_repeated()) {
int field_size = reflection->FieldSize(message, field);
handler.StartArray();
for (int index = 0; index < field_size; ++index) {
if (!Convert(reflection->GetRepeatedMessage(
message, field, index), handler)) {
return false;
}
}
handler.EndArray(field_size);
} else {
if (!Convert(reflection->GetMessage(message, field), handler)) {
return false;
}
}
break;
}
}
return true;
}