@@ -3,7 +3,6 @@ package main
33import (
44 "errors"
55 "fmt"
6- "regexp"
76 "strings"
87
98 "google.golang.org/protobuf/types/descriptorpb"
@@ -28,99 +27,122 @@ func (b *contentBuilder) build(protoFile *descriptorpb.FileDescriptorProto) (str
2827 }
2928
3029 compVersion := b .request .GetCompilerVersion ()
31- fmt .Fprintln (b .output , "// Code generated by protoc-gen-pubsub-schema. DO NOT EDIT." )
32- fmt .Fprintln (b .output , "// versions:" )
33- fmt .Fprintln (b .output , "// protoc-gen-pubsub-schema v1.4.2 " )
30+ fmt .Fprintf (b .output , "// Code generated by protoc-gen-pubsub-schema. DO NOT EDIT.\n " )
31+ fmt .Fprintf (b .output , "// versions:\n " )
32+ fmt .Fprintf (b .output , "// protoc-gen-pubsub-schema v1.5.0 \n " )
3433 fmt .Fprintf (b .output , "// protoc v%d.%d.%d%s\n " , compVersion .GetMajor (), compVersion .GetMinor (), compVersion .GetPatch (), compVersion .GetSuffix ())
35- fmt .Fprintln (b .output , "// source:" , protoFile .GetName ())
36- fmt .Fprintln (b .output , "" )
37- fmt .Fprintf (b .output , `syntax = "%s";` , b .schemaSyntax )
38- b .output .WriteString ("\n \n " )
39- b .buildMessage (protoFile .GetMessageType ()[0 ], 0 )
34+ fmt .Fprintf (b .output , "// source: %s\n \n " , protoFile .GetName ())
35+ fmt .Fprintf (b .output , "syntax = \" %s\" ;\n " , b .schemaSyntax )
36+ b .buildMessages (protoFile .GetMessageType (), 0 )
37+ b .buildEnums (protoFile .GetEnumType (), 0 )
4038 return b .output .String (), nil
4139}
4240
41+ func (b * contentBuilder ) buildMessages (messages []* descriptorpb.DescriptorProto , level int ) {
42+ for _ , message := range messages {
43+ fmt .Fprintln (b .output )
44+ b .buildMessage (message , level )
45+ }
46+ }
47+
4348func (b * contentBuilder ) buildMessage (message * descriptorpb.DescriptorProto , level int ) {
4449 fmt .Fprintf (b .output , "%smessage %s {\n " , buildIndent (level ), message .GetName ())
45- debts := []string (nil )
46- for _ , field := range message .GetField () {
47- debts = append (debts , b .buildField (field , level + 1 ))
48- }
49- b .payDebts (debts , level + 1 )
50+ b .buildFields (message .GetField (), level + 1 )
51+ b .buildMessages (message .GetNestedType (), level + 1 )
52+ b .buildEnums (message .GetEnumType (), level + 1 )
53+ b .buildOtherTypes (message , level + 1 )
5054 fmt .Fprintf (b .output , "%s}\n " , buildIndent (level ))
5155}
5256
53- func (b * contentBuilder ) buildField (field * descriptorpb.FieldDescriptorProto , level int ) string {
54- fieldType , debt := b .getFieldType (field )
55- fmt .Fprintf (b .output , "%s%s%s %s = %d;\n " ,
56- buildIndent (level ),
57- b .getLabelPrefix (field .GetLabel ()),
58- fieldType ,
59- field .GetName (),
60- field .GetNumber (),
61- )
62- return debt
57+ func (b * contentBuilder ) buildFields (fields []* descriptorpb.FieldDescriptorProto , level int ) {
58+ for _ , field := range fields {
59+ fmt .Fprint (b .output , buildIndent (level ))
60+ label := field .GetLabel ()
61+ if b .schemaSyntax == "proto2" || label == descriptorpb .FieldDescriptorProto_LABEL_REPEATED {
62+ fmt .Fprintf (b .output , "%s " , strings .ToLower (strings .TrimPrefix (label .String (), "LABEL_" )))
63+ }
64+ fmt .Fprintf (b .output , "%s %s = %d;\n " , b .getFieldType (field ), field .GetName (), field .GetNumber ())
65+ }
6366}
6467
65- func (b * contentBuilder ) getFieldType (field * descriptorpb.FieldDescriptorProto ) (string , string ) {
66- if field .GetType () != descriptorpb .FieldDescriptorProto_TYPE_MESSAGE {
67- return strings .ToLower (strings .TrimPrefix (field .GetType ().String (), "TYPE_" )), ""
68- }
69- fullMessageName := field .GetTypeName ()
70- if b .messageEncoding == "json" {
71- if wkt , ok := wktMapping [fullMessageName ]; ok {
72- return wkt , ""
68+ func (b * contentBuilder ) getFieldType (field * descriptorpb.FieldDescriptorProto ) string {
69+ typeName := field .GetTypeName ()
70+ switch field .GetType () {
71+ case descriptorpb .FieldDescriptorProto_TYPE_MESSAGE :
72+ if b .messageEncoding == "json" && wktMapping [typeName ] != "" {
73+ return wktMapping [typeName ]
74+ }
75+ if b .isNestedType (typeName ) {
76+ return shortName (typeName )
7377 }
78+ return pascalCase (typeName )
79+ case descriptorpb .FieldDescriptorProto_TYPE_ENUM :
80+ return shortName (typeName )
81+ default :
82+ return strings .ToLower (strings .TrimPrefix (field .GetType ().String (), "TYPE_" ))
7483 }
75- return b .getLocalName (fullMessageName ), fullMessageName
7684}
7785
78- func (b * contentBuilder ) getLabelPrefix (label descriptorpb.FieldDescriptorProto_Label ) string {
79- if label == descriptorpb .FieldDescriptorProto_LABEL_REPEATED {
80- return "repeated "
81- }
82- if b .schemaSyntax == "proto2" {
83- return strings .ToLower (strings .TrimPrefix (label .String (), "LABEL_" )) + " "
86+ func (b * contentBuilder ) buildEnums (enums []* descriptorpb.EnumDescriptorProto , level int ) {
87+ for _ , enum := range enums {
88+ fmt .Fprintln (b .output )
89+ fmt .Fprintf (b .output , "%senum %s {\n " , buildIndent (level ), enum .GetName ())
90+ for _ , value := range enum .GetValue () {
91+ fmt .Fprintf (b .output , "%s%s = %d;\n " , buildIndent (level + 1 ), value .GetName (), value .GetNumber ())
92+ }
93+ fmt .Fprintf (b .output , "%s}\n " , buildIndent (level ))
8494 }
85- return ""
8695}
8796
88- func (b * contentBuilder ) payDebts ( debts [] string , level int ) {
89- payedDebts := make (map [string ]bool )
90- for _ , debt := range debts {
91- if debt != "" && ! payedDebts [ debt ] {
92- b . payDebt ( debt , level )
93- payedDebts [ debt ] = true
97+ func (b * contentBuilder ) buildOtherTypes ( message * descriptorpb. DescriptorProto , level int ) {
98+ built := make (map [string ]bool )
99+ for _ , field := range message . GetField () {
100+ typeName := field . GetTypeName ()
101+ if field . GetType () != descriptorpb . FieldDescriptorProto_TYPE_MESSAGE {
102+ continue
94103 }
104+ if b .messageEncoding == "json" && wktMapping [typeName ] != "" {
105+ continue
106+ }
107+ if b .isNestedType (typeName ) {
108+ continue
109+ }
110+ if built [typeName ] {
111+ continue
112+ }
113+ b .buildOtherType (typeName , level )
114+ built [typeName ] = true
95115 }
96116}
97117
98- func (b * contentBuilder ) payDebt (debt string , level int ) {
99- message := b .messageTypes [debt ]
100- defer func (originalName * string ) { message .Name = originalName }(message .Name )
101- localName := b .getLocalName (debt )
102- message .Name = & localName
103- b .output .WriteString ("\n " )
118+ func (b * contentBuilder ) buildOtherType (typeName string , level int ) {
119+ message := b .messageTypes [typeName ]
120+ defer func (name * string ) { message .Name = name }(message .Name )
121+ * message .Name = pascalCase (typeName )
122+ fmt .Fprintln (b .output )
104123 b .buildMessage (message , level )
105124}
106125
107- var localNamePattern = regexp .MustCompile (`\..` )
126+ func (b * contentBuilder ) isNestedType (name string ) bool {
127+ return b .messageTypes [name [:strings .LastIndexByte (name , '.' )]] != nil
128+ }
108129
109- func (b * contentBuilder ) getLocalName (fullMessageName string ) string {
110- if b .isNestedType (fullMessageName ) {
111- return fullMessageName [strings .LastIndexByte (fullMessageName , '.' )+ 1 :]
112- }
113- return localNamePattern .ReplaceAllStringFunc (
114- fullMessageName ,
115- func (s string ) string { return strings .ToUpper (s [1 :]) },
116- )
130+ func buildIndent (level int ) string {
131+ return strings .Repeat (" " , level )
117132}
118133
119- func (b * contentBuilder ) isNestedType (fullMessageName string ) bool {
120- parent := fullMessageName [:strings .LastIndexByte (fullMessageName , '.' )]
121- return b .messageTypes [parent ] != nil
134+ func shortName (name string ) string {
135+ return name [strings .LastIndexByte (name , '.' )+ 1 :]
122136}
123137
124- func buildIndent (level int ) string {
125- return strings .Repeat (" " , level )
138+ func pascalCase (name string ) string {
139+ sb := new (strings.Builder )
140+ for i , c := range name {
141+ if i > 0 && name [i - 1 ] == '.' {
142+ sb .WriteString (strings .ToUpper (string (c )))
143+ } else if c != '.' {
144+ sb .WriteRune (c )
145+ }
146+ }
147+ return sb .String ()
126148}
0 commit comments