protobuf: fix required/group bug in descriptor proto output of editions files
These need to be converted back to the appropriate label/type enums to produce valid descriptor protos under editions.
Change-Id: Ife04c4c556ffb06d1bc477725ff49058928a75ca
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/575916
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Stapelberg <stapelberg@google.com>
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
diff --git a/internal/filedesc/desc.go b/internal/filedesc/desc.go
index f09f734..55b5de1 100644
--- a/internal/filedesc/desc.go
+++ b/internal/filedesc/desc.go
@@ -538,8 +538,9 @@
// Surrogate files are can be used to create standalone descriptors
// where the syntax is only information derived from the parent file.
var (
- SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
- SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
+ SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
+ SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
+ SurrogateEdition2023 = &File{L1: FileL1{Syntax: protoreflect.Editions, Edition: Edition2023}, L2: &FileL2{}}
)
type (
diff --git a/internal/filedesc/editions.go b/internal/filedesc/editions.go
index 5f01803..d1e16a2 100644
--- a/internal/filedesc/editions.go
+++ b/internal/filedesc/editions.go
@@ -20,6 +20,7 @@
unmarshalEditionDefaults(editiondefaults.Defaults)
SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2)
SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3)
+ SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023)
}
func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
diff --git a/reflect/protodesc/proto.go b/reflect/protodesc/proto.go
index 7aa21be..a5de8d4 100644
--- a/reflect/protodesc/proto.go
+++ b/reflect/protodesc/proto.go
@@ -163,6 +163,18 @@
if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
p.Proto3Optional = proto.Bool(true)
}
+ if field.Syntax() == protoreflect.Editions {
+ // Editions have no group keyword, this type is only set so that downstream users continue
+ // treating this as delimited encoding.
+ if p.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP {
+ p.Type = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum()
+ }
+ // Editions have no required keyword, this label is only set so that downstream users continue
+ // treating it as required.
+ if p.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REQUIRED {
+ p.Label = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()
+ }
+ }
if field.HasDefault() {
def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
if err != nil && field.DefaultEnumValue() != nil {
diff --git a/reflect/protodesc/proto_test.go b/reflect/protodesc/proto_test.go
new file mode 100644
index 0000000..ec09123
--- /dev/null
+++ b/reflect/protodesc/proto_test.go
@@ -0,0 +1,110 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protodesc
+
+import (
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ "google.golang.org/protobuf/internal/filedesc"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/testing/protocmp"
+ "google.golang.org/protobuf/types/descriptorpb"
+)
+
+func TestEditionsRequired(t *testing.T) {
+ fd := new(filedesc.Field)
+ fd.L0.ParentFile = filedesc.SurrogateEdition2023
+ fd.L0.FullName = "foo_field"
+ fd.L1.Number = 1337
+ fd.L1.Cardinality = protoreflect.Required
+ fd.L1.Kind = protoreflect.BytesKind
+
+ want := &descriptorpb.FieldDescriptorProto{
+ Name: proto.String("foo_field"),
+ Number: proto.Int32(1337),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(),
+ }
+
+ got := ToFieldDescriptorProto(fd)
+ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
+ t.Errorf("ToFieldDescriptor: unexpected diff (-want +got):\n%s", diff)
+ }
+}
+
+func TestProto2Required(t *testing.T) {
+ fd := new(filedesc.Field)
+ fd.L0.ParentFile = filedesc.SurrogateProto2
+ fd.L0.FullName = "foo_field"
+ fd.L1.Number = 1337
+ fd.L1.Cardinality = protoreflect.Required
+ fd.L1.Kind = protoreflect.BytesKind
+
+ want := &descriptorpb.FieldDescriptorProto{
+ Name: proto.String("foo_field"),
+ Number: proto.Int32(1337),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(),
+ }
+
+ got := ToFieldDescriptorProto(fd)
+ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
+ t.Errorf("ToFieldDescriptor: unexpected diff (-want +got):\n%s", diff)
+ }
+}
+
+func TestEditionsDelimited(t *testing.T) {
+ md := new(filedesc.Message)
+ md.L0.ParentFile = filedesc.SurrogateEdition2023
+ md.L0.FullName = "foo_message"
+ fd := new(filedesc.Field)
+ fd.L0.ParentFile = filedesc.SurrogateEdition2023
+ fd.L0.FullName = "foo_field"
+ fd.L1.Number = 1337
+ fd.L1.Cardinality = protoreflect.Optional
+ fd.L1.Kind = protoreflect.GroupKind
+ fd.L1.Message = md
+
+ want := &descriptorpb.FieldDescriptorProto{
+ Name: proto.String("foo_field"),
+ Number: proto.Int32(1337),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
+ TypeName: proto.String(".foo_message"),
+ }
+
+ got := ToFieldDescriptorProto(fd)
+ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
+ t.Errorf("ToFieldDescriptor: unexpected diff (-want +got):\n%s", diff)
+ }
+}
+
+func TestProto2Group(t *testing.T) {
+ md := new(filedesc.Message)
+ md.L0.ParentFile = filedesc.SurrogateProto2
+ md.L0.FullName = "foo_message"
+ fd := new(filedesc.Field)
+ fd.L0.ParentFile = filedesc.SurrogateProto2
+ fd.L0.FullName = "foo_field"
+ fd.L1.Number = 1337
+ fd.L1.Cardinality = protoreflect.Optional
+ fd.L1.Kind = protoreflect.GroupKind
+ fd.L1.Message = md
+
+ want := &descriptorpb.FieldDescriptorProto{
+ Name: proto.String("foo_field"),
+ Number: proto.Int32(1337),
+ Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
+ Type: descriptorpb.FieldDescriptorProto_TYPE_GROUP.Enum(),
+ TypeName: proto.String(".foo_message"),
+ }
+
+ got := ToFieldDescriptorProto(fd)
+ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
+ t.Errorf("ToFieldDescriptor: unexpected diff (-want +got):\n%s", diff)
+ }
+}