Hi Adam,

Yes, the HealthReport variable is the parent, and it contains a 
HardwareComponent variable, but I am enumerating the from the parent, 
meaning I am trying to not hard-code the structure of the contained items.

So how would I obtain a pointer to the message for each leaf without 
hard-coding the member names in there?

I am able to figure out what value I want to set in each leaf by a map I 
have that uses the field's path to match it to the value I want to store.

On Tuesday, 22 June 2021 at 13:33:11 UTC-4 [email protected] wrote:

> So is it correct that HealthReport is the top-level message type and 
> HardwareComponent is nested somewhere within that? I think what you're 
> trying to do is doable, but when you call reflection->SetString(), you have 
> to pass the immediate parent message containing the field, not the 
> top-level message. You don't need to save the descriptor for each leaf, but 
> you do need to save a pointer to the message containing each leaf.
>
> On Tue, Jun 22, 2021 at 10:17 AM J G <[email protected]> wrote:
>
>> Hi again Adam, and thank you for taking the time to help me.
>>
>> Maybe I haven't explained what I am trying to do properly.
>>
>> I have a protobuf variable, which itself is composed of more nested 
>> variables.
>>
>> I am enumerating the fields of the variable.
>>
>> Where the item is a leaf, the field is a simple c-like type (int, bool, 
>> string, etc)
>>
>> Where the item itself has fields, it is an agglomerate type and it is 
>> descended recursively.
>>
>> My aim is to set each leaf programmatically.
>>
>> So as I traverse the arborescance, I am collecting the field definitions 
>> for the leafs.
>>
>> So later, I am addressing the variable again, but trying to set one of 
>> its leafs by the field definition I saved. Do I also have to save the 
>> descriptor for each leaf?
>>
>> Can what I want to do be done?
>>
>>
>> On Tuesday, 22 June 2021 at 11:52:00 UTC-4 [email protected] wrote:
>>
>>> 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/39fd7a89-426a-453d-9482-4cb3e3658da0n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/protobuf/39fd7a89-426a-453d-9482-4cb3e3658da0n%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/764459e6-6f37-42aa-869c-0f8405aa13c6n%40googlegroups.com.

Reply via email to