❔ Mapping common primitive types with protobuf & grpc
I have a bunch of generated classes from proto that contain semi-pritmitive data types, for example Vector3. In every project I have to define (copy-paste) mapping code from the generated proto Vector3 to the proto Vector3.
Are there any best practices doing this kind of stuff? I found auto mapping libraries but those still require me to define a mapping and I'd be repeating the mapping definitions in every project where I use the generated files.
37 Replies
so, you're using a proto file as your source of truth?
no
I believe the System.Numerics.Vector3 is the best example I have.
imagine the following proto definition:
At some point in the code after receiving this proto message you'd want to tranform the proto Vector3 into a System.Numerics.Vector3 to use it for calculations / call libraries, etc. In every project that I use the above proto file I have to copy-paste a mapping function that given a Namespace.Of.Just.Generated.Proto.Vector3 into a System.Numerics.Vector3.
what's generating these models?
I use Grpc.Tools
which generates from what?
proto
ah you meant source of truth for the code generation...
I edited OP because for some reason my brain wrote that I have generated classes from grpc instead of "i have generated classes from proto"
is Grpc.Tools a source generator? or just a scaffolding tool?
it's generating code compile time so I believe it's using source generators, or something similar
but no idea how they choose to implement codegen
well, that's what I was getting at
I dunno, unless they specifically have hooks for allowing you to define your own type mappings, you're probably out-of-luck
Even if it did I wouldn't want to define any project/tool specific thing in the proto file as these are shared between completely different teams using different tech stack
right, I'm talking about Grpc.Tools
so what you're suggesting is that if there was a way it'd be best if instead of the generated Vector3, the code generator could already put System.Numerics.Vector3 in there.
just imagingin how that could possible work, at that point the generated code couldn't possibly call the proto write on that vector3 because obviously System.Numerics.Vector3 is not a proto class.
There'd need to exist a mapping still somewhere 😐
right
it's entirely possible, but I have no idea if Grpc.Tools supports anything like that
you'll have to read their docs
or, more likely, as it looks like they don't really HAVE any docs, you'll have to dive through source code
that's fine, can you please give me the tool whith which you're familiar where it's possible? I can take inspiration from that
(and yes grpctools has basically no docs..)
it's... not something you can take inspiration from
Grpc.Tools is either extensible, or it isn't
I mean.. it's open source I can fork / rewrite do anything, I can also switch over to what you're using
if it has the featureset that I need... I'm not married to grpc.tools...
what do you mean "what I'm using"?
I'm not "using" anything
sorry, I thought you had something specific in mind when you said
it's entirely possible, but I have no idea if Grpc.Tools supports anything like thatit came across that you are also using protobuf and know of a library or tool that supports what I need or have solved this issue otherwise
I've used protobuf a bit before, but the other way around
C# models as the source of truth, with the option to generate proto files for other languages, if I want
and I'm vaguely familiar with a few source gen libraries
hm, interesting approach, unfortunately I get the proto files so I have to use that as source
right
you could always write your own source gen
I do that already for other stuff, and I would do it here as well. My main issue is that I have no idea how a solution could look like
at the end of the day that mapping has to be defined somewhere
right
so, how does the source gen lib pick up on the proto files to gen for?
then it's either some msbuild step of source generators that do the magic
sure
so, there could be a config file that you include in a similar manner
or just config that you specify directly in the MSBuild
the config itself ought to be fairly simple, right?
you ultimately just need to say "for type X in protobuf, translate it to System.Numerics.Vector3"
and the source gen would need to do a little but of analysis to find that system type and make sure it's compatible and emit whatever translation code might be necessary
or, like, emit some kind of
TypeConverter<T>
class for each mapping
whatever the appropriate code would be if you were writing it yourselfooo that's clever, like generate the converters as well
if that's what it would take
protobuf generates partial classes so I can also generate implicit conversions "into" the proto classes
like proxy properties?
well, that sounds like a reasonable-enough solution
maybe not ideal
that or just simply
so you'd still see the generated type in the protobuf but that can be implicitly converted to the desired domain type
yeah
I'd probably be a little more inclined to use an explicit property than an implicit cast
those conversions can probably get expensive pretty quickly, so I'd rather have them be very visible
good point, but will have to look out for name collisions
it still seems like a common-enough scenario that Grpc.Tools ought to be extensible for you to put your own mappings in
probably worth asking on their github page
it doesn't have to be, I have a code generator for other purposes where I already do my own .proto -> .desc -> c# code, I can just hook into that and generate these mappings from a config file as well
and if they don't support it, you could always contribute it yourself
that way I'm still not married to grpc.tools
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.