ITADN

Print nested protobuf message types correctly with `mcap list schemas`

#1503OpenThatGeoGuy 创建于 2025-12-15
T
ThatGeoGuycommented
**Description** - Version: 0.0.58 - Platform: linux `mcap list schemas` does not list nested types within a message, which gives the false impression that schema are missing. This is related to #436, although I don't think that it is actually possible to return the original "schema source" in a perfectly copy-paste-able way. I guess to elaborate further, when a file descriptor set is written to an MCAP for protobuf schemas, this usually denotes the total sum of messages and their dependencies. This is usually a set of something akin to the Java [FileDescriptorProto](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.html) or Rust's [FileDescriptorProto](https://docs.rs/protobuf/latest/protobuf/descriptor/struct.FileDescriptorProto.html). At Tangram, we use nested messages as a way to namespace types, as well as to make sure we're compliant with the [1-1-1 convention](https://protobuf.dev/best-practices/1-1-1/). So whereas we might define a proto [like this](https://gitlab.com/tangram-vision/oss/tangram-protobuf-messages/-/blob/main/protos/tangram/detections/ImageMeasurements.proto), when it is printed out via `mcap list schemas`, it prints the following: ``` $ mcap list schemas detections.mcap id name encoding data 1 tangram.detections.ImageMeasurements protobuf syntax = "proto3"; message tangram.Uuid { optional value string = 1; } message google.protobuf.Timestamp { optional seconds int64 = 1; optional nanos int32 = 2; } message tangram.SynchronizableMetadata { optional component_uuid .tangram.Uuid = 1; optional timestamp .google.protobuf.Timestamp = 2; optional sync_group_id uint64 = 3; } message foxglove.Point2 { optional x double = 1; optional y double = 2; } message tangram.detections.ImageMeasurements { optional metadata .tangram.SynchronizableMetadata = 1; optional observed_object_space .tangram.Uuid = 2; repeated data .tangram.detections.ImageMeasurements.ImageMeasurementData = 3; } ``` **Steps To Reproduce** I don't have a minimal example, since that relies a lot on: - which language's protobuf library you're using to encode an MCAP; AND - the schema itself, which needs to have internal message definitions A simple enough schema that could replicate this is: ``` syntax = "proto3"; message Outer { message Inner { string data = 1; } repeated Inner inners = 1; } ``` I would expect that `mcap list schemas` would print out this nested `Inner` type as well. From what I can tell, all the data is actually encoded (albeit in binary) for these nested types. The only problem is that these aren't being printed internally inside the CLI tool. **Expected Behavior** I don't think you can necessarily print a perfect 1:1 representation of the original proto file as requested in #436 — in general you should not be copy and pasting those and should instead be just exporting the file descriptor set (as bytes) and generating any language-specific message types downstream of that. Since that data is structured and machine-consumable, copy and pasting the stringified output here feels like a (bad) workaround. Despite this, it would be helpful for users to be able to print out all the nested types in addition to the top-level types and dependencies, along with the nested types' fields. Especially if one wanted to use `mcap cat --json <FILE.MCAP>` or if the user is working in a dynamic language like Python where this can be automatically managed by the underlying mcap library it can be useful to get a sense of what types to expect.
1 条评论