all: use v2 Message interface for weak fields
Cleanup the generated logic by having the implementation be backed
by protoimpl rather that directly generated.
Weak fields are a deprecated feature of protobufs and
have entirely be superceded by extensions.
Unfortunately, there are still some usages of it.
Change-Id: Ie1a4b7da253e2ccf5e56627775d9b2fb4090d59a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/229717
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/weak.go b/internal/impl/weak.go
index 575c988..009cbef 100644
--- a/internal/impl/weak.go
+++ b/internal/impl/weak.go
@@ -5,9 +5,10 @@
package impl
import (
- "reflect"
+ "fmt"
pref "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/reflect/protoregistry"
)
// weakFields adds methods to the exported WeakFields type for internal use.
@@ -16,31 +17,58 @@
// defined directly on it.
type weakFields WeakFields
-func (w *weakFields) get(num pref.FieldNumber) (_ pref.ProtoMessage, ok bool) {
- if *w == nil {
- return nil, false
- }
- m, ok := (*w)[int32(num)]
- if !ok {
- return nil, false
- }
- // As a legacy quirk, consider a typed nil to be unset.
- //
- // TODO: Consider fixing the generated set methods to clear the field
- // when provided with a typed nil.
- if v := reflect.ValueOf(m); v.Kind() == reflect.Ptr && v.IsNil() {
- return nil, false
- }
- return Export{}.ProtoMessageV2Of(m), true
+func (w weakFields) get(num pref.FieldNumber) (pref.ProtoMessage, bool) {
+ m, ok := w[int32(num)]
+ return m, ok
}
func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) {
if *w == nil {
*w = make(weakFields)
}
- (*w)[int32(num)] = Export{}.ProtoMessageV1Of(m)
+ (*w)[int32(num)] = m
}
func (w *weakFields) clear(num pref.FieldNumber) {
delete(*w, int32(num))
}
+
+func (Export) HasWeak(w WeakFields, num pref.FieldNumber) bool {
+ _, ok := w[int32(num)]
+ return ok
+}
+
+func (Export) ClearWeak(w *WeakFields, num pref.FieldNumber) {
+ delete(*w, int32(num))
+}
+
+func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pref.ProtoMessage {
+ if m, ok := w[int32(num)]; ok {
+ return m
+ }
+ mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+ if mt == nil {
+ panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+ }
+ return mt.Zero().Interface()
+}
+
+func (Export) SetWeak(w *WeakFields, num pref.FieldNumber, name pref.FullName, m pref.ProtoMessage) {
+ if m != nil {
+ mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+ if mt == nil {
+ panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+ }
+ if mt != m.ProtoReflect().Type() {
+ panic(fmt.Sprintf("invalid message type for weak field: got %T, want %T", m, mt.Zero().Interface()))
+ }
+ }
+ if m == nil || !m.ProtoReflect().IsValid() {
+ delete(*w, int32(num))
+ return
+ }
+ if *w == nil {
+ *w = make(weakFields)
+ }
+ (*w)[int32(num)] = m
+}