-
Notifications
You must be signed in to change notification settings - Fork 1.6k
What is the idiomatic way to get the corresponding struct field for a FieldDescriptorProto? #457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Unfortunately, there's currently not really an idiomatic way to do this.
The solution for this is #364, so that you can use some proto reflection API to obtain the field value. |
I'm going to close this in favor of #364. |
FWIW, @junghoahnsc, it is possible to extract the field with existing APIs. But it isn't trivial (and not very pretty): rval := reflect.Value(m)
props := proto.GetProperties(reflect.TypeOf(m).Elem())
// ...
_, descProt := descriptor.ForMessage(m)
for _, fd := range descProt.GetField(m) {
// check the field option
opts := fd.GetOptions()
c, err := proto.GetExtension(opts, xxx)
// ...
if condition {
var field reflect.Value
for _, p := range props.Prop {
if int32(p.Tag) == fd.GetNumber() {
field = rval.FieldByName(p.Name)
break
}
}
if !field.IsValid() {
// must be a one-of if not found above
for _, oo := range props.OneofTypes {
if int32(oo.Prop.Tag) == fd.GetNumber() {
field = rval.Field(oo.Field).Elem().FieldByName(oo.Prop.Name)
break
}
}
}
if !field.IsValid() {
panic(fmt.Sprintf("cannot find struct field for %s, tag %d", fd.GetName(), fd.GetNumber()))
}
// do something with field...
}
} Note that this code is a naive implementation. (A better one would probably pre-compute a map of tag number -> accessor function to avoid paying the linear scan for each field query. As is, the example code is quadratic when it could be linear.) |
@jhump Thanks for the tip! And I noticed that StructProperties has |
Hello,
I'm trying to loop each field of a message and check proto field option. For example,
Here,
fd.GetName()
returns the proto field name, so we need to convert to Go name.Should I use https://github.com/golang/protobuf/blob/master/protoc-gen-go/generator/generator.go#L2736 ? Or is there any better way to do that?
Thanks,
The text was updated successfully, but these errors were encountered: