bool PbToJsonConverter::_PbFieldToJson()

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;
}