diff --git a/desc/protoparse/linker.go b/desc/protoparse/linker.go index 0301541c..2aa32f08 100644 --- a/desc/protoparse/linker.go +++ b/desc/protoparse/linker.go @@ -372,6 +372,14 @@ func (l *linker) resolveMessageTypes(r *parseResult, fd *dpb.FileDescriptorProto return err } } + for _, ood := range md.OneofDecl { + if ood.Options != nil { + ooName := fmt.Sprintf("%s.%s", fqn, ood.GetName()) + if err := l.resolveOptions(r, fd, "oneof", ooName, proto.MessageName(ood.Options), ood.Options.UninterpretedOption, scopes); err != nil { + return err + } + } + } for _, fld := range md.Extension { if err := l.resolveFieldTypes(r, fd, prefix, fld, scopes); err != nil { return err diff --git a/desc/protoparse/linker_test.go b/desc/protoparse/linker_test.go index b9ab9705..287dc662 100644 --- a/desc/protoparse/linker_test.go +++ b/desc/protoparse/linker_test.go @@ -180,6 +180,44 @@ func TestLinkerValidation(t *testing.T) { }, "foo.proto:1:70: field fu.baz.foobar.a: unknown type baz; resolved to fu.baz which is not defined; consider using a leading dot", }, + { + map[string]string{ + "foo.proto": ` + syntax = "proto2"; + package foo; + import "google/protobuf/descriptor.proto"; + extend google.protobuf.FileOptions { optional string fil_foo = 12000; } + extend google.protobuf.MessageOptions { optional string msg_foo = 12000; } + extend google.protobuf.FieldOptions { optional string fld_foo = 12000 [(fld_foo) = "extension"]; } + extend google.protobuf.OneofOptions { optional string oof_foo = 12000; } + extend google.protobuf.EnumOptions { optional string enm_foo = 12000; } + extend google.protobuf.EnumValueOptions { optional string env_foo = 12000; } + extend google.protobuf.ExtensionRangeOptions { optional string ext_foo = 12000; } + extend google.protobuf.ServiceOptions { optional string svc_foo = 12000; } + extend google.protobuf.MethodOptions { optional string mtd_foo = 12000; } + option (fil_foo) = "file"; + message Bar { + option (msg_foo) = "message"; + oneof foo { + option (oof_foo) = "oneof"; + string bar = 1 [(fld_foo) = "field"]; + } + extensions 100 to 200 [(ext_foo) = "extensionrange"]; + } + enum Baz { + option (enm_foo) = "enum"; + ZERO = 0 [(env_foo) = "enumvalue"]; + } + service FooService { + option (svc_foo) = "service"; + rpc Bar(Bar) returns (Bar) { + option (mtd_foo) = "method"; + } + } + `, + }, + "", // should success + }, { map[string]string{ "foo.proto": "package fu.baz; message foobar{ repeated string a = 1 [default = \"abc\"]; }",