It looks to me like r->report points to a vafmsg.HealthReport but the field
descriptor refers to a field in another message (vafmsg.HardwareComponent).

On Tue, Jun 22, 2021 at 7:42 AM J G <[email protected]> wrote:

> Hello Adam,
>
> OK, I understand, so I've tried this, but I get an error.
>
> void my_set_value( class healthreport * r, const char * defaultvalue,
> const google::protobuf::FieldDescriptor * descriptor ) {
>
>     auto reflection = r->report->GetReflection();
>
>     switch( descriptor->type() ) {
>         case google::protobuf::FieldDescriptor::TYPE_STRING: {
>
>                 printf( "REQUESTED TYPE: STRING" EOL );
>                 std::string s = defaultvalue;
>                 reflection->SetString( r->report, descriptor, s );
>
>             }
>             break;
>
>         default:
>
>             printf( "REQUESTED TYPE %d NOT HANDLED" EOL,
> descriptor->type() );
>             break;
>
>     }
>
> }
> Running the above produces the following output:
>
> REQUESTED TYPE: STRING
> [libprotobuf FATAL
> /var/tmp/portage/dev-libs/protobuf-3.15.8/work/protobuf-3.15.8/src/google/protobuf/generated_message_reflection.cc:111]
> Protocol Buffer reflection usage error:
>   Method      : google::protobuf::Reflection::SetString
>   Message type: vafmsg.HealthReport
>   Field       : vafmsg.HardwareComponent.hardware_interface
>   Problem     : Field does not match message type.
> terminate called after throwing an instance of
> 'google::protobuf::FatalException'
>   what():  Protocol Buffer reflection usage error:
>   Method      : google::protobuf::Reflection::SetString
>   Message type: vafmsg.HealthReport
>   Field       : vafmsg.HardwareComponent.hardware_interface
>   Problem     : Field does not match message type.
>
> Here is the proto definition of the variable triggering the exception:
>
> message HardwareComponent {
>     optional Component component = 1;
>     repeated DiscreteValue temp = 2;
>     optional string hardware_interface = 3;
>     optional uint32 remaining_life = 4;
>     optional uint32 total_hours = 5;
>     optional EnergyInfo energy = 6;
> }
>
> So the type really IS string, yet an exception is triggered...
>
> What am I doing wrong?
>
> On Friday, 18 June 2021 at 17:56:57 UTC-4 [email protected] wrote:
>
>> Each descriptor describes part of the schema (e.g. a message type, enum
>> type, etc.) but is unrelated to any particular instance of it. As a result,
>> if you have a descriptor by itself then you can't really modify anything
>> because you separately need an instance of the thing you want to modify.
>> The way to programmatically modify a message is to use the Reflection
>> <https://github.com/protocolbuffers/protobuf/blob/9d9d8ee18dedfb18371031cd299d1d282ddf707f/src/google/protobuf/message.h#L452>
>> API. You can use Reflection::ListFields() to get a list of all the fields
>> that are set on the message and then there are Reflection::Get* and
>> Reflection::Set* methods to get and set particular fields.
>>
>> On Fri, Jun 18, 2021 at 9:11 AM J G <[email protected]> wrote:
>>
>>> Hi,
>>>
>>> I've got some code that lets me recursively walk a protobuf variable.
>>>
>>> That part works, I can enumerate the characteristics of a variable, but
>>> the pointers/references returned by the API are const.
>>>
>>> My question is: From a variable's Descriptor or FieldDescriptor, is it
>>> possible to get a non-const pointer/reference to the field to be able to
>>> modify it?
>>>
>>> Here's my (simplified) code so far:
>>>
>>> void enumpb(  const google::protobuf::Descriptor * d ) {
>>>
>>>     for ( int i = 0; i < d->field_count(); i++ ) {
>>>
>>>         auto field = d->field( i );
>>>
>>>         // Modify variable code here
>>>         [...]
>>>
>>>         auto mt = field->message_type();
>>>         if ( ! mt ) {
>>>             continue;
>>>         } else if ( 0 != strcmp( d->full_name().c_str(),
>>> mt->full_name().c_str() ) ) {
>>>
>>>             enumpb( mt ) ;
>>>
>>>         }
>>>
>>>     }
>>>
>>>     return true;
>>>
>>> }
>>>
>>> --
>>> 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 [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/protobuf/dcf6bb53-24ce-4404-ab71-0fe3a94adc40n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/protobuf/dcf6bb53-24ce-4404-ab71-0fe3a94adc40n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/protobuf/7ef6e77e-8635-4b16-b570-b80f75d207d9n%40googlegroups.com
> <https://groups.google.com/d/msgid/protobuf/7ef6e77e-8635-4b16-b570-b80f75d207d9n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/protobuf/CADqAXr4x6%3D9XxxJuVciQJVbM%3D9uUMoUD_wpB_5%2B_47Sg00WFVA%40mail.gmail.com.

Reply via email to