Set field onof type message using reflection in protobuf

31 views
Skip to first unread message

Gaurav Bhosale

unread,
Jun 22, 2019, 2:50:51 AM6/22/19
to Protocol Buffers
I am trying to set field of protobuf message.
My proto message look like,

package message;

message Packet
{
    required int32 header = 1;
    oneof payload
    {
        Home home = 2;
        Door door = 3;
    }
}

message Home {
    required int32 id = 1;
}
message Door {
    required int32 id = 1;
}

What I did,
Using SetInt32, I am able to set header field.
But when I am trying to set Home message fields ( oneof payload ), I am getting following errors.
I facing issue with setting field values of oneof message fields.

Output:
 header : header int32
 header value : 42
 Payload : payload 2
 home : home message
[libprotobuf FATAL google/protobuf/generated_message_reflection.cc:112] Protocol Buffer reflection usage error:
  Method      : google::protobuf::Reflection::SetInt32
  Message type: message.Packet
  Field       : message.Packet.home
  Problem     : Field is not the right type for this message:
    Expected  : CPPTYPE_INT32
    Field type: CPPTYPE_MESSAGE
terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  Protocol Buffer reflection usage error:
  Method      : google::protobuf::Reflection::SetInt32
  Message type: message.Packet
  Field       : message.Packet.home
  Problem     : Field is not the right type for this message:
    Expected  : CPPTYPE_INT32
    Field type: CPPTYPE_MESSAGE
Aborted (core dumped)

CPP code:

#include <iostream>
#include "proto/message.pb.h"

using namespace std;
using namespace google::protobuf;

int main(int argc, char const *argv[])
{
message::Packet f;
const google::protobuf::Descriptor *d = f.GetDescriptor();
const google::protobuf::FieldDescriptor *a = d->FindFieldByName("header");

cout << " header : " << a->name() << " "<< a->type_name() << endl;

const google::protobuf::Reflection* r = f.GetReflection();
r->SetInt32(&f, a, 42);

cout << " header value : " << f.header() << endl;

//const OneofDescriptor* oneof2_ = d->FindOneofByName("payload");
//cout << " Payload : " << oneof2_->name() << " " << oneof2_->field_count() <<endl;
const google::protobuf::FieldDescriptor *a11 = d->FindFieldByName("home");
const google::protobuf::FieldDescriptor *a1 = a11->message_type()->FindFieldByName("id");
cout << " home : " << a1->name() << " " << a1->type_name() <<endl;

const google::protobuf::Reflection* rr = f.GetReflection();
rr->SetInt32(&f, a1, 24);
cout << " home id value : " << f.home().id() << endl;
}




main.cpp
message.proto

Adam Cozzette

unread,
Jun 24, 2019, 1:12:50 PM6/24/19
to Gaurav Bhosale, Protocol Buffers
I think the problem is that when you call rr->SetInt32(&f, a1, 24) you're trying to set a field inside a nested message inside f, which does not work. You can only set a field directly inside the message you're passing, so it should be something like rr->SetInt32(f->mutable_home(), a1, 24).

--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to protobuf+u...@googlegroups.com.
To post to this group, send email to prot...@googlegroups.com.
Visit this group at https://groups.google.com/group/protobuf.
To view this discussion on the web visit https://groups.google.com/d/msgid/protobuf/e834aec3-8ceb-4b91-a3cc-911831caf1de%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages