I think the easiest thing would be that wherever you're now storing a
google::protobuf::FieldDescriptor*, you can also store a
google::protobuf::Message* pointing to the parent message.

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

> 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
> <https://groups.google.com/d/msgid/protobuf/764459e6-6f37-42aa-869c-0f8405aa13c6n%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/CADqAXr7s5T9Oj1wLOhfpsWRD5tbCUe8dAj62QVBgJx4NvXmEig%40mail.gmail.com.

Reply via email to