Explorar o código

internal/impl: split messageWrapper into different types

The previous implementation of messageWrapper implemented both
proto.Message and protoreflect.Message. This made it possible for users
to accidentally rely on this fact when it was actually an internal
implementation detail.

To avoid this, we split the wrapper type into two, ensuring that each
only implements one or the other. Doing so also revealed bugs in our
own code where we accidentally relied on this fact.

Change-Id: I0ff521b5c806b7dcb0b86942bd97e8319d8e8657
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/166938
Reviewed-by: Damien Neil <dneil@google.com>
Joe Tsai %!s(int64=6) %!d(string=hai) anos
pai
achega
22b1ebd068
Modificáronse 2 ficheiros con 20 adicións e 14 borrados
  1. 19 13
      internal/impl/message.go
  2. 1 1
      internal/legacy/extension.go

+ 19 - 13
internal/impl/message.go

@@ -145,7 +145,7 @@ func (mi *MessageType) makeExtensionFieldsFunc(t reflect.Type) {
 }
 }
 
 
 func (mi *MessageType) MessageOf(p interface{}) pref.Message {
 func (mi *MessageType) MessageOf(p interface{}) pref.Message {
-	return (*messageWrapper)(mi.dataTypeOf(p))
+	return (*messageReflectWrapper)(mi.dataTypeOf(p))
 }
 }
 
 
 func (mi *MessageType) dataTypeOf(p interface{}) *messageDataType {
 func (mi *MessageType) dataTypeOf(p interface{}) *messageDataType {
@@ -182,34 +182,40 @@ type messageDataType struct {
 	mi *MessageType
 	mi *MessageType
 }
 }
 
 
-type messageWrapper messageDataType
+type messageReflectWrapper messageDataType
 
 
-func (m *messageWrapper) Type() pref.MessageType {
+func (m *messageReflectWrapper) Type() pref.MessageType {
 	return m.mi.PBType
 	return m.mi.PBType
 }
 }
-func (m *messageWrapper) KnownFields() pref.KnownFields {
+func (m *messageReflectWrapper) KnownFields() pref.KnownFields {
 	m.mi.init()
 	m.mi.init()
 	return (*knownFields)(m)
 	return (*knownFields)(m)
 }
 }
-func (m *messageWrapper) UnknownFields() pref.UnknownFields {
+func (m *messageReflectWrapper) UnknownFields() pref.UnknownFields {
 	m.mi.init()
 	m.mi.init()
 	return m.mi.unknownFields((*messageDataType)(m))
 	return m.mi.unknownFields((*messageDataType)(m))
 }
 }
-func (m *messageWrapper) Interface() pref.ProtoMessage {
+func (m *messageReflectWrapper) Interface() pref.ProtoMessage {
 	if m, ok := m.ProtoUnwrap().(pref.ProtoMessage); ok {
 	if m, ok := m.ProtoUnwrap().(pref.ProtoMessage); ok {
 		return m
 		return m
 	}
 	}
-	return m
+	return (*messageIfaceWrapper)(m)
 }
 }
-func (m *messageWrapper) ProtoReflect() pref.Message {
-	return m
-}
-func (m *messageWrapper) ProtoUnwrap() interface{} {
+func (m *messageReflectWrapper) ProtoUnwrap() interface{} {
 	return m.p.AsIfaceOf(m.mi.GoType.Elem())
 	return m.p.AsIfaceOf(m.mi.GoType.Elem())
 }
 }
-func (m *messageWrapper) ProtoMutable() {}
+func (m *messageReflectWrapper) ProtoMutable() {}
+
+var _ pvalue.Unwrapper = (*messageReflectWrapper)(nil)
+
+type messageIfaceWrapper messageDataType
 
 
-var _ pvalue.Unwrapper = (*messageWrapper)(nil)
+func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
+	return (*messageReflectWrapper)(m)
+}
+func (m *messageIfaceWrapper) ProtoUnwrap() interface{} {
+	return m.p.AsIfaceOf(m.mi.GoType.Elem())
+}
 
 
 type knownFields messageDataType
 type knownFields messageDataType
 
 

+ 1 - 1
internal/legacy/extension.go

@@ -214,7 +214,7 @@ func extensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 			if xd.Kind() == pref.EnumKind {
 			if xd.Kind() == pref.EnumKind {
 				return xt.ValueOf(Export{}.EnumOf(v))
 				return xt.ValueOf(Export{}.EnumOf(v))
 			} else {
 			} else {
-				return xt.ValueOf(Export{}.MessageOf(v))
+				return xt.ValueOf(Export{}.MessageOf(v).Interface())
 			}
 			}
 		}
 		}
 		xt2.interfaceOf = func(v pref.Value) interface{} {
 		xt2.interfaceOf = func(v pref.Value) interface{} {