reflect/protoreflect: drop the ProtoEnum type
Drop the protoreflect.ProtoEnum type (containing a single method
returning a protoreflect.Enum) and make generated enum types
directly implement protoreflect.Enum instead.
Messages have a two-level type split (ProtoMessage and Message) to
minimize conflicts between reflection methods and field names. Enums
need no such split, since enums do not have fields and therefore have
no source of conflicts.
Change-Id: I2b6222e9404253e6bfef2217859e1b760ffcd29b
Reviewed-on: https://go-review.googlesource.com/c/156902
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/export.go b/internal/impl/export.go
index 7e2d392..0a153c4 100644
--- a/internal/impl/export.go
+++ b/internal/impl/export.go
@@ -18,8 +18,8 @@
// ProtoReflect method, otherwise it wraps the v1 enum to implement
// the v2 reflective interface.
func (Export) EnumOf(e interface{}) pref.Enum {
- if ev, ok := e.(pref.ProtoEnum); ok {
- return ev.ProtoReflect()
+ if ev, ok := e.(pref.Enum); ok {
+ return ev
}
return legacyWrapper.EnumOf(e)
}
@@ -29,8 +29,8 @@
// calling the ProtoReflect.Type method, otherwise it derives an enum type
// from the v1 named int32 type.
func (Export) EnumTypeOf(e interface{}) pref.EnumType {
- if ev, ok := e.(pref.ProtoEnum); ok {
- return ev.ProtoReflect().Type()
+ if ev, ok := e.(pref.Enum); ok {
+ return ev.Type()
}
return legacyWrapper.EnumTypeOf(e)
}
@@ -67,8 +67,8 @@
switch t := t.(type) {
case nil:
return ptype.GoExtension(d, nil, nil)
- case pref.ProtoEnum:
- return ptype.GoExtension(d, t.ProtoReflect().Type(), nil)
+ case pref.Enum:
+ return ptype.GoExtension(d, t.Type(), nil)
case pref.ProtoMessage:
return ptype.GoExtension(d, nil, t.ProtoReflect().Type())
}
diff --git a/internal/impl/message_test.go b/internal/impl/message_test.go
index 97fbabd..b98fe65 100644
--- a/internal/impl/message_test.go
+++ b/internal/impl/message_test.go
@@ -936,7 +936,7 @@
FullName: "EnumProto2",
Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
}),
- func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
+ func(_ pref.EnumType, n pref.EnumNumber) pref.Enum {
return EnumProto2(n)
},
)
@@ -944,7 +944,6 @@
func (e EnumProto2) Enum() *EnumProto2 { return &e }
func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
-func (e EnumProto2) ProtoReflect() pref.Enum { return e }
type EnumProto3 int32
@@ -954,7 +953,7 @@
FullName: "EnumProto3",
Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
}),
- func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
+ func(_ pref.EnumType, n pref.EnumNumber) pref.Enum {
return EnumProto3(n)
},
)
@@ -962,7 +961,6 @@
func (e EnumProto3) Enum() *EnumProto3 { return &e }
func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
-func (e EnumProto3) ProtoReflect() pref.Enum { return e }
type EnumMessages struct {
EnumP2 *EnumProto2 `protobuf:"1"`
diff --git a/internal/legacy/enum.go b/internal/legacy/enum.go
index e71bc2a..89b5c87 100644
--- a/internal/legacy/enum.go
+++ b/internal/legacy/enum.go
@@ -17,9 +17,9 @@
descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
)
-// wrapEnum wraps v as a protoreflect.ProtoEnum,
+// wrapEnum wraps v as a protoreflect.Enum,
// where v must be a int32 kind and not implement the v2 API already.
-func wrapEnum(v reflect.Value) pref.ProtoEnum {
+func wrapEnum(v reflect.Value) pref.Enum {
et := loadEnumType(v.Type())
return et.New(pref.EnumNumber(v.Int()))
}
@@ -37,9 +37,9 @@
// Slow-path: derive enum descriptor and initialize EnumType.
var m sync.Map // map[protoreflect.EnumNumber]proto.Enum
ed := loadEnumDesc(t)
- et := ptype.GoEnum(ed, func(et pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
+ et := ptype.GoEnum(ed, func(et pref.EnumType, n pref.EnumNumber) pref.Enum {
if e, ok := m.Load(n); ok {
- return e.(pref.ProtoEnum)
+ return e.(pref.Enum)
}
e := &enumWrapper{num: n, pbTyp: et, goTyp: t}
m.Store(n, e)
@@ -72,7 +72,6 @@
var (
_ pref.Enum = (*enumWrapper)(nil)
- _ pref.ProtoEnum = (*enumWrapper)(nil)
_ pvalue.Unwrapper = (*enumWrapper)(nil)
)
@@ -99,7 +98,7 @@
// Derive the enum descriptor from the raw descriptor proto.
e := new(ptype.StandaloneEnum)
ev := reflect.Zero(t).Interface()
- if _, ok := ev.(pref.ProtoEnum); ok {
+ if _, ok := ev.(pref.Enum); ok {
panic(fmt.Sprintf("%v already implements proto.Enum", t))
}
if ed, ok := ev.(enumV1); ok {
diff --git a/internal/legacy/export.go b/internal/legacy/export.go
index f51a33a..c5114f0 100644
--- a/internal/legacy/export.go
+++ b/internal/legacy/export.go
@@ -18,7 +18,7 @@
type Export struct{}
func (Export) EnumOf(e interface{}) pvalue.LegacyEnum {
- return wrapEnum(reflect.ValueOf(e)).ProtoReflect().(pvalue.LegacyEnum)
+ return wrapEnum(reflect.ValueOf(e)).(pvalue.LegacyEnum)
}
func (Export) EnumTypeOf(e interface{}) pref.EnumType {
diff --git a/internal/legacy/message.go b/internal/legacy/message.go
index f4b358f..5158374 100644
--- a/internal/legacy/message.go
+++ b/internal/legacy/message.go
@@ -219,8 +219,8 @@
// Populate EnumType and MessageType.
if f.EnumType == nil && f.Kind == pref.EnumKind {
- if ev, ok := reflect.Zero(t).Interface().(pref.ProtoEnum); ok {
- f.EnumType = ev.ProtoReflect().Type()
+ if ev, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
+ f.EnumType = ev.Type()
} else {
f.EnumType = loadEnumDesc(t)
}
diff --git a/internal/testprotos/test/test.pb.go b/internal/testprotos/test/test.pb.go
index f1a3ce3..bb71643 100644
--- a/internal/testprotos/test/test.pb.go
+++ b/internal/testprotos/test/test.pb.go
@@ -25,15 +25,10 @@
TestAllTypes_NEG TestAllTypes_NestedEnum = -1
)
-type xxx_TestAllTypes_NestedEnum TestAllTypes_NestedEnum
-
-func (e TestAllTypes_NestedEnum) ProtoReflect() protoreflect.Enum {
- return (xxx_TestAllTypes_NestedEnum)(e)
-}
-func (e xxx_TestAllTypes_NestedEnum) Type() protoreflect.EnumType {
+func (e TestAllTypes_NestedEnum) Type() protoreflect.EnumType {
return xxx_Test_ProtoFile_EnumTypes[0]
}
-func (e xxx_TestAllTypes_NestedEnum) Number() protoreflect.EnumNumber {
+func (e TestAllTypes_NestedEnum) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(e)
}
@@ -1622,7 +1617,7 @@
var xxx_Test_ProtoFile_EnumTypes = [1]protoreflect.EnumType{
prototype.GoEnum(
xxx_Test_ProtoFile_EnumDescs[0].Reference(),
- func(_ protoreflect.EnumType, n protoreflect.EnumNumber) protoreflect.ProtoEnum {
+ func(_ protoreflect.EnumType, n protoreflect.EnumNumber) protoreflect.Enum {
return TestAllTypes_NestedEnum(n)
},
),
diff --git a/internal/value/convert.go b/internal/value/convert.go
index 1722d01..9e40ac2 100644
--- a/internal/value/convert.go
+++ b/internal/value/convert.go
@@ -31,7 +31,7 @@
stringType = reflect.TypeOf(string(""))
bytesType = reflect.TypeOf([]byte(nil))
- enumIfaceV2 = reflect.TypeOf((*pref.ProtoEnum)(nil)).Elem()
+ enumIfaceV2 = reflect.TypeOf((*pref.Enum)(nil)).Elem()
messageIfaceV1 = reflect.TypeOf((*papi.Message)(nil)).Elem()
messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
@@ -122,14 +122,14 @@
case pref.EnumKind:
// Handle v2 enums, which must satisfy the proto.Enum interface.
if t.Kind() != reflect.Ptr && t.Implements(enumIfaceV2) {
- et := reflect.Zero(t).Interface().(pref.ProtoEnum).ProtoReflect().Type()
+ et := reflect.Zero(t).Interface().(pref.Enum).Type()
return Converter{
PBValueOf: func(v reflect.Value) pref.Value {
if v.Type() != t {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
}
- e := v.Interface().(pref.ProtoEnum)
- return pref.ValueOf(e.ProtoReflect().Number())
+ e := v.Interface().(pref.Enum)
+ return pref.ValueOf(e.Number())
},
GoValueOf: func(v pref.Value) reflect.Value {
rv := reflect.ValueOf(et.New(v.Enum()))