reflect/protodesc: descriptors that use legacy features (message set wire format, weak imports and weak fields) cannot be round-tripped to protos and back
What version of protobuf and what language are you using? v1.25.0
What did you do?
Example proto file tmp.proto
syntax = "proto2";
option go_package = "main";
message Foo {
option message_set_wire_format = true;
extensions 100 to max;
}We can successfully generate Go code for this:
protoc --go_out=. tmp.protoAnd the resulting code can successfully retrieve the descriptor:
package main
import "github.com/golang/protobuf/proto"
import "fmt"
func main() {
r := proto.MessageReflect(&Foo{})
fmt.Println(r.Descriptor().FullName())
}However, if we try to convert the descriptor to a proto and then create a descriptor from that (which would also happen if, for example, we loaded the descriptor from a protoset produced by protoc or from a gRPC server via server reflection), we get an error:
package main
import "github.com/golang/protobuf/proto"
import "google.golang.org/protobuf/reflect/protodesc"
import "google.golang.org/protobuf/reflect/protoregistry"
import "fmt"
func main() {
r := proto.MessageReflect(&Foo{})
fmt.Println(r.Descriptor().FullName())
pr := protodesc.ToFileDescriptorProto(r.Descriptor().ParentFile())
var reg protoregistry.Files
fd, err := protodesc.NewFile(pr, ®)
if err != nil {
panic(err)
}
fmt.Println(fd.Path())
}What did you expect to see? The second, longer program succeeds and prints "tmp.proto".
What did you see instead? Running the new program actually fails:
panic: proto: message "Foo" is a MessageSet, which is a legacy proto1 feature that is no longer supportedI can understand an error like that if we tried to use such a message, to serialize or de-serialize. But it seems really weird that we can't even create the descriptor, especially since we can successfully create the descriptor if it is packaged in the protoc-gen-go-generated code.
Source: golang/protobuf