types/dynamicpb: add NewEnumType

Add support for creating dynamic EnumTypes.

Change-Id: Ic9f5b73630734848b29cc436f6c179549a8ea74a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/237219
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Joe Tsai <joetsai@google.com>
This commit is contained in:
Damien Neil 2020-06-09 15:12:34 -07:00
parent f49fd502d3
commit 7e8b902d03
3 changed files with 76 additions and 5 deletions

33
testing/prototest/enum.go Normal file
View File

@ -0,0 +1,33 @@
// Copyright 2020 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 prototest
import (
"testing"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
// Enum tests an EnumType implementation.
type Enum struct{}
func (test Enum) Test(t testing.TB, et pref.EnumType) {
ed := et.Descriptor()
values := ed.Values()
for i := 0; i < values.Len(); i++ {
evd := values.Get(i)
num := evd.Number()
e := et.New(num)
if e.Descriptor() != ed {
t.Errorf("enumType.New(%v).Descriptor() != enumType.Descriptor(), should match", num)
}
if e.Type() != et {
t.Errorf("enumType.New(%v).Type() != enumType, should match", num)
}
if got, want := e.Number(), num; got != want {
t.Errorf("enumType.New(%v).Number() = %v, want %v", num, got, want)
}
}
}

View File

@ -14,6 +14,39 @@ import (
"google.golang.org/protobuf/runtime/protoimpl"
)
// enum is a dynamic protoreflect.Enum.
type enum struct {
num pref.EnumNumber
typ pref.EnumType
}
func (e enum) Descriptor() pref.EnumDescriptor { return e.typ.Descriptor() }
func (e enum) Type() pref.EnumType { return e.typ }
func (e enum) Number() pref.EnumNumber { return e.num }
// enumType is a dynamic protoreflect.EnumType.
type enumType struct {
desc pref.EnumDescriptor
}
// NewEnumType creates a new EnumType with the provided descriptor.
//
// EnumTypes created by this package are equal if their descriptors are equal.
// That is, if ed1 == ed2, then NewEnumType(ed1) == NewEnumType(ed2).
//
// Enum values created by the EnumType are equal if their numbers are equal.
func NewEnumType(desc pref.EnumDescriptor) pref.EnumType {
return enumType{desc}
}
func (et enumType) New(n pref.EnumNumber) pref.Enum { return enum{n, et} }
func (et enumType) Descriptor() pref.EnumDescriptor { return et.desc }
// extensionType is a dynamic protoreflect.ExtensionType.
type extensionType struct {
desc extensionTypeDescriptor
}
// A Message is a dynamically constructed protocol buffer message.
//
// Message implements the proto.Message interface, and may be used with all
@ -577,11 +610,6 @@ func newListEntry(fd pref.FieldDescriptor) pref.Value {
panic(errors.New("%v: unknown kind %v", fd.FullName(), fd.Kind()))
}
// extensionType is a dynamic protoreflect.ExtensionType.
type extensionType struct {
desc extensionTypeDescriptor
}
// NewExtensionType creates a new ExtensionType with the provided descriptor.
//
// Dynamic ExtensionTypes with the same descriptor compare as equal. That is,

View File

@ -39,6 +39,16 @@ func TestDynamicExtensions(t *testing.T) {
}
}
func TestDynamicEnums(t *testing.T) {
for _, enum := range []pref.Enum{
testpb.TestAllTypes_FOO,
test3pb.TestAllTypes_FOO,
} {
et := dynamicpb.NewEnumType(enum.Descriptor())
prototest.Enum{}.Test(t, et)
}
}
type extResolver struct{}
func (extResolver) FindExtensionByName(field pref.FullName) (pref.ExtensionType, error) {