mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-02-05 15:40:09 +00:00
internal/impl: handle legacy ExtensionDesc form
Add support for an ExtensionDesc with only Field populated as returned by protoV1.ExtensionDescs. Rather than panicking when TypeDescriptor is called, return a placeholder that preserves the name and/or number. Change-Id: I60352a7aec8ccd8a0c1fb08db5891043a441695f Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/193725 Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
6e095998ae
commit
bee625258d
@ -140,10 +140,12 @@ func (xi *ExtensionInfo) lazyInitSlow() {
|
|||||||
if xi.desc.ExtensionDescriptor == nil {
|
if xi.desc.ExtensionDescriptor == nil {
|
||||||
xi.initFromLegacy()
|
xi.initFromLegacy()
|
||||||
}
|
}
|
||||||
if xi.ExtensionType == nil {
|
if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
|
||||||
xi.initToLegacy()
|
if xi.ExtensionType == nil {
|
||||||
|
xi.initToLegacy()
|
||||||
|
}
|
||||||
|
xi.conv = NewConverter(xi.goType, xi.desc)
|
||||||
}
|
}
|
||||||
xi.conv = NewConverter(xi.goType, xi.desc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type extensionTypeDescriptor struct {
|
type extensionTypeDescriptor struct {
|
||||||
|
@ -180,7 +180,7 @@ func (OneofMessage) isOneofUnion() {}
|
|||||||
|
|
||||||
type AberrantEnum int32
|
type AberrantEnum int32
|
||||||
|
|
||||||
func TestAberrant(t *testing.T) {
|
func TestAberrantMessages(t *testing.T) {
|
||||||
want := new(descriptorpb.DescriptorProto)
|
want := new(descriptorpb.DescriptorProto)
|
||||||
if err := prototext.Unmarshal([]byte(`
|
if err := prototext.Unmarshal([]byte(`
|
||||||
name: "AberrantMessage"
|
name: "AberrantMessage"
|
||||||
@ -320,3 +320,34 @@ func TestAberrantRace(t *testing.T) {
|
|||||||
t.Errorf("mismatching exact message descriptors")
|
t.Errorf("mismatching exact message descriptors")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAberrantExtensions(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in *impl.ExtensionInfo
|
||||||
|
wantName protoreflect.FullName
|
||||||
|
wantNumber protoreflect.FieldNumber
|
||||||
|
wantPlaceholder bool
|
||||||
|
}{{
|
||||||
|
in: &impl.ExtensionInfo{Field: 500},
|
||||||
|
wantNumber: 500,
|
||||||
|
wantPlaceholder: true,
|
||||||
|
}, {
|
||||||
|
in: &impl.ExtensionInfo{Name: "foo.bar.baz"},
|
||||||
|
wantName: "foo.bar.baz",
|
||||||
|
wantPlaceholder: true,
|
||||||
|
}}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
xtd := tt.in.TypeDescriptor()
|
||||||
|
switch {
|
||||||
|
case xtd.FullName() != tt.wantName:
|
||||||
|
t.Errorf("FullName() = %v, want %v", xtd.FullName(), tt.wantName)
|
||||||
|
case xtd.Number() != tt.wantNumber:
|
||||||
|
t.Errorf("Number() = %v, want %v", xtd.Number(), tt.wantNumber)
|
||||||
|
case xtd.IsPlaceholder() != tt.wantPlaceholder:
|
||||||
|
t.Errorf("IsPlaceholder() = %v, want %v", xtd.IsPlaceholder(), tt.wantPlaceholder)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,9 +7,11 @@ package impl
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/internal/descopts"
|
||||||
"google.golang.org/protobuf/internal/encoding/messageset"
|
"google.golang.org/protobuf/internal/encoding/messageset"
|
||||||
ptag "google.golang.org/protobuf/internal/encoding/tag"
|
ptag "google.golang.org/protobuf/internal/encoding/tag"
|
||||||
"google.golang.org/protobuf/internal/filedesc"
|
"google.golang.org/protobuf/internal/filedesc"
|
||||||
|
"google.golang.org/protobuf/internal/pragma"
|
||||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
@ -71,6 +73,17 @@ func (xi *ExtensionInfo) initToLegacy() {
|
|||||||
// initFromLegacy initializes an ExtensionInfo from
|
// initFromLegacy initializes an ExtensionInfo from
|
||||||
// the contents of the deprecated exported fields of the type.
|
// the contents of the deprecated exported fields of the type.
|
||||||
func (xi *ExtensionInfo) initFromLegacy() {
|
func (xi *ExtensionInfo) initFromLegacy() {
|
||||||
|
// The v1 API returns "type incomplete" descriptors where only the
|
||||||
|
// field number is specified. In such a case, use a placeholder.
|
||||||
|
if xi.ExtendedType == nil || xi.ExtensionType == nil {
|
||||||
|
xd := placeholderExtension{
|
||||||
|
name: pref.FullName(xi.Name),
|
||||||
|
number: pref.FieldNumber(xi.Field),
|
||||||
|
}
|
||||||
|
xi.desc = extensionTypeDescriptor{xd, xi}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve enum or message dependencies.
|
// Resolve enum or message dependencies.
|
||||||
var ed pref.EnumDescriptor
|
var ed pref.EnumDescriptor
|
||||||
var md pref.MessageDescriptor
|
var md pref.MessageDescriptor
|
||||||
@ -123,3 +136,38 @@ func (xi *ExtensionInfo) initFromLegacy() {
|
|||||||
xi.goType = tt
|
xi.goType = tt
|
||||||
xi.desc = extensionTypeDescriptor{xd, xi}
|
xi.desc = extensionTypeDescriptor{xd, xi}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type placeholderExtension struct {
|
||||||
|
name pref.FullName
|
||||||
|
number pref.FieldNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x placeholderExtension) ParentFile() pref.FileDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) Parent() pref.Descriptor { return nil }
|
||||||
|
func (x placeholderExtension) Index() int { return 0 }
|
||||||
|
func (x placeholderExtension) Syntax() pref.Syntax { return 0 }
|
||||||
|
func (x placeholderExtension) Name() pref.Name { return x.name.Name() }
|
||||||
|
func (x placeholderExtension) FullName() pref.FullName { return x.name }
|
||||||
|
func (x placeholderExtension) IsPlaceholder() bool { return true }
|
||||||
|
func (x placeholderExtension) Options() pref.ProtoMessage { return descopts.Field }
|
||||||
|
func (x placeholderExtension) Number() pref.FieldNumber { return x.number }
|
||||||
|
func (x placeholderExtension) Cardinality() pref.Cardinality { return 0 }
|
||||||
|
func (x placeholderExtension) Kind() pref.Kind { return 0 }
|
||||||
|
func (x placeholderExtension) HasJSONName() bool { return false }
|
||||||
|
func (x placeholderExtension) JSONName() string { return "" }
|
||||||
|
func (x placeholderExtension) IsExtension() bool { return true }
|
||||||
|
func (x placeholderExtension) IsWeak() bool { return false }
|
||||||
|
func (x placeholderExtension) IsPacked() bool { return false }
|
||||||
|
func (x placeholderExtension) IsList() bool { return false }
|
||||||
|
func (x placeholderExtension) IsMap() bool { return false }
|
||||||
|
func (x placeholderExtension) MapKey() pref.FieldDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) MapValue() pref.FieldDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) HasDefault() bool { return false }
|
||||||
|
func (x placeholderExtension) Default() pref.Value { return pref.Value{} }
|
||||||
|
func (x placeholderExtension) DefaultEnumValue() pref.EnumValueDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) ContainingOneof() pref.OneofDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) ContainingMessage() pref.MessageDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) Enum() pref.EnumDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) Message() pref.MessageDescriptor { return nil }
|
||||||
|
func (x placeholderExtension) ProtoType(pref.FieldDescriptor) { return }
|
||||||
|
func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user