cmd/protoc-gen-go: register FileDescriptorProto
Generate the gzipped FileDescriptorProto var, and register it with
proto.RegisterFile at init time.
Change-Id: Ie232f20412ca9cd7bde91aaba7127dc181e9758c
Reviewed-on: https://go-review.googlesource.com/134118
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go/main.go b/cmd/protoc-gen-go/main.go
index 5792ebe..b9223b0 100644
--- a/cmd/protoc-gen-go/main.go
+++ b/cmd/protoc-gen-go/main.go
@@ -7,6 +7,15 @@
package main
import (
+ "bytes"
+ "compress/gzip"
+ "crypto/sha256"
+ "encoding/hex"
+ "fmt"
+ "strconv"
+
+ "github.com/golang/protobuf/proto"
+ descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"google.golang.org/proto/protogen"
)
@@ -34,7 +43,51 @@
genMessage(gen, g, m)
}
- // TODO: Everything.
+ genFileDescriptor(gen, g, f)
+}
+
+func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *protogen.File) {
+ // Determine the name of the var holding the file descriptor:
+ //
+ // fileDescriptor_<hash of filename>
+ filenameHash := sha256.Sum256([]byte(f.Desc.Path()))
+ varName := fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(filenameHash[:8]))
+
+ // Trim the source_code_info from the descriptor.
+ // Marshal and gzip it.
+ descProto := proto.Clone(f.Proto).(*descpb.FileDescriptorProto)
+ descProto.SourceCodeInfo = nil
+ b, err := proto.Marshal(descProto)
+ if err != nil {
+ gen.Error(err)
+ return
+ }
+ var buf bytes.Buffer
+ w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
+ w.Write(b)
+ w.Close()
+ b = buf.Bytes()
+
+ g.P("func init() { proto.RegisterFile(", strconv.Quote(f.Desc.Path()), ", ", varName, ") }")
+ g.P()
+ g.P("var ", varName, " = []byte{")
+ g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
+ for len(b) > 0 {
+ n := 16
+ if n > len(b) {
+ n = len(b)
+ }
+
+ s := ""
+ for _, c := range b[:n] {
+ s += fmt.Sprintf("0x%02x,", c)
+ }
+ g.P(s)
+
+ b = b[n:]
+ }
+ g.P("}")
+ g.P()
}
func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, m *protogen.Message) {
diff --git a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
index 0ae32d1..ba78d1b 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -11,3 +11,21 @@
type Layer1_Layer2_Layer3 struct {
}
+
+func init() { proto.RegisterFile("proto2/nested_messages.proto", fileDescriptor_7417ee157699d191) }
+
+var fileDescriptor_7417ee157699d191 = []byte{
+ // 184 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0x28, 0xca, 0x2f,
+ 0xc9, 0x37, 0xd2, 0xcf, 0x4b, 0x2d, 0x2e, 0x49, 0x4d, 0x89, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c,
+ 0x4f, 0x2d, 0xd6, 0x03, 0x0b, 0x0b, 0x89, 0xa6, 0xe7, 0x83, 0x19, 0x10, 0x6e, 0x32, 0x84, 0x32,
+ 0x52, 0x3a, 0xc3, 0xc8, 0xc5, 0xe6, 0x93, 0x58, 0x99, 0x5a, 0x64, 0x28, 0x64, 0xc2, 0xc5, 0x94,
+ 0x63, 0x24, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0x55, 0xb9, 0x1e, 0x44, 0x29,
+ 0x84, 0x32, 0x0a, 0x62, 0xca, 0x31, 0x12, 0xb2, 0xe6, 0x62, 0xca, 0x31, 0x96, 0x60, 0x02, 0xeb,
+ 0xd2, 0x26, 0x46, 0x17, 0x84, 0x32, 0x0e, 0x62, 0xca, 0x31, 0x96, 0xf2, 0x87, 0x5a, 0x0e, 0x33,
+ 0x86, 0x91, 0x3c, 0x63, 0x38, 0xa0, 0xc6, 0x18, 0x3b, 0x59, 0x47, 0x59, 0xa6, 0xe7, 0xe7, 0xa7,
+ 0xe7, 0xa4, 0xea, 0xa5, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, 0xeb, 0xe5, 0x17, 0xa5, 0xeb, 0x83, 0xb5,
+ 0xeb, 0x27, 0xe7, 0xa6, 0x40, 0x58, 0xc9, 0xba, 0xe9, 0xa9, 0x79, 0xba, 0xe9, 0xf9, 0xfa, 0x25,
+ 0xa9, 0xc5, 0x25, 0x29, 0x89, 0x25, 0x89, 0x10, 0x61, 0x23, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x47, 0x0d, 0xa3, 0x19, 0x41, 0x01, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 90ffa17..72dcb71 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -5,3 +5,16 @@
type Message struct {
}
+
+func init() { proto.RegisterFile("proto2/proto2.proto", fileDescriptor_d756bbe8817c03c1) }
+
+var fileDescriptor_d756bbe8817c03c1 = []byte{
+ // 107 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f,
+ 0xc9, 0x37, 0xd2, 0x87, 0x50, 0x7a, 0x60, 0x4a, 0x48, 0x34, 0x3d, 0x1f, 0xcc, 0x80, 0x70, 0x93,
+ 0x21, 0x94, 0x91, 0x12, 0x27, 0x17, 0xbb, 0x6f, 0x6a, 0x71, 0x71, 0x62, 0x7a, 0xaa, 0x93, 0x75,
+ 0x94, 0x65, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x5e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, 0xba, 0x5e,
+ 0x7e, 0x51, 0x3a, 0xc4, 0x0c, 0xfd, 0xe4, 0xdc, 0x14, 0x08, 0x2b, 0x59, 0x37, 0x3d, 0x35, 0x4f,
+ 0x37, 0x3d, 0x5f, 0xbf, 0x24, 0xb5, 0xb8, 0x24, 0x25, 0xb1, 0x24, 0x11, 0x6a, 0x09, 0x20, 0x00,
+ 0x00, 0xff, 0xff, 0xd7, 0x76, 0x0d, 0x22, 0x74, 0x00, 0x00, 0x00,
+}
diff --git a/protogen/protogen.go b/protogen/protogen.go
index ffc1d7a..be5e503 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -299,7 +299,8 @@
// A File describes a .proto source file.
type File struct {
- Desc protoreflect.FileDescriptor
+ Desc protoreflect.FileDescriptor
+ Proto *descpb.FileDescriptorProto
GoPackageName GoPackageName // name of this file's Go package
GoImportPath GoImportPath // import path of this file's Go package
@@ -324,6 +325,7 @@
}
f := &File{
Desc: desc,
+ Proto: p,
GoPackageName: packageName,
GoImportPath: importPath,
}