internal/filedesc, internal/filetype: initial commit
The internal/fileinit package is split apart into two packages:
* internal/filedesc constructs descriptors from the raw proto.
It is very similar to the previous internal/fileinit package.
* internal/filetype wraps descriptors with Go type information
Overview:
* The internal/fileinit package will be deleted in a future CL.
It is kept around since the v1 repo currently depends on it.
* The internal/prototype package is deleted. All former usages of it
are now using internal/filedesc instead. Most significantly,
the reflect/protodesc package was almost entirely re-written.
* The internal/impl package drops support for messages that do not
have a Descriptor method (pre-2016). This removes a significant amount
of technical debt.
filedesc.Builder to parse raw descriptors.
* The internal/encoding/defval package now handles enum values by name.
Change-Id: I3957bcc8588a70470fd6c7de1122216b80615ab7
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/182360
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/legacy_extension.go b/internal/impl/legacy_extension.go
index 33ca82c..ca3475f 100644
--- a/internal/impl/legacy_extension.go
+++ b/internal/impl/legacy_extension.go
@@ -11,7 +11,7 @@
"google.golang.org/protobuf/internal/descfmt"
ptag "google.golang.org/protobuf/internal/encoding/tag"
- ptype "google.golang.org/protobuf/internal/prototype"
+ "google.golang.org/protobuf/internal/filedesc"
pvalue "google.golang.org/protobuf/internal/value"
pref "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry"
@@ -112,7 +112,7 @@
}
if ed, ok := reflect.Zero(t).Interface().(enumV1); ok && protoPkg == "" {
b, _ := ed.EnumDescriptor()
- protoPkg = legacyLoadFileDesc(b).GetPackage()
+ protoPkg = string(legacyLoadFileDesc(b).Package())
}
if protoPkg != "" {
@@ -159,46 +159,45 @@
return t.(pref.ExtensionType)
}
- // Derive basic field information from the struct tag.
+ // Resolve enum or message dependencies.
+ var ed pref.EnumDescriptor
+ var md pref.MessageDescriptor
t := reflect.TypeOf(d.ExtensionType)
isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
if isOptional || isRepeated {
t = t.Elem()
}
- f := ptag.Unmarshal(d.Tag, t)
+ switch v := reflect.Zero(t).Interface().(type) {
+ case pref.Enum:
+ ed = v.Descriptor()
+ case enumV1:
+ ed = LegacyLoadEnumDesc(t)
+ case pref.ProtoMessage:
+ md = v.ProtoReflect().Descriptor()
+ case messageV1:
+ md = LegacyLoadMessageDesc(t)
+ }
+
+ // Derive basic field information from the struct tag.
+ var evs pref.EnumValueDescriptors
+ if ed != nil {
+ evs = ed.Values()
+ }
+ fd := ptag.Unmarshal(d.Tag, t, evs).(*filedesc.Field)
// Construct a v2 ExtensionType.
- var ed pref.EnumDescriptor
- var md pref.MessageDescriptor
- switch f.Kind {
- case pref.EnumKind:
- if e, ok := reflect.Zero(t).Interface().(pref.Enum); ok {
- ed = e.Descriptor()
- } else {
- ed = LegacyLoadEnumDesc(t)
- }
- case pref.MessageKind, pref.GroupKind:
- if m, ok := reflect.Zero(t).Interface().(pref.ProtoMessage); ok {
- md = m.ProtoReflect().Descriptor()
- } else {
- md = LegacyLoadMessageDesc(t)
- }
- }
- xd, err := ptype.NewExtension(&ptype.StandaloneExtension{
- FullName: pref.FullName(d.Name),
- Number: pref.FieldNumber(d.Field),
- Cardinality: f.Cardinality,
- Kind: f.Kind,
- Default: f.Default,
- Options: f.Options,
- EnumType: ed,
- MessageType: md,
- ExtendedType: Export{}.MessageDescriptorOf(d.ExtendedType),
- })
- if err != nil {
- panic(err)
- }
+ xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
+ xd.L0.ParentFile = filedesc.SurrogateProto2
+ xd.L0.FullName = pref.FullName(d.Name)
+ xd.L1.Number = pref.FieldNumber(d.Field)
+ xd.L2.Cardinality = fd.L1.Cardinality
+ xd.L1.Kind = fd.L1.Kind
+ xd.L2.IsPacked = fd.L1.IsPacked
+ xd.L2.Default = fd.L1.Default
+ xd.L1.Extendee = Export{}.MessageDescriptorOf(d.ExtendedType)
+ xd.L2.Enum = ed
+ xd.L2.Message = md
xt := LegacyExtensionTypeOf(xd, t)
// Cache the conversion for both directions.