Generates a type registry file based off of a set of types
discovered during runtime, similar to go stringer. Used to generate
a Map of names to reflect.Type
from a Protobuf gRPC plugin.
type-registry -in mytypes.pb.go
Scans mytypes.pb.go and writes out a map of name to each struct
defined in that file, by default the output file is
<inputfile>.typeregistry.go
.
-
-in
Input file to generate type registry from.
-
-out
Output file name; defaults to infile.typeregistry.go
-
-package
Package name to use in outfile; defaults to package name from infile.
-
-registryfield
Name of the field to declare the registry under; defaults to
typeregistry
-
-typenameprefix
A prefix added to the type name values emitted.
This feature allows generating the type registry of all the gRPC / protobuffer wrapper types. For example, we want to map a message of type
Ping
to the wrapper typeGameMessage_Ping
:typeregistry["Ping"] = reflect.TypeOf(GameMessage_Ping{})
This requires using a typenameprefix of "GameMessage_".
Note that this feature only generates type names that are valid structs contained within the infile: if
GameMessage_Ping
does not exist or is not a struct, "Ping" will be emitted instead:typeregistry["Ping"] = reflect.TypeOf(Ping{})
From command line, to take an input file from message.pb.go and create a registry mapping the structs in that file to their wrapper structs:
$ type-registry -in testdata/message.pb.go -typenameprefix GameMessage_
This creates an output file testdata/message.pb.typeregistry.go
:
// Code generated by "type-registry -in ./message.pb.go -typenameprefix GameMessage_"; DO NOT EDIT.
package message
import "reflect"
var typeregistry = make(map[string]reflect.Type)
func init() {
typeregistry["GameMessage_GetNotification"] = reflect.TypeOf(GameMessage_GetNotification{})
typeregistry["DropRequest"] = reflect.TypeOf(GameMessage_DropRequest{})
typeregistry["ErrorRequest"] = reflect.TypeOf(GameMessage_ErrorRequest{})
typeregistry["ErrorResponse"] = reflect.TypeOf(GameMessage_ErrorResponse{})
typeregistry["GetNotification"] = reflect.TypeOf(GameMessage_GetNotification{})
typeregistry["GameMessage_LoginRequest"] = reflect.TypeOf(GameMessage_LoginRequest{})
// etc. etc. etc.
}
This tool is meant to be used with go:generate for converting .proto files into .proto.go files, and then creating type registries of the structs found in that .proto.go file:
package message
//go:generate protoc -I . message.proto --go_out=plugins=grpc:.
//go:generate type-registry -in ./message.pb.go -typenameprefix GameMessage_
func BuildGameMessageUsingLotsOfReflection(payload interface{}) (result *GameMessage, err error) {
// find the wrapper type for our payload
wrapperType := typeregistry[reflect.TypeOf(payload).Name()]
// do a bunch more stuff...
return
}