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.
Refs:
I am fine with internal representation as I will wrap it in a kotlin extension.
CodePudding user response:
You cannot do this. A B
has no need of, or attachment to, an A
. If you want to track the parents, you must do so explicitly yourself.
CodePudding user response:
There is no good (efficient) way to initialize a backing data structure.
An alternative approach is for the visitor to maintain an Array rather than just a B. Here is an example:
fun depthFirstVisitor(root: A, fragFilter: (frag: B) -> Boolean): Sequence<Array<B>> {
return sequence {
root.fragmentsList.forEach { child ->
if (fragFilter(child)) {
yield(arrayOf(child))
dfs(emptyArray(), child, fragFilter)
}
}
}
}
private suspend fun SequenceScope<Array<B>>.dfs(
ancestry: Array<B>,
base: B,
fragFilter: (frag: B) -> Boolean
) {
val ancestryNew = ancestry base
base.fragmentsList.forEach { child ->
if (fragFilter(child)) {
yield(ancestryNew child)
dfs(ancestryNew, child, fragFilter)
}
}
}
The current B is the last element of the array. I am using an Array because it does not suffer from type erasure like other containers.