Skip to content

Commit

Permalink
cmd/protoc-gen-go: generate _protoopaque variant for hybrid
Browse files Browse the repository at this point in the history
For golang/protobuf#1657

Change-Id: I3c35fceeddedcd159a5adacec3113e12497ebd27
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/634817
Reviewed-by: Damien Neil <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
  • Loading branch information
stapelberg committed Dec 11, 2024
1 parent 9eda3d5 commit b64efdb
Show file tree
Hide file tree
Showing 25 changed files with 25,119 additions and 5 deletions.
48 changes: 43 additions & 5 deletions cmd/protoc-gen-go/internal_gengo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"google.golang.org/protobuf/runtime/protoimpl"

"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/gofeaturespb"
"google.golang.org/protobuf/types/pluginpb"
)

Expand Down Expand Up @@ -70,11 +71,41 @@ type goImportPath interface {
Ident(string) protogen.GoIdent
}

func setToOpaque(msg *protogen.Message) {
msg.APILevel = gofeaturespb.GoFeatures_API_OPAQUE
for _, nested := range msg.Messages {
nested.APILevel = gofeaturespb.GoFeatures_API_OPAQUE
setToOpaque(nested)
}
}

// GenerateFile generates the contents of a .pb.go file.
//
// With the Hybrid API, multiple files are generated (_protoopaque.pb.go variant),
// but only the first file (regular, not a variant) is returned.
func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile {
filename := file.GeneratedFilenamePrefix + ".pb.go"
g := gen.NewGeneratedFile(filename, file.GoImportPath)
return generateFiles(gen, file)[0]
}

func generateFiles(gen *protogen.Plugin, file *protogen.File) []*protogen.GeneratedFile {
f := newFileInfo(file)
generated := []*protogen.GeneratedFile{
generateOneFile(gen, file, f, ""),
}
if f.APILevel == gofeaturespb.GoFeatures_API_HYBRID {
// Update all APILevel fields to OPAQUE
f.APILevel = gofeaturespb.GoFeatures_API_OPAQUE
for _, msg := range f.Messages {
setToOpaque(msg)
}
generated = append(generated, generateOneFile(gen, file, f, "_protoopaque"))
}
return generated
}

func generateOneFile(gen *protogen.Plugin, file *protogen.File, f *fileInfo, variant string) *protogen.GeneratedFile {
filename := file.GeneratedFilenamePrefix + variant + ".pb.go"
g := gen.NewGeneratedFile(filename, file.GoImportPath)

var packageDoc protogen.Comments
if !gen.InternalStripForEditionsDiff() {
Expand All @@ -84,6 +115,11 @@ func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated

packageDoc = genPackageKnownComment(f)
}
if variant == "_protoopaque" {
g.P("//go:build protoopaque")
} else if f.APILevel == gofeaturespb.GoFeatures_API_HYBRID {
g.P("//go:build !protoopaque")
}
g.P(packageDoc, "package ", f.GoPackageName)
g.P()

Expand Down Expand Up @@ -190,9 +226,11 @@ func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp

// Generate public imports by generating the imported file, parsing it,
// and extracting every symbol that should receive a forwarding declaration.
impGen := GenerateFile(gen, impFile)
impGen.Skip()
b, err := impGen.Content()
impGens := generateFiles(gen, impFile)
for _, impGen := range impGens {
impGen.Skip()
}
b, err := impGens[0].Content()
if err != nil {
gen.Error(err)
return
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b64efdb

Please sign in to comment.