瀏覽代碼

reflect: switch ExtensionType.New to return Value

This change preserves consistency with CL/157077,
where New returns a value closer to the reflective type.

Change-Id: I85bfdae24e1ce1a10c3c7b939420fa1043bff743
Reviewed-on: https://go-review.googlesource.com/c/157078
Reviewed-by: Damien Neil <dneil@google.com>
Joe Tsai 7 年之前
父節點
當前提交
d18bd31838
共有 4 個文件被更改,包括 25 次插入23 次删除
  1. 2 2
      internal/impl/legacy_extension.go
  2. 7 6
      internal/legacy/extension.go
  3. 2 3
      reflect/protoreflect/type.go
  4. 14 12
      reflect/prototype/go_type.go

+ 2 - 2
internal/impl/legacy_extension.go

@@ -133,7 +133,7 @@ func (p legacyExtensionFields) NewMessage(n pref.FieldNumber) pref.Message {
 		panic("no extension descriptor registered")
 	}
 	xt := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
-	return xt.ValueOf(xt.New()).Message()
+	return xt.New().Message()
 }
 
 func (p legacyExtensionFields) ExtensionTypes() pref.ExtensionFieldTypes {
@@ -167,7 +167,7 @@ func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
 	if t.Cardinality() == pref.Repeated {
 		// If the field is repeated, initialize the entry with an empty list
 		// so that future Get operations can return a mutable and concrete list.
-		x.Value = t.InterfaceOf(t.ValueOf(t.New()))
+		x.Value = t.InterfaceOf(t.New())
 	}
 	p.x.Set(t.Number(), x)
 }

+ 7 - 6
internal/legacy/extension.go

@@ -204,8 +204,8 @@ func extensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 	xt2 := &extensionType{ExtensionType: xt}
 	if xd.Cardinality() != pref.Repeated {
 		xt2.typ = t
-		xt2.new = func() interface{} {
-			return xt.New().(pvalue.Unwrapper).ProtoUnwrap()
+		xt2.new = func() pref.Value {
+			return xt.New()
 		}
 		xt2.valueOf = func(v interface{}) pref.Value {
 			if reflect.TypeOf(v) != xt2.typ {
@@ -222,8 +222,9 @@ func extensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 		}
 	} else {
 		xt2.typ = reflect.PtrTo(reflect.SliceOf(t))
-		xt2.new = func() interface{} {
-			return reflect.New(xt2.typ.Elem()).Interface()
+		xt2.new = func() pref.Value {
+			v := reflect.New(xt2.typ.Elem()).Interface()
+			return pref.ValueOf(pvalue.ListOf(v, conv))
 		}
 		xt2.valueOf = func(v interface{}) pref.Value {
 			if reflect.TypeOf(v) != xt2.typ {
@@ -245,13 +246,13 @@ func extensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension
 type extensionType struct {
 	pref.ExtensionType
 	typ         reflect.Type
-	new         func() interface{}
+	new         func() pref.Value
 	valueOf     func(interface{}) pref.Value
 	interfaceOf func(pref.Value) interface{}
 }
 
 func (x *extensionType) GoType() reflect.Type                 { return x.typ }
-func (x *extensionType) New() interface{}                     { return x.new() }
+func (x *extensionType) New() pref.Value                      { return x.new() }
 func (x *extensionType) ValueOf(v interface{}) pref.Value     { return x.valueOf(v) }
 func (x *extensionType) InterfaceOf(v pref.Value) interface{} { return x.interfaceOf(v) }
 func (x *extensionType) Format(s fmt.State, r rune)           { pfmt.FormatDesc(s, r, x) }

+ 2 - 3
reflect/protoreflect/type.go

@@ -415,13 +415,12 @@ type ExtensionType interface {
 
 	// New returns a new value for the field.
 	// For scalars, this returns the default value in native Go form.
-	New() interface{}
+	New() Value
 
 	// GoType returns the Go type of the field value.
 	//
 	// Invariants:
-	//	t.GoType() == reflect.TypeOf(t.New())
-	//	t.GoType() == reflect.TypeOf(t.InterfaceOf(t.ValueOf(t.New())))
+	//	t.GoType() == reflect.TypeOf(t.InterfaceOf(t.New()))
 	GoType() reflect.Type
 
 	// TODO: What to do with nil?

+ 14 - 12
reflect/prototype/go_type.go

@@ -157,7 +157,7 @@ type goExtension struct {
 
 	once        sync.Once
 	typ         reflect.Type
-	new         func() interface{}
+	new         func() protoreflect.Value
 	valueOf     func(v interface{}) protoreflect.Value
 	interfaceOf func(v protoreflect.Value) interface{}
 }
@@ -172,13 +172,14 @@ func (t *goExtension) GoType() reflect.Type {
 	t.lazyInit()
 	return t.typ
 }
-func (t *goExtension) New() interface{} {
+func (t *goExtension) New() protoreflect.Value {
 	t.lazyInit()
-	v := t.new()
+	pv := t.new()
+	v := t.interfaceOf(pv)
 	if reflect.TypeOf(v) != t.typ {
 		panic(fmt.Sprintf("invalid type: got %T, want %v", v, t.typ))
 	}
-	return v
+	return pv
 }
 func (t *goExtension) ValueOf(v interface{}) protoreflect.Value {
 	t.lazyInit()
@@ -205,8 +206,8 @@ func (t *goExtension) lazyInit() {
 			switch t.Kind() {
 			case protoreflect.EnumKind:
 				t.typ = t.enumType.GoType()
-				t.new = func() interface{} {
-					return t.enumType.New(t.Default().Enum())
+				t.new = func() protoreflect.Value {
+					return t.Default()
 				}
 				t.valueOf = func(v interface{}) protoreflect.Value {
 					ev := v.(protoreflect.Enum)
@@ -217,8 +218,8 @@ func (t *goExtension) lazyInit() {
 				}
 			case protoreflect.MessageKind, protoreflect.GroupKind:
 				t.typ = t.messageType.GoType()
-				t.new = func() interface{} {
-					return t.messageType.New().Interface()
+				t.new = func() protoreflect.Value {
+					return protoreflect.ValueOf(t.messageType.New())
 				}
 				t.valueOf = func(v interface{}) protoreflect.Value {
 					mv := v.(protoreflect.ProtoMessage).ProtoReflect()
@@ -229,8 +230,8 @@ func (t *goExtension) lazyInit() {
 				}
 			default:
 				t.typ = goTypeForPBKind[t.Kind()]
-				t.new = func() interface{} {
-					return t.Default().Interface()
+				t.new = func() protoreflect.Value {
+					return t.Default()
 				}
 				t.valueOf = func(v interface{}) protoreflect.Value {
 					return protoreflect.ValueOf(v)
@@ -251,8 +252,9 @@ func (t *goExtension) lazyInit() {
 			}
 			c := value.NewConverter(typ, t.Kind())
 			t.typ = reflect.PtrTo(reflect.SliceOf(typ))
-			t.new = func() interface{} {
-				return reflect.New(t.typ.Elem()).Interface()
+			t.new = func() protoreflect.Value {
+				v := reflect.New(t.typ.Elem()).Interface()
+				return protoreflect.ValueOf(value.ListOf(v, c))
 			}
 			t.valueOf = func(v interface{}) protoreflect.Value {
 				return protoreflect.ValueOf(value.ListOf(v, c))