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/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go
index 53d7c96..c58a3ef 100644
--- a/cmd/protoc-gen-go/internal_gengo/reflect.go
+++ b/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -25,7 +25,7 @@
genFileDescriptor(gen, g, f)
if len(f.allEnums) > 0 {
- g.P("var ", enumTypesVarName(f), " = make([]", protoreflectPackage.Ident("EnumType"), ",", len(f.allEnums), ")")
+ g.P("var ", enumTypesVarName(f), " = make([]", prototypePackage.Ident("Enum"), ",", len(f.allEnums), ")")
}
if len(f.allMessages) > 0 {
g.P("var ", messageTypesVarName(f), " = make([]", protoimplPackage.Ident("MessageInfo"), ",", len(f.allMessages), ")")
@@ -73,17 +73,16 @@
}
}
- // This ordering is significant. See protoimpl.FileBuilder.GoTypes.
+ // This ordering is significant.
+ // See filetype.TypeBuilder.DependencyIndexes.
+ var depOffsets []string
for _, enum := range f.allEnums {
genEnum(enum, "")
}
for _, message := range f.allMessages {
genMessage(message, "")
}
- for _, extension := range f.allExtensions {
- source := string(extension.Desc.FullName())
- genMessage(extension.Extendee, source+":extendee")
- }
+ depOffsets = append(depOffsets, fmt.Sprintf("%d, // starting offset of field type_name sub-list", len(depIdxs)))
for _, message := range f.allMessages {
for _, field := range message.Fields {
if field.Desc.IsWeak() {
@@ -94,18 +93,34 @@
genMessage(field.Message, source+":type_name")
}
}
+ depOffsets = append(depOffsets, fmt.Sprintf("%d, // starting offset of extension extendee sub-list", len(depIdxs)))
+ for _, extension := range f.allExtensions {
+ source := string(extension.Desc.FullName())
+ genMessage(extension.Extendee, source+":extendee")
+ }
+ depOffsets = append(depOffsets, fmt.Sprintf("%d, // starting offset of extension type_name sub-list", len(depIdxs)))
for _, extension := range f.allExtensions {
source := string(extension.Desc.FullName())
genEnum(extension.Enum, source+":type_name")
genMessage(extension.Message, source+":type_name")
}
+ depOffsets = append(depOffsets, fmt.Sprintf("%d, // starting offset of method input_type sub-list", len(depIdxs)))
for _, service := range f.Services {
for _, method := range service.Methods {
source := string(method.Desc.FullName())
genMessage(method.Input, source+":input_type")
+ }
+ }
+ depOffsets = append(depOffsets, fmt.Sprintf("%d, // starting offset of method output_type sub-list", len(depIdxs)))
+ for _, service := range f.Services {
+ for _, method := range service.Methods {
+ source := string(method.Desc.FullName())
genMessage(method.Output, source+":output_type")
}
}
+ for i := len(depOffsets) - 1; i >= 0; i-- {
+ depIdxs = append(depIdxs, depOffsets[i])
+ }
if len(depIdxs) > math.MaxInt32 {
panic("too many dependencies") // sanity check
}
@@ -140,29 +155,27 @@
g.P(initFuncName(impFile), "()")
}
- if len(f.allExtensions) > 0 {
- g.P("extensionTypes := make([]", protoreflectPackage.Ident("ExtensionType"), ",", len(f.allExtensions), ")")
- }
-
- g.P(f.GoDescriptorIdent, " = ", protoimplPackage.Ident("FileBuilder"), "{")
+ g.P("out := ", protoimplPackage.Ident("TypeBuilder"), "{")
+ g.P("File: ", protoimplPackage.Ident("DescBuilder"), "{")
g.P("RawDescriptor: ", rawDescVarName(f), ",")
+ g.P("NumEnums: ", len(f.allEnums), ",")
+ g.P("NumMessages: ", len(f.allMessages), ",")
+ g.P("NumExtensions: ", len(f.allExtensions), ",")
+ g.P("NumServices: ", len(f.Services), ",")
+ g.P("},")
g.P("GoTypes: ", goTypesVarName(f), ",")
g.P("DependencyIndexes: ", depIdxsVarName(f), ",")
- if len(f.allExtensions) > 0 {
- g.P("LegacyExtensions: ", extDecsVarName(f), ",")
- }
- if len(f.allEnums) > 0 {
- g.P("EnumOutputTypes: ", enumTypesVarName(f), ",")
- }
if len(f.allMessages) > 0 {
- g.P("MessageOutputTypes: ", messageTypesVarName(f), ",")
+ g.P("MessageInfos: ", messageTypesVarName(f), ",")
}
if len(f.allExtensions) > 0 {
- g.P("ExtensionOutputTypes: extensionTypes,")
+ g.P("LegacyExtensions: ", extDescsVarName(f), ",")
}
- g.P("FilesRegistry: ", protoregistryPackage.Ident("GlobalFiles"), ",")
- g.P("TypesRegistry: ", protoregistryPackage.Ident("GlobalTypes"), ",")
- g.P("}.Init()")
+ g.P("}.Build()")
+ g.P(f.GoDescriptorIdent, " = out.File")
+ if len(f.allEnums) > 0 {
+ g.P(enumTypesVarName(f), " = out.Enums")
+ }
// Set inputs to nil to allow GC to reclaim resources.
g.P(rawDescVarName(f), " = nil")
@@ -235,7 +248,7 @@
// Descriptor method.
g.P("func (", enum.GoIdent, ") Descriptor() ", protoreflectPackage.Ident("EnumDescriptor"), " {")
- g.P("return ", typesVar, "[", idx, "].Descriptor()")
+ g.P("return ", typesVar, "[", idx, "].EnumDescriptor")
g.P("}")
g.P()
@@ -281,7 +294,7 @@
func messageTypesVarName(f *fileInfo) string {
return fileVarName(f.File, "msgTypes")
}
-func extDecsVarName(f *fileInfo) string {
+func extDescsVarName(f *fileInfo) string {
return fileVarName(f.File, "extDescs")
}
func initFuncName(f *protogen.File) string {