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 {