From 21ade498bd69f3dba478aaeb26fc12f0f64d37c6 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Wed, 22 May 2019 13:42:54 -0400 Subject: [PATCH] internal/impl: move legacy files into impl The internal/legacy package was originally separated out from internal/impl to avoid a cyclic dependency on descriptor proto. However, the dependency that legacy has on descriptor has long been dropped such that we can now merge the two packages together again. All legacy related logic are in a file with a legacy prefix. Change-Id: I2424fc0f50721696ad06fa7cebb9bdd0babea13c Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/178542 Reviewed-by: Damien Neil --- internal/impl/{export.go => api_export.go} | 23 +- internal/impl/encode_field.go | 8 +- .../{legacy/enum.go => impl/legacy_enum.go} | 58 ++--- .../extension.go => impl/legacy_extension.go} | 66 +++--- .../legacy_extension_test.go} | 33 ++- .../{legacy/file.go => impl/legacy_file.go} | 18 +- .../file_test.go => impl/legacy_file_test.go} | 212 +++++++++--------- internal/impl/legacy_hook.go | 42 ---- .../message.go => impl/legacy_message.go} | 77 +++---- .../{legacy/parse.go => impl/legacy_parse.go} | 80 +++---- internal/impl/legacy_test.go | 165 ++++++++++---- internal/impl/message_field.go | 64 +++++- internal/impl/message_field_extension.go | 4 +- internal/legacy/export.go | 110 --------- internal/legacy/legacy_test.go | 97 -------- runtime/protolegacy/legacy.go | 14 +- 16 files changed, 475 insertions(+), 596 deletions(-) rename internal/impl/{export.go => api_export.go} (78%) rename internal/{legacy/enum.go => impl/legacy_enum.go} (72%) rename internal/{legacy/extension.go => impl/legacy_extension.go} (78%) rename internal/{legacy/extension_test.go => impl/legacy_extension_test.go} (64%) rename internal/{legacy/file.go => impl/legacy_file.go} (75%) rename internal/{legacy/file_test.go => impl/legacy_file_test.go} (61%) delete mode 100644 internal/impl/legacy_hook.go rename internal/{legacy/message.go => impl/legacy_message.go} (80%) rename internal/{legacy/parse.go => impl/legacy_parse.go} (59%) delete mode 100644 internal/legacy/export.go delete mode 100644 internal/legacy/legacy_test.go diff --git a/internal/impl/export.go b/internal/impl/api_export.go similarity index 78% rename from internal/impl/export.go rename to internal/impl/api_export.go index 8c7c1213..d031d17a 100644 --- a/internal/impl/export.go +++ b/internal/impl/api_export.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/encoding/prototext" pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/prototype" + piface "google.golang.org/protobuf/runtime/protoiface" ) // Export is a zero-length named type that exists only to export a set of @@ -26,7 +27,7 @@ func (Export) EnumOf(e enum) pref.Enum { if ev, ok := e.(pref.Enum); ok { return ev } - return legacyWrapper.EnumOf(e) + return legacyWrapEnum(reflect.ValueOf(e)) } // EnumTypeOf returns the protoreflect.EnumType for e. @@ -39,7 +40,7 @@ func (Export) EnumTypeOf(e enum) pref.EnumType { }, } } - return legacyWrapper.EnumTypeOf(e) + return legacyLoadEnumType(reflect.TypeOf(e)) } // EnumDescriptorOf returns the protoreflect.EnumDescriptor for e. @@ -47,7 +48,7 @@ func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor { if ev, ok := e.(pref.Enum); ok { return ev.Descriptor() } - return legacyWrapper.EnumDescriptorOf(e) + return LegacyLoadEnumDesc(reflect.TypeOf(e)) } // EnumStringOf returns the enum value as a string, either as the name if @@ -69,7 +70,7 @@ func (Export) MessageOf(m message) pref.Message { if mv, ok := m.(pref.ProtoMessage); ok { return mv.ProtoReflect() } - return legacyWrapper.MessageOf(m) + return legacyWrapMessage(reflect.ValueOf(m)).ProtoReflect() } // MessageTypeOf returns the protoreflect.MessageType for m. @@ -82,7 +83,7 @@ func (Export) MessageTypeOf(m message) pref.MessageType { }, } } - return legacyWrapper.MessageTypeOf(m) + return legacyLoadMessageInfo(reflect.TypeOf(m)).PBType } // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m. @@ -90,7 +91,7 @@ func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor { if mv, ok := m.(pref.ProtoMessage); ok { return mv.ProtoReflect().Descriptor() } - return legacyWrapper.MessageDescriptorOf(m) + return LegacyLoadMessageDesc(reflect.TypeOf(m)) } // MessageStringOf returns the message value as a string, @@ -99,3 +100,13 @@ func (Export) MessageStringOf(m pref.ProtoMessage) string { b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m) return string(b) } + +// ExtensionDescFromType returns the legacy protoiface.ExtensionDescV1 for t. +func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 { + return legacyExtensionDescFromType(t) +} + +// ExtensionTypeFromDesc returns the v2 protoreflect.ExtensionType for d. +func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { + return legacyExtensionTypeFromDesc(d) +} diff --git a/internal/impl/encode_field.go b/internal/impl/encode_field.go index 2e4884d4..53a8edac 100644 --- a/internal/impl/encode_field.go +++ b/internal/impl/encode_field.go @@ -82,11 +82,11 @@ func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCode } else { return pointerCoderFuncs{ size: func(p pointer, tagsize int, opts marshalOptions) int { - m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface() + m := legacyWrapMessage(p.AsValueOf(ft).Elem()) return sizeMessage(m, tagsize, opts) }, marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { - m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface() + m := legacyWrapMessage(p.AsValueOf(ft).Elem()) return appendMessage(b, m, wiretag, opts) }, } @@ -141,11 +141,11 @@ func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderF } else { return pointerCoderFuncs{ size: func(p pointer, tagsize int, opts marshalOptions) int { - m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface() + m := legacyWrapMessage(p.AsValueOf(ft).Elem()) return sizeGroup(m, tagsize, opts) }, marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) { - m := legacyWrapper.MessageOf(p.AsValueOf(ft).Elem().Interface()).Interface() + m := legacyWrapMessage(p.AsValueOf(ft).Elem()) return appendGroup(b, m, wiretag, opts) }, } diff --git a/internal/legacy/enum.go b/internal/impl/legacy_enum.go similarity index 72% rename from internal/legacy/enum.go rename to internal/impl/legacy_enum.go index d38aa8cd..7aa8b840 100644 --- a/internal/legacy/enum.go +++ b/internal/impl/legacy_enum.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy +package impl import ( "fmt" @@ -16,85 +16,85 @@ import ( "google.golang.org/protobuf/reflect/prototype" ) -// wrapEnum wraps v as a protoreflect.Enum, +// legacyWrapEnum wraps v as a protoreflect.Enum, // where v must be a int32 kind and not implement the v2 API already. -func wrapEnum(v reflect.Value) pref.Enum { - et := loadEnumType(v.Type()) +func legacyWrapEnum(v reflect.Value) pref.Enum { + et := legacyLoadEnumType(v.Type()) return et.New(pref.EnumNumber(v.Int())) } -var enumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType +var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType -// loadEnumType dynamically loads a protoreflect.EnumType for t, +// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t, // where t must be an int32 kind and not implement the v2 API already. -func loadEnumType(t reflect.Type) pref.EnumType { +func legacyLoadEnumType(t reflect.Type) pref.EnumType { // Fast-path: check if a EnumType is cached for this concrete type. - if et, ok := enumTypeCache.Load(t); ok { + if et, ok := legacyEnumTypeCache.Load(t); ok { return et.(pref.EnumType) } // Slow-path: derive enum descriptor and initialize EnumType. var et pref.EnumType var m sync.Map // map[protoreflect.EnumNumber]proto.Enum - ed := LoadEnumDesc(t) + ed := LegacyLoadEnumDesc(t) et = &prototype.Enum{ EnumDescriptor: ed, NewEnum: func(n pref.EnumNumber) pref.Enum { if e, ok := m.Load(n); ok { return e.(pref.Enum) } - e := &enumWrapper{num: n, pbTyp: et, goTyp: t} + e := &legacyEnumWrapper{num: n, pbTyp: et, goTyp: t} m.Store(n, e) return e }, } - if et, ok := enumTypeCache.LoadOrStore(t, et); ok { + if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok { return et.(pref.EnumType) } return et } -type enumWrapper struct { +type legacyEnumWrapper struct { num pref.EnumNumber pbTyp pref.EnumType goTyp reflect.Type } // TODO: Remove this. -func (e *enumWrapper) Type() pref.EnumType { +func (e *legacyEnumWrapper) Type() pref.EnumType { return e.pbTyp } -func (e *enumWrapper) Descriptor() pref.EnumDescriptor { +func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor { return e.pbTyp.Descriptor() } -func (e *enumWrapper) Number() pref.EnumNumber { +func (e *legacyEnumWrapper) Number() pref.EnumNumber { return e.num } -func (e *enumWrapper) ProtoReflect() pref.Enum { +func (e *legacyEnumWrapper) ProtoReflect() pref.Enum { return e } -func (e *enumWrapper) ProtoUnwrap() interface{} { +func (e *legacyEnumWrapper) ProtoUnwrap() interface{} { v := reflect.New(e.goTyp).Elem() v.SetInt(int64(e.num)) return v.Interface() } var ( - _ pref.Enum = (*enumWrapper)(nil) - _ pvalue.Unwrapper = (*enumWrapper)(nil) + _ pref.Enum = (*legacyEnumWrapper)(nil) + _ pvalue.Unwrapper = (*legacyEnumWrapper)(nil) ) -var enumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor +var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor -var enumNumberType = reflect.TypeOf(pref.EnumNumber(0)) +var legacyEnumNumberType = reflect.TypeOf(pref.EnumNumber(0)) -// LoadEnumDesc returns an EnumDescriptor derived from the Go type, +// LegacyLoadEnumDesc returns an EnumDescriptor derived from the Go type, // which must be an int32 kind and not implement the v2 API already. // // This is exported for testing purposes. -func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { +func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { // Fast-path: check if an EnumDescriptor is cached for this concrete type. - if ed, ok := enumDescCache.Load(t); ok { + if ed, ok := legacyEnumDescCache.Load(t); ok { return ed.(pref.EnumDescriptor) } @@ -102,7 +102,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { if t.Kind() != reflect.Int32 || t.PkgPath() == "" { panic(fmt.Sprintf("got %v, want named int32 kind", t)) } - if t == enumNumberType { + if t == legacyEnumNumberType { panic(fmt.Sprintf("cannot be %v", t)) } @@ -114,7 +114,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { } if ed, ok := ev.(enumV1); ok { b, idxs := ed.EnumDescriptor() - fd := loadFileDesc(b) + fd := legacyLoadFileDesc(b) // Derive syntax. switch fd.GetSyntax() { @@ -125,7 +125,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { } // Derive the full name and correct enum descriptor. - var ed *enumDescriptorProto + var ed *legacyEnumDescriptorProto e.FullName = pref.FullName(fd.GetPackage()) if len(idxs) == 1 { ed = fd.EnumType[idxs[0]] @@ -160,7 +160,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { // most operations continue to work. For example, prototext and protojson // will be unable to parse a message with an enum value by name. e.Syntax = pref.Proto2 - e.FullName = deriveFullName(t) + e.FullName = legacyDeriveFullName(t) e.Values = []ptype.EnumValue{{Name: "INVALID", Number: math.MinInt32}} } @@ -168,7 +168,7 @@ func LoadEnumDesc(t reflect.Type) pref.EnumDescriptor { if err != nil { panic(err) } - if ed, ok := enumDescCache.LoadOrStore(t, ed); ok { + if ed, ok := legacyEnumDescCache.LoadOrStore(t, ed); ok { return ed.(pref.EnumDescriptor) } return ed diff --git a/internal/legacy/extension.go b/internal/impl/legacy_extension.go similarity index 78% rename from internal/legacy/extension.go rename to internal/impl/legacy_extension.go index c8cb3e98..33ca82c5 100644 --- a/internal/legacy/extension.go +++ b/internal/impl/legacy_extension.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy +package impl import ( "fmt" @@ -11,7 +11,6 @@ import ( "google.golang.org/protobuf/internal/descfmt" ptag "google.golang.org/protobuf/internal/encoding/tag" - pimpl "google.golang.org/protobuf/internal/impl" ptype "google.golang.org/protobuf/internal/prototype" pvalue "google.golang.org/protobuf/internal/value" pref "google.golang.org/protobuf/reflect/protoreflect" @@ -20,9 +19,9 @@ import ( piface "google.golang.org/protobuf/runtime/protoiface" ) -// extensionDescKey is a comparable version of protoiface.ExtensionDescV1 +// legacyExtensionDescKey is a comparable version of protoiface.ExtensionDescV1 // suitable for use as a key in a map. -type extensionDescKey struct { +type legacyExtensionDescKey struct { typeV2 pref.ExtensionType extendedType reflect.Type extensionType reflect.Type @@ -32,8 +31,8 @@ type extensionDescKey struct { filename string } -func extensionDescKeyOf(d *piface.ExtensionDescV1) extensionDescKey { - return extensionDescKey{ +func legacyExtensionDescKeyOf(d *piface.ExtensionDescV1) legacyExtensionDescKey { + return legacyExtensionDescKey{ d.Type, reflect.TypeOf(d.ExtendedType), reflect.TypeOf(d.ExtensionType), @@ -42,13 +41,13 @@ func extensionDescKeyOf(d *piface.ExtensionDescV1) extensionDescKey { } var ( - extensionTypeCache sync.Map // map[extensionDescKey]protoreflect.ExtensionType - extensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1 + legacyExtensionTypeCache sync.Map // map[legacyExtensionDescKey]protoreflect.ExtensionType + legacyExtensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1 ) -// extensionDescFromType converts a v2 protoreflect.ExtensionType to a +// legacyExtensionDescFromType converts a v2 protoreflect.ExtensionType to a // protoiface.ExtensionDescV1. The returned ExtensionDesc must not be mutated. -func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 { +func legacyExtensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 { // Fast-path: check whether an extension desc is already nested within. if xt, ok := xt.(interface { ProtoLegacyExtensionDesc() *piface.ExtensionDescV1 @@ -60,7 +59,7 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 { // Fast-path: check the cache for whether this ExtensionType has already // been converted to a legacy descriptor. - if d, ok := extensionDescCache.Load(xt); ok { + if d, ok := legacyExtensionDescCache.Load(xt); ok { return d.(*piface.ExtensionDescV1) } @@ -113,7 +112,7 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 { } if ed, ok := reflect.Zero(t).Interface().(enumV1); ok && protoPkg == "" { b, _ := ed.EnumDescriptor() - protoPkg = loadFileDesc(b).GetPackage() + protoPkg = legacyLoadFileDesc(b).GetPackage() } if protoPkg != "" { @@ -137,17 +136,17 @@ func extensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 { Tag: ptag.Marshal(xt.Descriptor(), enumName), Filename: filename, } - if d, ok := extensionDescCache.LoadOrStore(xt, d); ok { + if d, ok := legacyExtensionDescCache.LoadOrStore(xt, d); ok { return d.(*piface.ExtensionDescV1) } return d } -// extensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a +// legacyExtensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a // v2 protoreflect.ExtensionType. The returned descriptor type takes ownership // of the input extension desc. The input must not be mutated so long as the // returned type is still in use. -func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { +func legacyExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { // Fast-path: check whether an extension type is already nested within. if d.Type != nil { return d.Type @@ -155,8 +154,8 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { // Fast-path: check the cache for whether this ExtensionType has already // been converted from a legacy descriptor. - dk := extensionDescKeyOf(d) - if t, ok := extensionTypeCache.Load(dk); ok { + dk := legacyExtensionDescKeyOf(d) + if t, ok := legacyExtensionTypeCache.Load(dk); ok { return t.(pref.ExtensionType) } @@ -177,13 +176,13 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { if e, ok := reflect.Zero(t).Interface().(pref.Enum); ok { ed = e.Descriptor() } else { - ed = LoadEnumDesc(t) + ed = LegacyLoadEnumDesc(t) } case pref.MessageKind, pref.GroupKind: if m, ok := reflect.Zero(t).Interface().(pref.ProtoMessage); ok { md = m.ProtoReflect().Descriptor() } else { - md = LoadMessageDesc(t) + md = LegacyLoadMessageDesc(t) } } xd, err := ptype.NewExtension(&ptype.StandaloneExtension{ @@ -195,26 +194,27 @@ func extensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { Options: f.Options, EnumType: ed, MessageType: md, - ExtendedType: pimpl.Export{}.MessageDescriptorOf(d.ExtendedType), + ExtendedType: Export{}.MessageDescriptorOf(d.ExtendedType), }) if err != nil { panic(err) } - xt := ExtensionTypeOf(xd, t) + xt := LegacyExtensionTypeOf(xd, t) // Cache the conversion for both directions. - extensionDescCache.LoadOrStore(xt, d) - if xt, ok := extensionTypeCache.LoadOrStore(dk, xt); ok { + legacyExtensionDescCache.LoadOrStore(xt, d) + if xt, ok := legacyExtensionTypeCache.LoadOrStore(dk, xt); ok { return xt.(pref.ExtensionType) } return xt } -// ExtensionTypeOf returns a protoreflect.ExtensionType where the type of the -// field is t. The type t must be provided if the field is an enum or message. +// LegacyExtensionTypeOf returns a protoreflect.ExtensionType where the +// element type of the field is t. The type t must be provided if the field +// is an enum or message. // // This is exported for testing purposes. -func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType { +func LegacyExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType { var conv pvalue.Converter var isLegacy bool xt := &prototype.Extension{ExtensionDescriptor: xd} @@ -234,7 +234,7 @@ func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension } // Wrap ExtensionType such that GoType presents the legacy Go type. - xt2 := &extensionType{ExtensionType: xt} + xt2 := &legacyExtensionType{ExtensionType: xt} if xd.Cardinality() != pref.Repeated { xt2.typ = t xt2.new = func() pref.Value { @@ -276,7 +276,7 @@ func ExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.Extension return xt2 } -type extensionType struct { +type legacyExtensionType struct { pref.ExtensionType typ reflect.Type new func() pref.Value @@ -284,8 +284,8 @@ type extensionType struct { interfaceOf func(pref.Value) interface{} } -func (x *extensionType) GoType() reflect.Type { return x.typ } -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) { descfmt.FormatDesc(s, r, x.Descriptor()) } +func (x *legacyExtensionType) GoType() reflect.Type { return x.typ } +func (x *legacyExtensionType) New() pref.Value { return x.new() } +func (x *legacyExtensionType) ValueOf(v interface{}) pref.Value { return x.valueOf(v) } +func (x *legacyExtensionType) InterfaceOf(v pref.Value) interface{} { return x.interfaceOf(v) } +func (x *legacyExtensionType) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, x.Descriptor()) } diff --git a/internal/legacy/extension_test.go b/internal/impl/legacy_extension_test.go similarity index 64% rename from internal/legacy/extension_test.go rename to internal/impl/legacy_extension_test.go index c9bc9d4c..13a2c6d5 100644 --- a/internal/legacy/extension_test.go +++ b/internal/impl/legacy_extension_test.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy_test +package impl_test import ( "reflect" "testing" pimpl "google.golang.org/protobuf/internal/impl" - plegacy "google.golang.org/protobuf/internal/legacy" ptype "google.golang.org/protobuf/internal/prototype" pref "google.golang.org/protobuf/reflect/protoreflect" piface "google.golang.org/protobuf/runtime/protoiface" @@ -17,15 +16,15 @@ import ( proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152" ) -type legacyTestMessage struct { +type legacyExtendedMessage struct { XXX_unrecognized []byte XXX_InternalExtensions map[int32]pimpl.ExtensionFieldV1 } -func (*legacyTestMessage) Reset() {} -func (*legacyTestMessage) String() string { return "" } -func (*legacyTestMessage) ProtoMessage() {} -func (*legacyTestMessage) ExtensionRangeArray() []piface.ExtensionRangeV1 { +func (*legacyExtendedMessage) Reset() {} +func (*legacyExtendedMessage) String() string { return "" } +func (*legacyExtendedMessage) ProtoMessage() {} +func (*legacyExtendedMessage) ExtensionRangeArray() []piface.ExtensionRangeV1 { return []piface.ExtensionRangeV1{{Start: 10000, End: 20000}} } @@ -34,23 +33,23 @@ func mustMakeExtensionType(x *ptype.StandaloneExtension, v interface{}) pref.Ext if err != nil { panic(err) } - return plegacy.ExtensionTypeOf(xd, reflect.TypeOf(v)) + return pimpl.LegacyExtensionTypeOf(xd, reflect.TypeOf(v)) } var ( - parentDesc = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil)) - messageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil)) + extParentDesc = pimpl.Export{}.MessageDescriptorOf((*legacyExtendedMessage)(nil)) + extMessageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil)) wantType = mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_message_v1", Number: 10007, Cardinality: pref.Optional, Kind: pref.MessageKind, - MessageType: messageV1Desc, - ExtendedType: parentDesc, + MessageType: extMessageV1Desc, + ExtendedType: extParentDesc, }, (*proto2_20180125.Message_ChildMessage)(nil)) wantDesc = &piface.ExtensionDescV1{ - ExtendedType: (*legacyTestMessage)(nil), + ExtendedType: (*legacyExtendedMessage)(nil), ExtensionType: (*proto2_20180125.Message_ChildMessage)(nil), Field: 10007, Name: "fizz.buzz.optional_message_v1", @@ -61,14 +60,14 @@ var ( func BenchmarkConvert(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - xd := plegacy.Export{}.ExtensionDescFromType(wantType) - gotType := plegacy.Export{}.ExtensionTypeFromDesc(xd) + xd := pimpl.Export{}.ExtensionDescFromType(wantType) + gotType := pimpl.Export{}.ExtensionTypeFromDesc(xd) if gotType != wantType { b.Fatalf("ExtensionType mismatch: got %p, want %p", gotType, wantType) } - xt := plegacy.Export{}.ExtensionTypeFromDesc(wantDesc) - gotDesc := plegacy.Export{}.ExtensionDescFromType(xt) + xt := pimpl.Export{}.ExtensionTypeFromDesc(wantDesc) + gotDesc := pimpl.Export{}.ExtensionDescFromType(xt) if gotDesc != wantDesc { b.Fatalf("ExtensionDesc mismatch: got %p, want %p", gotDesc, wantDesc) } diff --git a/internal/legacy/file.go b/internal/impl/legacy_file.go similarity index 75% rename from internal/legacy/file.go rename to internal/impl/legacy_file.go index e98508ba..ddf33f7b 100644 --- a/internal/legacy/file.go +++ b/internal/impl/legacy_file.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy +package impl import ( "bytes" @@ -28,18 +28,18 @@ type ( } ) -var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto +var legacyFileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto -// loadFileDesc unmarshals b as a compressed FileDescriptorProto message. +// legacyLoadFileDesc unmarshals b as a compressed FileDescriptorProto message. // // This assumes that b is immutable and that b does not refer to part of a // concatenated series of GZIP files (which would require shenanigans that // rely on the concatenation properties of both protobufs and GZIP). // File descriptors generated by protoc-gen-go do not rely on that property. -func loadFileDesc(b []byte) *fileDescriptorProto { +func legacyLoadFileDesc(b []byte) *legacyFileDescriptorProto { // Fast-path: check whether we already have a cached file descriptor. - if fd, ok := fileDescCache.Load(&b[0]); ok { - return fd.(*fileDescriptorProto) + if fd, ok := legacyFileDescCache.Load(&b[0]); ok { + return fd.(*legacyFileDescriptorProto) } // Slow-path: decompress and unmarshal the file descriptor proto. @@ -51,9 +51,9 @@ func loadFileDesc(b []byte) *fileDescriptorProto { if err != nil { panic(err) } - fd := parseFileDescProto(b) - if fd, ok := fileDescCache.LoadOrStore(&b[0], fd); ok { - return fd.(*fileDescriptorProto) + fd := legacyParseFileDescProto(b) + if fd, ok := legacyFileDescCache.LoadOrStore(&b[0], fd); ok { + return fd.(*legacyFileDescriptorProto) } return fd } diff --git a/internal/legacy/file_test.go b/internal/impl/legacy_file_test.go similarity index 61% rename from internal/legacy/file_test.go rename to internal/impl/legacy_file_test.go index ac1a7b09..d4c5890b 100644 --- a/internal/legacy/file_test.go +++ b/internal/impl/legacy_file_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy_test +package impl_test import ( "bytes" @@ -11,9 +11,9 @@ import ( "reflect" "testing" - cmp "github.com/google/go-cmp/cmp" - legacy "google.golang.org/protobuf/internal/legacy" - pragma "google.golang.org/protobuf/internal/pragma" + "github.com/google/go-cmp/cmp" + "google.golang.org/protobuf/internal/impl" + "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/proto" pdesc "google.golang.org/protobuf/reflect/protodesc" pref "google.golang.org/protobuf/reflect/protoreflect" @@ -59,343 +59,343 @@ func TestDescriptor(t *testing.T) { fileDescP2_20160225 := mustLoadFileDesc(new(proto2_20160225.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160225.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160225.SiblingEnum(0))), want: fileDescP2_20160225.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160225.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160225.Message_ChildEnum(0))), want: fileDescP2_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.SiblingMessage))), want: fileDescP2_20160225.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ChildMessage))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message))), want: fileDescP2_20160225.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_NamedGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OptionalGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RequiredGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_RepeatedGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_OneofGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionOptionalGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160225.Message_ExtensionRepeatedGroup))), want: fileDescP2_20160225.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20160225 := mustLoadFileDesc(new(proto3_20160225.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160225.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160225.SiblingEnum(0))), want: fileDescP3_20160225.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160225.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160225.Message_ChildEnum(0))), want: fileDescP3_20160225.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.SiblingMessage))), want: fileDescP3_20160225.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message_ChildMessage))), want: fileDescP3_20160225.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160225.Message))), want: fileDescP3_20160225.Messages().ByName("Message"), }}...) fileDescP2_20160519 := mustLoadFileDesc(new(proto2_20160519.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160519.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160519.SiblingEnum(0))), want: fileDescP2_20160519.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20160519.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20160519.Message_ChildEnum(0))), want: fileDescP2_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.SiblingMessage))), want: fileDescP2_20160519.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ChildMessage))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message))), want: fileDescP2_20160519.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_NamedGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OptionalGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RequiredGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_RepeatedGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_OneofGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionOptionalGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20160519.Message_ExtensionRepeatedGroup))), want: fileDescP2_20160519.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20160519 := mustLoadFileDesc(new(proto3_20160519.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160519.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160519.SiblingEnum(0))), want: fileDescP3_20160519.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20160519.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20160519.Message_ChildEnum(0))), want: fileDescP3_20160519.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.SiblingMessage))), want: fileDescP3_20160519.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message_ChildMessage))), want: fileDescP3_20160519.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20160519.Message))), want: fileDescP3_20160519.Messages().ByName("Message"), }}...) fileDescP2_20180125 := mustLoadFileDesc(new(proto2_20180125.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180125.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180125.SiblingEnum(0))), want: fileDescP2_20180125.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180125.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180125.Message_ChildEnum(0))), want: fileDescP2_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.SiblingMessage))), want: fileDescP2_20180125.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ChildMessage))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message))), want: fileDescP2_20180125.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_NamedGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OptionalGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RequiredGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_RepeatedGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_OneofGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionOptionalGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180125.Message_ExtensionRepeatedGroup))), want: fileDescP2_20180125.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20180125 := mustLoadFileDesc(new(proto3_20180125.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180125.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180125.SiblingEnum(0))), want: fileDescP3_20180125.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180125.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180125.Message_ChildEnum(0))), want: fileDescP3_20180125.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.SiblingMessage))), want: fileDescP3_20180125.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message_ChildMessage))), want: fileDescP3_20180125.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180125.Message))), want: fileDescP3_20180125.Messages().ByName("Message"), }}...) fileDescP2_20180430 := mustLoadFileDesc(new(proto2_20180430.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180430.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180430.SiblingEnum(0))), want: fileDescP2_20180430.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180430.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180430.Message_ChildEnum(0))), want: fileDescP2_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.SiblingMessage))), want: fileDescP2_20180430.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ChildMessage))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message))), want: fileDescP2_20180430.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_NamedGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OptionalGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RequiredGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_RepeatedGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_OneofGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionOptionalGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180430.Message_ExtensionRepeatedGroup))), want: fileDescP2_20180430.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20180430 := mustLoadFileDesc(new(proto3_20180430.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180430.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180430.SiblingEnum(0))), want: fileDescP3_20180430.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180430.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180430.Message_ChildEnum(0))), want: fileDescP3_20180430.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.SiblingMessage))), want: fileDescP3_20180430.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message_ChildMessage))), want: fileDescP3_20180430.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180430.Message))), want: fileDescP3_20180430.Messages().ByName("Message"), }}...) fileDescP2_20180814 := mustLoadFileDesc(new(proto2_20180814.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180814.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180814.SiblingEnum(0))), want: fileDescP2_20180814.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20180814.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20180814.Message_ChildEnum(0))), want: fileDescP2_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.SiblingMessage))), want: fileDescP2_20180814.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ChildMessage))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message))), want: fileDescP2_20180814.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_NamedGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OptionalGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RequiredGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_RepeatedGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_OneofGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionOptionalGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20180814.Message_ExtensionRepeatedGroup))), want: fileDescP2_20180814.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20180814 := mustLoadFileDesc(new(proto3_20180814.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180814.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180814.SiblingEnum(0))), want: fileDescP3_20180814.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20180814.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20180814.Message_ChildEnum(0))), want: fileDescP3_20180814.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.SiblingMessage))), want: fileDescP3_20180814.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message_ChildMessage))), want: fileDescP3_20180814.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20180814.Message))), want: fileDescP3_20180814.Messages().ByName("Message"), }}...) fileDescP2_20181126 := mustLoadFileDesc(new(proto2_20181126.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20181126.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20181126.SiblingEnum(0))), want: fileDescP2_20181126.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto2_20181126.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto2_20181126.Message_ChildEnum(0))), want: fileDescP2_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.SiblingMessage))), want: fileDescP2_20181126.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ChildMessage))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message))), want: fileDescP2_20181126.Messages().ByName("Message"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_NamedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_NamedGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("NamedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OptionalGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RequiredGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RequiredGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RequiredGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_RepeatedGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("RepeatedGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OneofGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_OneofGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("OneofGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionOptionalGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionOptionalGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionOptionalGroup"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionRepeatedGroup))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto2_20181126.Message_ExtensionRepeatedGroup))), want: fileDescP2_20181126.Messages().ByName("Message").Messages().ByName("ExtensionRepeatedGroup"), }}...) fileDescP3_20181126 := mustLoadFileDesc(new(proto3_20181126.Message).Descriptor()) tests = append(tests, []struct{ got, want pref.Descriptor }{{ - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20181126.SiblingEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20181126.SiblingEnum(0))), want: fileDescP3_20181126.Enums().ByName("SiblingEnum"), }, { - got: legacy.LoadEnumDesc(reflect.TypeOf(proto3_20181126.Message_ChildEnum(0))), + got: impl.LegacyLoadEnumDesc(reflect.TypeOf(proto3_20181126.Message_ChildEnum(0))), want: fileDescP3_20181126.Messages().ByName("Message").Enums().ByName("ChildEnum"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.SiblingMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.SiblingMessage))), want: fileDescP3_20181126.Messages().ByName("SiblingMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message_ChildMessage))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message_ChildMessage))), want: fileDescP3_20181126.Messages().ByName("Message").Messages().ByName("ChildMessage"), }, { - got: legacy.LoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message))), + got: impl.LegacyLoadMessageDesc(reflect.TypeOf(new(proto3_20181126.Message))), want: fileDescP3_20181126.Messages().ByName("Message"), }}...) diff --git a/internal/impl/legacy_hook.go b/internal/impl/legacy_hook.go deleted file mode 100644 index 98eaf2f5..00000000 --- a/internal/impl/legacy_hook.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 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 impl - -import ( - "reflect" - - pvalue "google.golang.org/protobuf/internal/value" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" -) - -// TODO: Add a default LegacyWrapper that panics with a more helpful message? -var legacyWrapper LegacyWrapper - -// RegisterLegacyWrapper registers a set of constructor functions that are -// called when a legacy enum or message is encountered that does not natively -// support the protobuf reflection APIs. -func RegisterLegacyWrapper(w LegacyWrapper) { - legacyWrapper = w -} - -// LegacyWrapper is a set of wrapper methods that wraps legacy v1 Go types -// to implement the v2 reflection APIs. -type LegacyWrapper interface { - NewConverter(reflect.Type, pref.Kind) pvalue.Converter - - EnumOf(interface{}) pref.Enum - EnumTypeOf(interface{}) pref.EnumType - EnumDescriptorOf(interface{}) pref.EnumDescriptor - - MessageOf(interface{}) pref.Message - MessageTypeOf(interface{}) pref.MessageType - MessageDescriptorOf(interface{}) pref.MessageDescriptor - - // TODO: Remove these eventually. - // See the TODOs in internal/impl/legacy_extension.go. - ExtensionDescFromType(pref.ExtensionType) *piface.ExtensionDescV1 - ExtensionTypeFromDesc(*piface.ExtensionDescV1) pref.ExtensionType -} diff --git a/internal/legacy/message.go b/internal/impl/legacy_message.go similarity index 80% rename from internal/legacy/message.go rename to internal/impl/legacy_message.go index b17d705b..c54cfc16 100644 --- a/internal/legacy/message.go +++ b/internal/impl/legacy_message.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy +package impl import ( "fmt" @@ -12,32 +12,31 @@ import ( "unicode" ptag "google.golang.org/protobuf/internal/encoding/tag" - pimpl "google.golang.org/protobuf/internal/impl" ptype "google.golang.org/protobuf/internal/prototype" pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/prototype" ) -// wrapMessage wraps v as a protoreflect.ProtoMessage, +// legacyWrapMessage wraps v as a protoreflect.ProtoMessage, // where v must be a *struct kind and not implement the v2 API already. -func wrapMessage(v reflect.Value) pref.ProtoMessage { - mt := loadMessageInfo(v.Type()) +func legacyWrapMessage(v reflect.Value) pref.ProtoMessage { + mt := legacyLoadMessageInfo(v.Type()) return mt.MessageOf(v.Interface()).Interface() } -var messageTypeCache sync.Map // map[reflect.Type]*MessageInfo +var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo -// loadMessageInfo dynamically loads a *MessageInfo for t, +// legacyLoadMessageInfo dynamically loads a *MessageInfo for t, // where t must be a *struct kind and not implement the v2 API already. -func loadMessageInfo(t reflect.Type) *pimpl.MessageInfo { +func legacyLoadMessageInfo(t reflect.Type) *MessageInfo { // Fast-path: check if a MessageInfo is cached for this concrete type. - if mt, ok := messageTypeCache.Load(t); ok { - return mt.(*pimpl.MessageInfo) + if mt, ok := legacyMessageTypeCache.Load(t); ok { + return mt.(*MessageInfo) } // Slow-path: derive message descriptor and initialize MessageInfo. - md := LoadMessageDesc(t) - mt := new(pimpl.MessageInfo) + md := LegacyLoadMessageDesc(t) + mt := new(MessageInfo) mt.GoType = t mt.PBType = &prototype.Message{ MessageDescriptor: md, @@ -45,32 +44,34 @@ func loadMessageInfo(t reflect.Type) *pimpl.MessageInfo { return mt.MessageOf(reflect.New(t.Elem()).Interface()) }, } - if mt, ok := messageTypeCache.LoadOrStore(t, mt); ok { - return mt.(*pimpl.MessageInfo) + if mt, ok := legacyMessageTypeCache.LoadOrStore(t, mt); ok { + return mt.(*MessageInfo) } return mt } -var messageDescLock sync.Mutex -var messageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor +var ( + legacyMessageDescLock sync.Mutex + legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor +) -// LoadMessageDesc returns an MessageDescriptor derived from the Go type, +// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type, // which must be a *struct kind and not implement the v2 API already. // // This is exported for testing purposes. -func LoadMessageDesc(t reflect.Type) pref.MessageDescriptor { - return messageDescSet{}.Load(t) +func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor { + return legacyMessageDescSet{}.Load(t) } -type messageDescSet struct { +type legacyMessageDescSet struct { visited map[reflect.Type]*ptype.StandaloneMessage descs []*ptype.StandaloneMessage types []reflect.Type } -func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor { +func (ms legacyMessageDescSet) Load(t reflect.Type) pref.MessageDescriptor { // Fast-path: check if a MessageDescriptor is cached for this concrete type. - if mi, ok := messageDescCache.Load(t); ok { + if mi, ok := legacyMessageDescCache.Load(t); ok { return mi.(pref.MessageDescriptor) } @@ -79,9 +80,9 @@ func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor { // Hold a global lock during message creation to ensure that each Go type // maps to exactly one MessageDescriptor. After obtaining the lock, we must // check again whether the message has already been handled. - messageDescLock.Lock() - defer messageDescLock.Unlock() - if mi, ok := messageDescCache.Load(t); ok { + legacyMessageDescLock.Lock() + defer legacyMessageDescLock.Unlock() + if mi, ok := legacyMessageDescCache.Load(t); ok { return mi.(pref.MessageDescriptor) } @@ -101,13 +102,13 @@ func (ms messageDescSet) Load(t reflect.Type) pref.MessageDescriptor { // pseudo-messages (has a descriptor, but no generated Go type). // Avoid caching these fake messages. if t := ms.types[i]; t.Kind() != reflect.Map { - messageDescCache.Store(t, md) + legacyMessageDescCache.Store(t, md) } } return mds[0] } -func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor { +func (ms *legacyMessageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor { // Fast-path: Obtain a placeholder if the message is already processed. if m, ok := ms.visited[t]; ok { return ptype.PlaceholderMessage(m.FullName) @@ -126,7 +127,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor } if md, ok := mv.(messageV1); ok { b, idxs := md.Descriptor() - fd := loadFileDesc(b) + fd := legacyLoadFileDesc(b) // Derive syntax. switch fd.GetSyntax() { @@ -148,7 +149,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor // obtain the full name is through the registry. However, this is // unreliable as some generated messages register with a fork of // golang/protobuf, so the registry may not have this information. - m.FullName = deriveFullName(t.Elem()) + m.FullName = legacyDeriveFullName(t.Elem()) m.Syntax = pref.Proto2 // Try to determine if the message is using proto3 by checking scalars. @@ -223,7 +224,7 @@ func (ms *messageDescSet) processMessage(t reflect.Type) pref.MessageDescriptor return ptype.PlaceholderMessage(m.FullName) } -func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.Type, parent *ptype.StandaloneMessage) ptype.Field { +func (ms *legacyMessageDescSet) parseField(tag, tagKey, tagVal string, goType reflect.Type, parent *ptype.StandaloneMessage) ptype.Field { t := goType isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 @@ -237,7 +238,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect. if ev, ok := reflect.Zero(t).Interface().(pref.Enum); ok { f.EnumType = ev.Descriptor() } else { - f.EnumType = LoadEnumDesc(t) + f.EnumType = LegacyLoadEnumDesc(t) } } if f.MessageType == nil && (f.Kind == pref.MessageKind || f.Kind == pref.GroupKind) { @@ -246,7 +247,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect. } else if t.Kind() == reflect.Map { m := &ptype.StandaloneMessage{ Syntax: parent.Syntax, - FullName: parent.FullName.Append(mapEntryName(f.Name)), + FullName: parent.FullName.Append(legacyMapEntryName(f.Name)), IsMapEntry: true, Fields: []ptype.Field{ ms.parseField(tagKey, "", "", t.Key(), nil), @@ -255,7 +256,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect. } ms.visit(m, t) f.MessageType = ptype.PlaceholderMessage(m.FullName) - } else if mv, ok := messageDescCache.Load(t); ok { + } else if mv, ok := legacyMessageDescCache.Load(t); ok { f.MessageType = mv.(pref.MessageDescriptor) } else { f.MessageType = ms.processMessage(t) @@ -264,7 +265,7 @@ func (ms *messageDescSet) parseField(tag, tagKey, tagVal string, goType reflect. return f } -func (ms *messageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) { +func (ms *legacyMessageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) { if ms.visited == nil { ms.visited = make(map[reflect.Type]*ptype.StandaloneMessage) } @@ -275,10 +276,10 @@ func (ms *messageDescSet) visit(m *ptype.StandaloneMessage, t reflect.Type) { ms.types = append(ms.types, t) } -// deriveFullName derives a fully qualified protobuf name for the given Go type +// legacyDeriveFullName derives a fully qualified protobuf name for the given Go type // The provided name is not guaranteed to be stable nor universally unique. // It should be sufficiently unique within a program. -func deriveFullName(t reflect.Type) pref.FullName { +func legacyDeriveFullName(t reflect.Type) pref.FullName { sanitize := func(r rune) rune { switch { case r == '/': @@ -304,9 +305,9 @@ func deriveFullName(t reflect.Type) pref.FullName { return pref.FullName(strings.Join(ss, ".")) } -// mapEntryName derives the message name for a map field of a given name. +// legacyMapEntryName derives the message name for a map field of a given name. // This is identical to MapEntryName from parser.cc in the protoc source. -func mapEntryName(s pref.Name) pref.Name { +func legacyMapEntryName(s pref.Name) pref.Name { var b []byte nextUpper := true for i := 0; i < len(s); i++ { diff --git a/internal/legacy/parse.go b/internal/impl/legacy_parse.go similarity index 59% rename from internal/legacy/parse.go rename to internal/impl/legacy_parse.go index 6de9578f..90ba1b76 100644 --- a/internal/legacy/parse.go +++ b/internal/impl/legacy_parse.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package legacy +package impl import ( "google.golang.org/protobuf/internal/encoding/wire" @@ -14,21 +14,21 @@ import ( // // TODO: Consider unifying this with the parser in fileinit. -type fileDescriptorProto struct { +type legacyFileDescriptorProto struct { Syntax string Package string - EnumType []*enumDescriptorProto - MessageType []*descriptorProto + EnumType []*legacyEnumDescriptorProto + MessageType []*legacyDescriptorProto } -func (fd fileDescriptorProto) GetSyntax() string { return fd.Syntax } -func (fd fileDescriptorProto) GetPackage() string { return fd.Package } +func (fd legacyFileDescriptorProto) GetSyntax() string { return fd.Syntax } +func (fd legacyFileDescriptorProto) GetPackage() string { return fd.Package } -func parseFileDescProto(b []byte) *fileDescriptorProto { - fd := &fileDescriptorProto{} +func legacyParseFileDescProto(b []byte) *legacyFileDescriptorProto { + fd := &legacyFileDescriptorProto{} for len(b) > 0 { num, typ, n := wire.ConsumeTag(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch typ { case wire.BytesType: @@ -40,37 +40,37 @@ func parseFileDescProto(b []byte) *fileDescriptorProto { case fieldnum.FileDescriptorProto_Package: fd.Package = string(v) case fieldnum.FileDescriptorProto_EnumType: - fd.EnumType = append(fd.EnumType, parseEnumDescProto(v)) + fd.EnumType = append(fd.EnumType, legacyParseEnumDescProto(v)) case fieldnum.FileDescriptorProto_MessageType: fd.MessageType = append(fd.MessageType, parseDescProto(v)) } default: n := wire.ConsumeFieldValue(num, typ, b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] } } return fd } -type descriptorProto struct { +type legacyDescriptorProto struct { Name string - NestedType []*descriptorProto - EnumType []*enumDescriptorProto + NestedType []*legacyDescriptorProto + EnumType []*legacyEnumDescriptorProto } -func (md descriptorProto) GetName() string { return md.Name } +func (md legacyDescriptorProto) GetName() string { return md.Name } -func parseDescProto(b []byte) *descriptorProto { - md := &descriptorProto{} +func parseDescProto(b []byte) *legacyDescriptorProto { + md := &legacyDescriptorProto{} for len(b) > 0 { num, typ, n := wire.ConsumeTag(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch typ { case wire.BytesType: v, n := wire.ConsumeBytes(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch num { case fieldnum.DescriptorProto_Name: @@ -78,68 +78,68 @@ func parseDescProto(b []byte) *descriptorProto { case fieldnum.DescriptorProto_NestedType: md.NestedType = append(md.NestedType, parseDescProto(v)) case fieldnum.DescriptorProto_EnumType: - md.EnumType = append(md.EnumType, parseEnumDescProto(v)) + md.EnumType = append(md.EnumType, legacyParseEnumDescProto(v)) } default: n := wire.ConsumeFieldValue(num, typ, b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] } } return md } -type enumDescriptorProto struct { +type legacyEnumDescriptorProto struct { Name string - Value []*enumValueDescriptorProto + Value []*legacyEnumValueDescriptorProto } -func (ed enumDescriptorProto) GetName() string { return ed.Name } +func (ed legacyEnumDescriptorProto) GetName() string { return ed.Name } -func parseEnumDescProto(b []byte) *enumDescriptorProto { - ed := &enumDescriptorProto{} +func legacyParseEnumDescProto(b []byte) *legacyEnumDescriptorProto { + ed := &legacyEnumDescriptorProto{} for len(b) > 0 { num, typ, n := wire.ConsumeTag(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch typ { case wire.BytesType: v, n := wire.ConsumeBytes(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch num { case fieldnum.EnumDescriptorProto_Name: ed.Name = string(v) case fieldnum.EnumDescriptorProto_Value: - ed.Value = append(ed.Value, parseEnumValueDescProto(v)) + ed.Value = append(ed.Value, legacyParseEnumValueDescProto(v)) } default: n := wire.ConsumeFieldValue(num, typ, b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] } } return ed } -type enumValueDescriptorProto struct { +type legacyEnumValueDescriptorProto struct { Name string Number int32 } -func (ed enumValueDescriptorProto) GetName() string { return ed.Name } -func (ed enumValueDescriptorProto) GetNumber() int32 { return ed.Number } +func (ed legacyEnumValueDescriptorProto) GetName() string { return ed.Name } +func (ed legacyEnumValueDescriptorProto) GetNumber() int32 { return ed.Number } -func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto { - vd := &enumValueDescriptorProto{} +func legacyParseEnumValueDescProto(b []byte) *legacyEnumValueDescriptorProto { + vd := &legacyEnumValueDescriptorProto{} for len(b) > 0 { num, typ, n := wire.ConsumeTag(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch typ { case wire.VarintType: v, n := wire.ConsumeVarint(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch num { case fieldnum.EnumValueDescriptorProto_Number: @@ -147,7 +147,7 @@ func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto { } case wire.BytesType: v, n := wire.ConsumeBytes(b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] switch num { case fieldnum.EnumDescriptorProto_Name: @@ -155,14 +155,14 @@ func parseEnumValueDescProto(b []byte) *enumValueDescriptorProto { } default: n := wire.ConsumeFieldValue(num, typ, b) - parseCheck(n) + legacyParseCheck(n) b = b[n:] } } return vd } -func parseCheck(n int) { +func legacyParseCheck(n int) { if n < 0 { panic(wire.ParseError(n)) } diff --git a/internal/impl/legacy_test.go b/internal/impl/legacy_test.go index a01dac11..d6ca9418 100644 --- a/internal/impl/legacy_test.go +++ b/internal/impl/legacy_test.go @@ -8,13 +8,13 @@ import ( "bytes" "math" "reflect" + "sync" "testing" cmp "github.com/google/go-cmp/cmp" cmpopts "github.com/google/go-cmp/cmp/cmpopts" pack "google.golang.org/protobuf/internal/encoding/pack" pimpl "google.golang.org/protobuf/internal/impl" - plegacy "google.golang.org/protobuf/internal/legacy" pragma "google.golang.org/protobuf/internal/pragma" ptype "google.golang.org/protobuf/internal/prototype" scalar "google.golang.org/protobuf/internal/scalar" @@ -172,20 +172,12 @@ func TestLegacyUnknown(t *testing.T) { } } -func mustMakeExtensionType(x *ptype.StandaloneExtension, v interface{}) pref.ExtensionType { - xd, err := ptype.NewExtension(x) - if err != nil { - panic(xd) - } - return plegacy.ExtensionTypeOf(xd, reflect.TypeOf(v)) -} - var ( - parentDesc = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil)) - enumV1Desc = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0)) - messageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil)) - enumV2Desc = enumProto2Type.Descriptor() - messageV2Desc = enumMessagesType.PBType.Descriptor() + testParentDesc = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil)) + testEnumV1Desc = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0)) + testMessageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil)) + testEnumV2Desc = enumProto2Type.Descriptor() + testMessageV2Desc = enumMessagesType.PBType.Descriptor() extensionTypes = []pref.ExtensionType{ mustMakeExtensionType(&ptype.StandaloneExtension{ @@ -194,7 +186,7 @@ var ( Cardinality: pref.Optional, Kind: pref.BoolKind, Default: pref.ValueOf(true), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_int32", @@ -202,7 +194,7 @@ var ( Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: pref.ValueOf(int32(-12345)), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_uint32", @@ -210,7 +202,7 @@ var ( Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: pref.ValueOf(uint32(3200)), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_float", @@ -218,7 +210,7 @@ var ( Cardinality: pref.Optional, Kind: pref.FloatKind, Default: pref.ValueOf(float32(3.14159)), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_string", @@ -226,7 +218,7 @@ var ( Cardinality: pref.Optional, Kind: pref.StringKind, Default: pref.ValueOf(string("hello, \"world!\"\n")), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_bytes", @@ -234,7 +226,7 @@ var ( Cardinality: pref.Optional, Kind: pref.BytesKind, Default: pref.ValueOf([]byte("dead\xde\xad\xbe\xefbeef")), - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_enum_v1", @@ -242,16 +234,16 @@ var ( Cardinality: pref.Optional, Kind: pref.EnumKind, Default: pref.ValueOf(pref.EnumNumber(0)), - EnumType: enumV1Desc, - ExtendedType: parentDesc, + EnumType: testEnumV1Desc, + ExtendedType: testParentDesc, }, proto2_20180125.Message_ChildEnum(0)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_message_v1", Number: 10007, Cardinality: pref.Optional, Kind: pref.MessageKind, - MessageType: messageV1Desc, - ExtendedType: parentDesc, + MessageType: testMessageV1Desc, + ExtendedType: testParentDesc, }, (*proto2_20180125.Message_ChildMessage)(nil)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_enum_v2", @@ -259,90 +251,90 @@ var ( Cardinality: pref.Optional, Kind: pref.EnumKind, Default: pref.ValueOf(pref.EnumNumber(57005)), - EnumType: enumV2Desc, - ExtendedType: parentDesc, + EnumType: testEnumV2Desc, + ExtendedType: testParentDesc, }, EnumProto2(0)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.optional_message_v2", Number: 10009, Cardinality: pref.Optional, Kind: pref.MessageKind, - MessageType: messageV2Desc, - ExtendedType: parentDesc, + MessageType: testMessageV2Desc, + ExtendedType: testParentDesc, }, (*EnumMessages)(nil)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_bool", Number: 10010, Cardinality: pref.Repeated, Kind: pref.BoolKind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_int32", Number: 10011, Cardinality: pref.Repeated, Kind: pref.Int32Kind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_uint32", Number: 10012, Cardinality: pref.Repeated, Kind: pref.Uint32Kind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_float", Number: 10013, Cardinality: pref.Repeated, Kind: pref.FloatKind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_string", Number: 10014, Cardinality: pref.Repeated, Kind: pref.StringKind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_bytes", Number: 10015, Cardinality: pref.Repeated, Kind: pref.BytesKind, - ExtendedType: parentDesc, + ExtendedType: testParentDesc, }, nil), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_enum_v1", Number: 10016, Cardinality: pref.Repeated, Kind: pref.EnumKind, - EnumType: enumV1Desc, - ExtendedType: parentDesc, + EnumType: testEnumV1Desc, + ExtendedType: testParentDesc, }, proto2_20180125.Message_ChildEnum(0)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_message_v1", Number: 10017, Cardinality: pref.Repeated, Kind: pref.MessageKind, - MessageType: messageV1Desc, - ExtendedType: parentDesc, + MessageType: testMessageV1Desc, + ExtendedType: testParentDesc, }, (*proto2_20180125.Message_ChildMessage)(nil)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_enum_v2", Number: 10018, Cardinality: pref.Repeated, Kind: pref.EnumKind, - EnumType: enumV2Desc, - ExtendedType: parentDesc, + EnumType: testEnumV2Desc, + ExtendedType: testParentDesc, }, EnumProto2(0)), mustMakeExtensionType(&ptype.StandaloneExtension{ FullName: "fizz.buzz.repeated_message_v2", Number: 10019, Cardinality: pref.Repeated, Kind: pref.MessageKind, - MessageType: messageV2Desc, - ExtendedType: parentDesc, + MessageType: testMessageV2Desc, + ExtendedType: testParentDesc, }, (*EnumMessages)(nil)), } @@ -646,8 +638,8 @@ func TestExtensionConvert(t *testing.T) { wantType := extensionTypes[i] wantDesc := extensionDescs[i] - gotType := plegacy.Export{}.ExtensionTypeFromDesc(wantDesc) - gotDesc := plegacy.Export{}.ExtensionDescFromType(wantType) + gotType := pimpl.Export{}.ExtensionTypeFromDesc(wantDesc) + gotDesc := pimpl.Export{}.ExtensionDescFromType(wantType) // TODO: We need a test package to compare descriptors. type list interface { @@ -720,3 +712,88 @@ func TestExtensionConvert(t *testing.T) { }) } } + +type ( + MessageA struct { + A1 *MessageA `protobuf:"bytes,1,req,name=a1"` + A2 *MessageB `protobuf:"bytes,2,req,name=a2"` + A3 Enum `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"` + } + MessageB struct { + B1 *MessageA `protobuf:"bytes,1,req,name=b1"` + B2 *MessageB `protobuf:"bytes,2,req,name=b2"` + B3 Enum `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"` + } + Enum int32 +) + +// TestConcurrentInit tests that concurrent wrapping of multiple legacy types +// results in the exact same descriptor being created. +func TestConcurrentInit(t *testing.T) { + const numParallel = 5 + var messageATypes [numParallel]pref.MessageType + var messageBTypes [numParallel]pref.MessageType + var enumDescs [numParallel]pref.EnumDescriptor + + // Concurrently load message and enum types. + var wg sync.WaitGroup + for i := 0; i < numParallel; i++ { + i := i + wg.Add(3) + go func() { + defer wg.Done() + messageATypes[i] = pimpl.Export{}.MessageTypeOf((*MessageA)(nil)) + }() + go func() { + defer wg.Done() + messageBTypes[i] = pimpl.Export{}.MessageTypeOf((*MessageB)(nil)) + }() + go func() { + defer wg.Done() + enumDescs[i] = pimpl.Export{}.EnumDescriptorOf(Enum(0)) + }() + } + wg.Wait() + + var ( + wantMTA = messageATypes[0] + wantMDA = messageATypes[0].Descriptor().Fields().ByNumber(1).Message() + wantMTB = messageBTypes[0] + wantMDB = messageBTypes[0].Descriptor().Fields().ByNumber(2).Message() + wantED = messageATypes[0].Descriptor().Fields().ByNumber(3).Enum() + ) + + for _, gotMT := range messageATypes[1:] { + if gotMT != wantMTA { + t.Error("MessageType(MessageA) mismatch") + } + if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA { + t.Error("MessageDescriptor(MessageA) mismatch") + } + if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB { + t.Error("MessageDescriptor(MessageB) mismatch") + } + if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED { + t.Error("EnumDescriptor(Enum) mismatch") + } + } + for _, gotMT := range messageBTypes[1:] { + if gotMT != wantMTB { + t.Error("MessageType(MessageB) mismatch") + } + if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA { + t.Error("MessageDescriptor(MessageA) mismatch") + } + if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB { + t.Error("MessageDescriptor(MessageB) mismatch") + } + if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED { + t.Error("EnumDescriptor(Enum) mismatch") + } + } + for _, gotED := range enumDescs[1:] { + if gotED != wantED { + t.Error("EnumType(Enum) mismatch") + } + } +} diff --git a/internal/impl/message_field.go b/internal/impl/message_field.go index a69d2c8a..28fc7d14 100644 --- a/internal/impl/message_field.go +++ b/internal/impl/message_field.go @@ -12,6 +12,7 @@ import ( "google.golang.org/protobuf/internal/encoding/wire" pvalue "google.golang.org/protobuf/internal/value" pref "google.golang.org/protobuf/reflect/protoreflect" + piface "google.golang.org/protobuf/runtime/protoiface" ) type fieldInfo struct { @@ -42,7 +43,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, ot refle if !reflect.PtrTo(ot).Implements(ft) { panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft)) } - conv := newConverter(ot.Field(0).Type, fd.Kind()) + conv, _ := newConverter(ot.Field(0).Type, fd.Kind()) fieldOffset := offsetOf(fs) // TODO: Implement unsafe fast path? return fieldInfo{ @@ -97,8 +98,8 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo if ft.Kind() != reflect.Map { panic(fmt.Sprintf("invalid type: got %v, want map kind", ft)) } - keyConv := newConverter(ft.Key(), fd.MapKey().Kind()) - valConv := newConverter(ft.Elem(), fd.MapValue().Kind()) + keyConv, _ := newConverter(ft.Key(), fd.MapKey().Kind()) + valConv, _ := newConverter(ft.Elem(), fd.MapValue().Kind()) wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) fieldOffset := offsetOf(fs) // TODO: Implement unsafe fast path? @@ -139,7 +140,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo if ft.Kind() != reflect.Slice { panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) } - conv := newConverter(ft.Elem(), fd.Kind()) + conv, _ := newConverter(ft.Elem(), fd.Kind()) var wiretag uint64 if !fd.IsPacked() { wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) @@ -194,7 +195,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldIn ft = ft.Elem() } } - conv := newConverter(ft, fd.Kind()) + conv, _ := newConverter(ft, fd.Kind()) fieldOffset := offsetOf(fs) wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) // TODO: Implement unsafe fast path? @@ -264,7 +265,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldIn func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo { ft := fs.Type - conv := newConverter(ft, fd.Kind()) + conv, _ := newConverter(ft, fd.Kind()) fieldOffset := offsetOf(fs) // TODO: Implement unsafe fast path? wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) @@ -338,9 +339,52 @@ func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, wrappersByTy } } -func newConverter(t reflect.Type, k pref.Kind) pvalue.Converter { - if legacyWrapper != nil { - return legacyWrapper.NewConverter(t, k) +var ( + enumIfaceV2 = reflect.TypeOf((*pref.Enum)(nil)).Elem() + messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem() + messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem() +) + +func newConverter(t reflect.Type, k pref.Kind) (conv pvalue.Converter, isLegacy bool) { + switch k { + case pref.EnumKind: + if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) { + return pvalue.Converter{ + PBValueOf: func(v reflect.Value) pref.Value { + if v.Type() != t { + panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t)) + } + return pref.ValueOf(pref.EnumNumber(v.Int())) + }, + GoValueOf: func(v pref.Value) reflect.Value { + return reflect.ValueOf(v.Enum()).Convert(t) + }, + NewEnum: func(n pref.EnumNumber) pref.Enum { + return legacyWrapEnum(reflect.ValueOf(n).Convert(t)) + }, + }, true + } + case pref.MessageKind, pref.GroupKind: + if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) { + return pvalue.Converter{ + PBValueOf: func(v reflect.Value) pref.Value { + if v.Type() != t { + panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t)) + } + return pref.ValueOf(Export{}.MessageOf(v.Interface())) + }, + GoValueOf: func(v pref.Value) reflect.Value { + rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap()) + if rv.Type() != t { + panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t)) + } + return rv + }, + NewMessage: func() pref.Message { + return legacyWrapMessage(reflect.New(t.Elem())).ProtoReflect() + }, + }, true + } } - return pvalue.NewConverter(t, k) + return pvalue.NewConverter(t, k), false } diff --git a/internal/impl/message_field_extension.go b/internal/impl/message_field_extension.go index ada2f872..3c403af9 100644 --- a/internal/impl/message_field_extension.go +++ b/internal/impl/message_field_extension.go @@ -231,14 +231,14 @@ func extensionDescFromType(typ pref.ExtensionType) *piface.ExtensionDescV1 { return desc } } - return legacyWrapper.ExtensionDescFromType(typ) + return Export{}.ExtensionDescFromType(typ) } func extensionTypeFromDesc(desc *piface.ExtensionDescV1) pref.ExtensionType { if desc.Type != nil { return desc.Type } - return legacyWrapper.ExtensionTypeFromDesc(desc) + return Export{}.ExtensionTypeFromDesc(desc) } type ExtensionFieldV1 struct { diff --git a/internal/legacy/export.go b/internal/legacy/export.go deleted file mode 100644 index 701b578d..00000000 --- a/internal/legacy/export.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2018 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 legacy - -import ( - "fmt" - "reflect" - - pimpl "google.golang.org/protobuf/internal/impl" - pvalue "google.golang.org/protobuf/internal/value" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" -) - -// Export is a zero-length named type that exists only to export a set of -// functions that we do not want to appear in godoc. -type Export struct{} - -func (Export) EnumOf(e interface{}) pref.Enum { - return wrapEnum(reflect.ValueOf(e)) -} - -func (Export) EnumTypeOf(e interface{}) pref.EnumType { - return loadEnumType(reflect.TypeOf(e)) -} - -func (Export) EnumDescriptorOf(e interface{}) pref.EnumDescriptor { - return LoadEnumDesc(reflect.TypeOf(e)) -} - -func (Export) MessageOf(m interface{}) pref.Message { - return wrapMessage(reflect.ValueOf(m)).ProtoReflect() -} - -func (Export) MessageTypeOf(m interface{}) pref.MessageType { - return loadMessageInfo(reflect.TypeOf(m)).PBType -} - -func (Export) MessageDescriptorOf(m interface{}) pref.MessageDescriptor { - return LoadMessageDesc(reflect.TypeOf(m)) -} - -func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 { - return extensionDescFromType(t) -} - -func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType { - return extensionTypeFromDesc(d) -} - -var ( - enumIfaceV2 = reflect.TypeOf((*pref.Enum)(nil)).Elem() - messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem() - messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem() -) - -func (Export) NewConverter(t reflect.Type, k pref.Kind) pvalue.Converter { - c, _ := newConverter(t, k) - return c -} - -func newConverter(t reflect.Type, k pref.Kind) (pvalue.Converter, bool) { - switch k { - case pref.EnumKind: - if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) { - return pvalue.Converter{ - PBValueOf: func(v reflect.Value) pref.Value { - if v.Type() != t { - panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t)) - } - return pref.ValueOf(pref.EnumNumber(v.Int())) - }, - GoValueOf: func(v pref.Value) reflect.Value { - return reflect.ValueOf(v.Enum()).Convert(t) - }, - NewEnum: func(n pref.EnumNumber) pref.Enum { - return wrapEnum(reflect.ValueOf(n).Convert(t)) - }, - }, true - } - case pref.MessageKind, pref.GroupKind: - if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) { - return pvalue.Converter{ - PBValueOf: func(v reflect.Value) pref.Value { - if v.Type() != t { - panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t)) - } - return pref.ValueOf(Export{}.MessageOf(v.Interface())) - }, - GoValueOf: func(v pref.Value) reflect.Value { - rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap()) - if rv.Type() != t { - panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t)) - } - return rv - }, - NewMessage: func() pref.Message { - return wrapMessage(reflect.New(t.Elem())).ProtoReflect() - }, - }, true - } - } - return pvalue.NewConverter(t, k), false -} - -func init() { - pimpl.RegisterLegacyWrapper(Export{}) -} diff --git a/internal/legacy/legacy_test.go b/internal/legacy/legacy_test.go deleted file mode 100644 index be57f532..00000000 --- a/internal/legacy/legacy_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// 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 legacy - -import ( - "sync" - "testing" - - "google.golang.org/protobuf/reflect/protoreflect" -) - -type ( - MessageA struct { - A1 *MessageA `protobuf:"bytes,1,req,name=a1"` - A2 *MessageB `protobuf:"bytes,2,req,name=a2"` - A3 Enum `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"` - } - MessageB struct { - B1 *MessageA `protobuf:"bytes,1,req,name=b1"` - B2 *MessageB `protobuf:"bytes,2,req,name=b2"` - B3 Enum `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"` - } - Enum int32 -) - -// TestConcurrentInit tests that concurrent wrapping of multiple legacy types -// results in the exact same descriptor being created. -func TestConcurrentInit(t *testing.T) { - const numParallel = 5 - var messageATypes [numParallel]protoreflect.MessageType - var messageBTypes [numParallel]protoreflect.MessageType - var enumDescs [numParallel]protoreflect.EnumDescriptor - - // Concurrently load message and enum types. - var wg sync.WaitGroup - for i := 0; i < numParallel; i++ { - i := i - wg.Add(3) - go func() { - defer wg.Done() - messageATypes[i] = Export{}.MessageTypeOf((*MessageA)(nil)) - }() - go func() { - defer wg.Done() - messageBTypes[i] = Export{}.MessageTypeOf((*MessageB)(nil)) - }() - go func() { - defer wg.Done() - enumDescs[i] = Export{}.EnumDescriptorOf(Enum(0)) - }() - } - wg.Wait() - - var ( - wantMTA = messageATypes[0] - wantMDA = messageATypes[0].Descriptor().Fields().ByNumber(1).Message() - wantMTB = messageBTypes[0] - wantMDB = messageBTypes[0].Descriptor().Fields().ByNumber(2).Message() - wantED = messageATypes[0].Descriptor().Fields().ByNumber(3).Enum() - ) - - for _, gotMT := range messageATypes[1:] { - if gotMT != wantMTA { - t.Error("MessageType(MessageA) mismatch") - } - if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA { - t.Error("MessageDescriptor(MessageA) mismatch") - } - if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB { - t.Error("MessageDescriptor(MessageB) mismatch") - } - if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED { - t.Error("EnumDescriptor(Enum) mismatch") - } - } - for _, gotMT := range messageBTypes[1:] { - if gotMT != wantMTB { - t.Error("MessageType(MessageB) mismatch") - } - if gotMDA := gotMT.Descriptor().Fields().ByNumber(1).Message(); gotMDA != wantMDA { - t.Error("MessageDescriptor(MessageA) mismatch") - } - if gotMDB := gotMT.Descriptor().Fields().ByNumber(2).Message(); gotMDB != wantMDB { - t.Error("MessageDescriptor(MessageB) mismatch") - } - if gotED := gotMT.Descriptor().Fields().ByNumber(3).Enum(); gotED != wantED { - t.Error("EnumDescriptor(Enum) mismatch") - } - } - for _, gotED := range enumDescs[1:] { - if gotED != wantED { - t.Error("EnumType(Enum) mismatch") - } - } -} diff --git a/runtime/protolegacy/legacy.go b/runtime/protolegacy/legacy.go index b9bad196..14656334 100644 --- a/runtime/protolegacy/legacy.go +++ b/runtime/protolegacy/legacy.go @@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package protolegacy contains the default implementation for messages -// generated by protoc-gen-go. -// -// WARNING: This package should only ever be imported by the v1 proto package. -// The compatibility agreement covers nothing except for functionality needed -// to provide v1 interoperability. Breakages that occur due to unauthorized -// usages of this package are not the author's responsibility. +// Deprecated: Do not use. package protolegacy -import "google.golang.org/protobuf/internal/legacy" +// TODO: Remove this. -var X legacy.Export +import "google.golang.org/protobuf/internal/impl" + +var X impl.Export