How to: get the parent message

154 views
Skip to first unread message

phreed

unread,
Nov 22, 2022, 4:30:16 AM11/22/22
to Protocol Buffers
In Java…
Given a message (b of type B), nested in another (a of type A); how does one get ‘a’?
I was hoping for something like ‘b.getParent()’.

message B {  optional string c = 1; }
message A { optional B b  = 1; }

Here is an example instance of an ‘a’ with textual serialization.

b { c: “foo” }



Fred Eisele

unread,
Nov 22, 2022, 8:46:02 AM11/22/22
to Protocol Buffers
Given a message (b of type B), nested in another (a of type A); how does one get ‘a’?
I was hoping for something like ‘b.getParent()’.

message B { optional string name = 1;  repeated B b = 2; }
message A { optional string name = 1;  repeated B b = 1; }


Here is an example instance of an ‘a’ with textual serialization.

name: "a"
b { name: “foo”
      b { name: “fred”
            b { name: “flintstone” }}}
b { name: “bar” }
b { name: “baz” }

The issue is that I am navigating the collection 'a' with a visitor and I need to be able to reconstruct a full name composed of names of all the ancestors.

Nadav Samet

unread,
Nov 22, 2022, 12:16:29 PM11/22/22
to Fred Eisele, Protocol Buffers
Hi Fred, you haven't mentioned a specific language you use, but in all the standard implementations I am familiar with (Java, Python, C++) an instance of a message doesn't hold a reference to its container. The opposite is true, you can find all the fields if you start working from the root. To construct the path, you can have the visitor build the partial path from the root as it goes down the graph.

-Nadav

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/protobuf/9ba69d16-218b-4cde-b0c9-faa651a46167n%40googlegroups.com.


--
-Nadav

Fred Eisele

unread,
Nov 22, 2022, 1:54:35 PM11/22/22
to Protocol Buffers
Thanks for the answers.

I am using Kotlin.
I will modify my sequence to yield on a pair.
* the current path
* the current object
It should be a minor change. 
Currently, the yield is on the current object only.

Josh Humphries

unread,
Nov 29, 2022, 1:59:18 PM11/29/22
to Fred Eisele, Protocol Buffers
No official runtimes provide a way to do this. Messages do not have backlinks to containers if they are nested inside another message.

To do what you are trying to do would require a recursive traversal that starts at the top (a) and then accumulates the names into a path with each recursive call. Something like so:

func handle(msg b, path []string) {
    currentPath := append(path, msg.name)

    // ... do something with msg and currentPath ...

    if msg.b != nil {
        handle(msg.b, currentPath)
    }
}

----
Josh Humphries
jh...@bluegosling.com


Reply all
Reply to author
Forward
0 new messages