void serialize_message(const google::protobuf::Message& message, std::string* serialized_string) {

    const google::protobuf::Descriptor* descriptor = message.GetDescriptor();

    const google::protobuf::Reflection* reflection = message.GetReflection();

 

    for (int i = 0; i field_count(); ++i) {

        const google::protobuf::FieldDescriptor* field = descriptor->field(i);

        bool has_field = reflection->HasField(message, field);

 

        if (has_field) {

            //arrays not supported

            assert(!field->is_repeated());

 

            switch (field->cpp_type()) {

#define CASE_FIELD_TYPE(cpptype, method, valuetype)

                case google::protobuf::FieldDescriptor::CPPTYPE_##cpptype:{

                    valuetype value = reflection->Get##method(message, field);

                    int wsize = field->name().size();

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(field->name().c_str(), field->name().size());

                    wsize = sizeof(value);

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(reinterpret_cast(&value), sizeof(value));

                    break;

                }

 

                CASE_FIELD_TYPE(INT32, Int32, int);

                CASE_FIELD_TYPE(UINT32, UInt32, uint32_t);

                CASE_FIELD_TYPE(FLOAT, Float, float);

                CASE_FIELD_TYPE(DOUBLE, Double, double);

                CASE_FIELD_TYPE(BOOL, Bool, bool);

                CASE_FIELD_TYPE(INT64, Int64, int64_t);

                CASE_FIELD_TYPE(UINT64, UInt64, uint64_t);

#undef CASE_FIELD_TYPE

                case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {

                    int value = reflection->GetEnum(message, field)->number();

                    int wsize = field->name().size();

                    //写入name占用字节数

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    //写入name

                    serialized_string->append(field->name().c_str(), field->name().size());

                    wsize = sizeof(value);

                    //写入value占用字节数

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    //写入value

                    serialized_string->append(reinterpret_cast(&value), sizeof(value));

                    break;

                }

                case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {

                    std::string value = reflection->GetString(message, field);

                    int wsize = field->name().size();

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(field->name().c_str(), field->name().size());

                    wsize = value.size();

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(value.c_str(), value.size());

                    break;

                }

                case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {

                    std::string value;

                    int wsize = field->name().size();

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(field->name().c_str(), field->name().size());

                    const google::protobuf::Message& submessage = reflection->GetMessage(message, field);

                    serialize_message(submessage, &value);

                    wsize = value.size();

                    serialized_string->append(reinterpret_cast(&wsize), sizeof(wsize));

                    serialized_string->append(value.c_str(), value.size());

                    break;

                }

            }

        }

    }

}