Browse Source

goprotobuf: Fix proto.Clone handling of extensions.

R=r
CC=golang-dev
http://codereview.appspot.com/5093043
David Symonds 14 years ago
parent
commit
6342980a3a
2 changed files with 16 additions and 5 deletions
  1. 6 5
      proto/clone.go
  2. 10 0
      proto/clone_test.go

+ 6 - 5
proto/clone.go

@@ -62,9 +62,9 @@ func copyStruct(out, in reflect.Value) {
 		copyAny(out.Field(i), in.Field(i))
 	}
 
-	if emIn := in.FieldByName("XXX_extensions"); emIn.IsValid() {
-		emOut := out.FieldByName("XXX_extensions")
-		copyExtension(emOut.Interface().(map[int32]Extension), emIn.Interface().(map[int32]Extension))
+	if emIn, ok := in.Addr().Interface().(extendableProto); ok {
+		emOut := out.Addr().Interface().(extendableProto)
+		copyExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
 	}
 
 	// TODO: Deal with XXX_unrecognized.
@@ -108,8 +108,9 @@ func copyExtension(out, in map[int32]Extension) {
 	for extNum, eIn := range in {
 		eOut := Extension{desc: eIn.desc}
 		if eIn.value != nil {
-			eOut.value = reflect.Zero(reflect.TypeOf(eIn.value))
-			copyAny(reflect.ValueOf(eOut.value), reflect.ValueOf(eIn.value))
+			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
+			copyAny(v, reflect.ValueOf(eIn.value))
+			eOut.value = v.Interface()
 		}
 		if eIn.enc != nil {
 			eOut.enc = make([]byte, len(eIn.enc))

+ 10 - 0
proto/clone_test.go

@@ -32,6 +32,7 @@
 package proto_test
 
 import (
+	"log"
 	"testing"
 
 	"goprotobuf.googlecode.com/hg/proto"
@@ -56,6 +57,15 @@ var cloneTestMessage = &pb.MyMessage{
 	RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
 }
 
+func init() {
+	ext := &pb.Ext{
+		Data: proto.String("extension"),
+	}
+	if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil {
+		log.Fatalf("SetExtension: %v", err)
+	}
+}
+
 func TestClone(t *testing.T) {
 	m := proto.Clone(cloneTestMessage).(*pb.MyMessage)
 	if !proto.Equal(m, cloneTestMessage) {