github.com/cosmos/cosmos-proto@v1.0.0-beta.3/cmd/protoc-gen-go-pulsar/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "log" 7 "strings" 8 9 _ "github.com/cosmos/cosmos-proto/features/fastreflection" 10 _ "github.com/cosmos/cosmos-proto/features/protoc" 11 "github.com/cosmos/cosmos-proto/generator" 12 "google.golang.org/protobuf/reflect/protoreflect" 13 14 "google.golang.org/protobuf/compiler/protogen" 15 "google.golang.org/protobuf/types/pluginpb" 16 ) 17 18 type ObjectSet map[protogen.GoIdent]bool 19 20 func (o ObjectSet) String() string { 21 return fmt.Sprintf("%#v", o) 22 } 23 24 func (o ObjectSet) Set(s string) error { 25 idx := strings.LastIndexByte(s, '.') 26 if idx < 0 { 27 return fmt.Errorf("invalid object name: %q", s) 28 } 29 30 ident := protogen.GoIdent{ 31 GoImportPath: protogen.GoImportPath(s[0:idx]), 32 GoName: s[idx+1:], 33 } 34 o[ident] = true 35 return nil 36 } 37 38 func main() { 39 var features string 40 poolable := make(ObjectSet) 41 42 var f flag.FlagSet 43 f.Var(poolable, "pool", "use memory pooling for this object") 44 f.StringVar(&features, "features", "all", "list of features to generate (separated by '+')") 45 46 protogen.Options{ParamFunc: f.Set}.Run(func(plugin *protogen.Plugin) error { 47 processedMessages := make(map[protoreflect.FullName]struct{}) 48 for _, file := range plugin.Files { 49 if !file.Generate { 50 continue 51 } 52 for _, message := range file.Messages { 53 rewriteMessageField(message, processedMessages) 54 } 55 } 56 return generateAllFiles(plugin, strings.Split(features, "+"), poolable) 57 }) 58 } 59 60 var SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) 61 62 func generateAllFiles(plugin *protogen.Plugin, featureNames []string, poolable ObjectSet) error { 63 ext := &generator.Extensions{Poolable: poolable} 64 gen, err := generator.NewGenerator(plugin.Files, featureNames, ext) 65 if err != nil { 66 return err 67 } 68 69 for _, file := range plugin.Files { 70 if !file.Generate { 71 continue 72 } 73 74 gf := plugin.NewGeneratedFile(file.GeneratedFilenamePrefix+".pulsar.go", file.GoImportPath) 75 gf.P("// Code generated by protoc-gen-go-pulsar. DO NOT EDIT.") 76 gf.P("package ", file.GoPackageName) 77 if !gen.GenerateFile(plugin, gf, file) { 78 gf.Skip() 79 } 80 } 81 82 // plugin.SupportedFeatures = SupportedFeatures 83 return nil 84 } 85 86 var reservedFieldNames = map[string]struct{}{ 87 "Descriptor": {}, 88 "Type": {}, 89 "New": {}, 90 "Interface": {}, 91 "Range": {}, 92 "Has": {}, 93 "Clear": {}, 94 "Get": {}, 95 "Set": {}, 96 "Mutable": {}, 97 "NewField": {}, 98 "WhichOneof": {}, 99 "GetUnknown": {}, 100 "SetUnknown": {}, 101 "IsValid": {}, 102 "ProtoMethods": {}, 103 } 104 105 func rewriteMessageField(message *protogen.Message, processed map[protoreflect.FullName]struct{}) { 106 // skip already processed messages, useful for recursive messages 107 if _, done := processed[message.Desc.FullName()]; done { 108 return 109 } 110 // skip map entries 111 if message.Desc.IsMapEntry() { 112 return 113 } 114 115 for _, field := range message.Fields { 116 _, reserved := reservedFieldNames[field.GoName] 117 if !reserved { 118 continue 119 } 120 log.Printf("Message %s contains the reserved field name %s which conflicts with protoreflect.Message interface implementation.\nThis field will be suffixed with an underscore '_'.\nIf you can change the message field name, please do so.\nIn a future iteration of pulsar we may make a breaking change to this practice in order to be compliant with field naming of the original golang protobuf implementation.", message.Desc.FullName(), field.Desc.FullName()) 121 field.GoName = field.GoName + "_" 122 } 123 processed[message.Desc.FullName()] = struct{}{} 124 125 for _, nestedMessage := range message.Messages { 126 rewriteMessageField(nestedMessage, processed) 127 } 128 }