golang / protobuf

Go support for Google's protocol buffers
BSD 3-Clause "New" or "Revised" License
9.66k stars 1.58k forks source link

Type checking a message using protoreflect.MessageDescriptor #1476

Closed F21 closed 1 year ago

F21 commented 1 year ago

I am writing a protoc plugin using protogen. I need to traverse the fields of the input messages and check if a field is of a certain message type.

I am able to get the name of the message in string form using message.Desc.FullName(). I would then need to switch on the string like so:

switch msgName {
  case "pkg.myMessage1":

  case "pkg.myMessage2":
}

This is can be error-prone and hard to debug if a type is made in one of the cases. Is it possible to somehow use a type switch? Ideally, I'd love to be able to do something like this:

switch msg.(type) {
  case *pkg.myMessage1:

  case *pkg.myMessage2:
}
puellanivis commented 1 year ago

I’m confused. Are you asking if Go has a type switch, which it does:

switch msg := msg.(type) {
case *pkg.myMessage1:
  // msg as used here will be of concrete type `*pkg.myMessage1`
case *pkg.myMessage2:
  // msg as used here will be of concrete type `*pkg.myMessage2`
}

Or are you already aware of how to do type switches in Go, you’re just wondering how to do it here specifically with a dynamic protobuf descriptor datatype?

F21 commented 1 year ago

@puellanivis Whoops, just realized I forgot the .(type) in my example. Yes I am aware of how to use a type switch against a proto.message, so my question is how do I do it against a dynamic protobuf descriptor?

puellanivis commented 1 year ago

OK, thanks, I was kind of expecting that were the case, but I didn’t want to assume, just in case you weren’t so aware of type switches.

To the question🤔 I think, because the type-switch would require compiled source code to already be done, I’m thinking it’s unlikely that there would be any way to do it via a type switch rather than through through raw struct field values.

F21 commented 1 year ago

That's a bit unfortunate, but understandable. Looks like I'll just have to match against the full name of the message in string form. Thanks so much for your help!