all: refactor extensions, add proto.GetExtension etc.
Change protoiface.ExtensionDescV1 to implement protoreflect.ExtensionType.
ExtensionDescV1's Name field conflicts with the Descriptor Name method,
so change the protoreflect.{Message,Enum,Extension}Type types to no
longer implement the corresponding Descriptor interface. This also leads
to a clearer distinction between the two types.
Introduce a protoreflect.ExtensionTypeDescriptor type which bridges
between ExtensionType and ExtensionDescriptor.
Add extension accessor functions to the proto package:
proto.{Has,Clear,Get,Set}Extension. These functions take a
protoreflect.ExtensionType parameter, which allows writing the
same function call using either the old or new API:
proto.GetExtension(message, somepb.E_ExtensionFoo)
Fixes golang/protobuf#908
Change-Id: Ibc65d12a46666297849114fd3aefbc4a597d9f08
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189199
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/proto/extension.go b/proto/extension.go
new file mode 100644
index 0000000..2e1c78f
--- /dev/null
+++ b/proto/extension.go
@@ -0,0 +1,33 @@
+// Copyright 2019 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 proto
+
+import (
+ "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// HasExtension reports whether an extension field is populated.
+func HasExtension(m Message, ext protoreflect.ExtensionType) bool {
+ return m.ProtoReflect().Has(ext.Descriptor())
+}
+
+// ClearExtension clears an extension field such that subsequent
+// HasExtension calls return false.
+func ClearExtension(m Message, ext protoreflect.ExtensionType) {
+ m.ProtoReflect().Clear(ext.Descriptor())
+}
+
+// GetExtension retrieves the value for an extension field.
+//
+// If the field is unpopulated, it returns the default value for
+// scalars and an immutable, empty value for lists, maps, or messages.
+func GetExtension(m Message, ext protoreflect.ExtensionType) interface{} {
+ return ext.InterfaceOf(m.ProtoReflect().Get(ext.Descriptor()))
+}
+
+// SetExtension stores the value of an extension field.
+func SetExtension(m Message, ext protoreflect.ExtensionType, value interface{}) {
+ m.ProtoReflect().Set(ext.Descriptor(), ext.ValueOf(value))
+}