DynamicMessage::from_message round-trips through bytes, panics on mismatch, and needs a hand-resolved MessageIndex
- Dominant language
- Rust
- Stars
- 883
- Forks
- 88
- Avg merge
- 3d 19h
- Merged PRs (30d)
- 42
Description
`DynamicMessage::from_message` is the only road from a generated `Message` value to reflection, and it has two costs a caller cannot avoid:
- it encodes the whole message to a `Vec` and decodes it again against the descriptor, so a library that evaluates over a request struct it already holds pays an encode plus a full decode on every call;
- it takes a `MessageIndex` the caller has to resolve by hand from the pool (strip a leading dot, look the full name up), and it panics on a descriptor mismatch instead of returning an error, so a pool that was built from a different `.proto` revision than the generated code turns into a process abort rather than a `DecodeError`.
```rust
pub fn from_message(msg: &M, pool: Arc, msg_idx: MessageIndex) -> Self {
let bytes = msg.encode_to_vec();
Self::decode(pool, msg_idx, &bytes)
.expect("generated message must round-trip through its own descriptor")
}
```
What would close the gap, in increasing order of ambition:
1. A fallible variant, `try_from_message`, that returns the `DecodeError` and leaves the panicking one as a thin wrapper (or deprecates it).
2. Index resolution from the type itself: with `M: Message + MessageName` the full name is `M::PACKAGE` + `M::NAME`, so the caller should not need to look up the `MessageIndex` at all — `try_from_message(msg, pool)` with a `DecodeError`/`NotFound` when the pool lacks the type.
3. A road that does not re-encode: either a generated-code reflection hook (each generated message can walk its own fields against its descriptor and populate the dynamic field map directly), or a borrowed reflective view over `&M` that answers field-by-field reads without materialising a `DynamicMessage`. This is what makes reflection over a message the host already owns cheap enough to use per request.
Items 1 and 2 are small and additive. Item 3 is the real gap and probably wants a design note first; happy to sketch one if there is appetite.
Contributor guide
Assessment
This issue has not been assessed yet.