Skip to content

Commit dd3d3ed

Browse files
committed
put generate function into seperate file
1 parent e89ca79 commit dd3d3ed

File tree

6 files changed

+205
-185
lines changed

6 files changed

+205
-185
lines changed

example/output.proto

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,36 @@ option go_package = 'generated/proto;pb';
55

66
package example.com;
77

8+
message Base {
9+
int64 id = 1;
10+
}
11+
12+
// extends example.com.Base
13+
message Intermediate {
14+
int64 id = 1;
15+
int64 createdAt = 2;
16+
int64 updatedAt = 3;
17+
}
18+
19+
820
message groups {
21+
// extends example.com.Intermediate
922
message Group {
10-
11-
// ↓↓↓↓↓ extends Intermediate
12-
// ↓↓↓↓↓ extends Base
1323
int64 id = 1;
14-
// ↑↑↑↑↑ extends Base
15-
1624
int64 createdAt = 2;
1725
int64 updatedAt = 3;
18-
// ↑↑↑↑↑ extends Intermediate
19-
2026
string name = 11;
2127
repeated users.User users = 12;
2228
}
2329

2430
}
2531

2632
message users {
33+
// extends example.com.Intermediate
2734
message User {
28-
29-
// ↓↓↓↓↓ extends Intermediate
30-
// ↓↓↓↓↓ extends Base
3135
int64 id = 1;
32-
// ↑↑↑↑↑ extends Base
33-
3436
int64 createdAt = 2;
3537
int64 updatedAt = 3;
36-
// ↑↑↑↑↑ extends Intermediate
37-
3838
string name = 11;
3939
string email = 12;
4040
string password = 13;
@@ -43,18 +43,3 @@ message users {
4343

4444
}
4545

46-
message Base {
47-
int64 id = 1;
48-
}
49-
50-
message Intermediate {
51-
52-
// ↓↓↓↓↓ extends Base
53-
int64 id = 1;
54-
// ↑↑↑↑↑ extends Base
55-
56-
int64 createdAt = 2;
57-
int64 updatedAt = 3;
58-
}
59-
60-

main.go

Lines changed: 33 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package main
22

33
import (
4-
"bytes"
54
"fmt"
65
"io/fs"
76
"log"
87
"os"
98
"path/filepath"
10-
"strconv"
9+
"sort"
1110
"strings"
1211

1312
"github.com/jhump/protoreflect/desc/protoparse"
1413
"github.com/samber/lo"
1514
"github.com/spf13/pflag"
1615
"google.golang.org/protobuf/types/descriptorpb"
16+
17+
oneprotou_til "github.com/joesonw/oneproto/util"
1718
)
1819

1920
var (
@@ -23,6 +24,7 @@ var (
2324
pPackage = pflag.StringP("package", "P", "", "package name")
2425

2526
allMessageDescriptors = map[string]*descriptorpb.DescriptorProto{}
27+
parentResolvedMap = map[*descriptorpb.DescriptorProto]bool{}
2628
)
2729

2830
func main() {
@@ -51,15 +53,17 @@ func main() {
5153
os.Exit(1)
5254
}
5355

54-
parser := protoparse.Parser{}
56+
parser := protoparse.Parser{
57+
IncludeSourceCodeInfo: true,
58+
}
5559
files, err := parser.ParseFilesButDoNotLink(lo.Map(entries, func(entry string, index int) string {
5660
return filepath.Join(*pInclude, entry)
5761
})...)
5862
if err != nil {
5963
log.Fatalln(err)
6064
}
6165

62-
buf := &Buffer{buf: &bytes.Buffer{}}
66+
buf := oneprotou_til.NewBuffer()
6367
buf.Printf(string(templateContent))
6468

6569
// group files by package name
@@ -83,17 +87,21 @@ func main() {
8387

8488
for _, file := range packageFiles {
8589
for _, enum := range file.EnumType {
86-
generateEnum(buf, indentLevel, enum)
90+
oneprotou_til.GenerateEnum(buf, indentLevel, enum)
8791
buf.Printf("")
8892
}
8993

9094
for _, service := range file.Service {
91-
generateService(buf, indentLevel, service)
95+
oneprotou_til.GenerateService(buf, indentLevel, service)
9296
buf.Printf("")
9397
}
9498

9599
for _, message := range file.GetMessageType() {
96-
generateMessage(buf, indentLevel, message)
100+
message.Field = append(message.Field, resolveMessageExtends(buf, indentLevel, message)...)
101+
sort.Slice(message.Field, func(i, j int) bool {
102+
return message.Field[i].GetNumber() < message.Field[j].GetNumber()
103+
})
104+
oneprotou_til.GenerateMessage(buf, indentLevel, message)
97105
buf.Printf("")
98106
}
99107
}
@@ -108,152 +116,29 @@ func main() {
108116
}
109117
}
110118

111-
type Buffer struct {
112-
buf *bytes.Buffer
113-
}
114-
115-
func (b *Buffer) Printf(f string, i ...any) {
116-
_, _ = b.buf.WriteString(fmt.Sprintf(f+"\n", i...))
117-
}
118-
119-
func (b *Buffer) String() string {
120-
return b.buf.String()
121-
}
122-
123-
func (b *Buffer) Bytes() []byte {
124-
return b.buf.Bytes()
125-
}
126-
127-
func stringifyUninterpretedOption(opt *descriptorpb.UninterpretedOption) string {
128-
var value string
129-
if v := opt.IdentifierValue; v != nil {
130-
value = *v
131-
} else if v := opt.DoubleValue; v != nil {
132-
value = strconv.FormatFloat(*v, 'f', -1, 64)
133-
} else if v := opt.AggregateValue; v != nil {
134-
value = fmt.Sprintf("{%s}", *v)
135-
} else if v := opt.StringValue; v != nil {
136-
value = fmt.Sprintf("'%s'", v)
137-
} else if v := opt.PositiveIntValue; v != nil {
138-
value = strconv.Itoa(int(*v))
139-
} else if v := opt.NegativeIntValue; v != nil {
140-
value = strconv.Itoa(int(*v))
141-
}
142-
return fmt.Sprintf("(%s) = %s", strings.Join(lo.Map(opt.GetName(), func(name *descriptorpb.UninterpretedOption_NamePart, index int) string {
143-
return name.GetNamePart()
144-
}), ","), value)
145-
}
146-
147-
func stringifyField(message *descriptorpb.DescriptorProto, field *descriptorpb.FieldDescriptorProto) string {
148-
repeated := field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED
149-
if field.Type == nil {
150-
name := field.GetTypeName()
151-
for _, nested := range message.NestedType {
152-
if name == nested.GetName() && strings.HasSuffix(name, "Entry") { // map entry
153-
return fmt.Sprintf("map<%s,%s>", stringifyField(nested, nested.Field[0]), stringifyField(nested, nested.Field[1]))
154-
}
155-
}
156-
if repeated {
157-
return "repeated " + name
158-
}
159-
return name
160-
}
161-
name := strings.ToLower(field.GetType().String()[5:])
162-
if repeated {
163-
name = "repeated " + name
164-
}
165-
return name
166-
}
167-
168-
func generateService(buf *Buffer, indentLevel int, service *descriptorpb.ServiceDescriptorProto) {
169-
indent := strings.Repeat(" ", indentLevel*4)
170-
buf.Printf("%sservice %s {", indent, service.GetName())
171-
generateHeadOptions(buf, indent, service.GetOptions().GetUninterpretedOption())
172-
for _, method := range service.Method {
173-
buf.Printf("%s rpc %s(%s) returns (%s) {", indent, method.GetName(), method.GetInputType(), method.GetOutputType())
174-
for _, opt := range method.GetOptions().GetUninterpretedOption() {
175-
buf.Printf("%s option %s;", indent, stringifyUninterpretedOption(opt))
176-
}
177-
buf.Printf("%s }", indent)
178-
buf.Printf("")
179-
}
180-
buf.Printf("%s}", indent)
181-
}
182-
183-
func generateEnum(buf *Buffer, indentLevel int, enum *descriptorpb.EnumDescriptorProto) {
184-
indent := strings.Repeat(" ", indentLevel*4)
185-
buf.Printf("%senum %s {", indent, enum.GetName())
186-
generateHeadOptions(buf, indent, enum.GetOptions().GetUninterpretedOption())
187-
188-
for _, value := range enum.Value {
189-
buf.Printf("%s %s = %d%s;", indent, value.GetName(), value.GetNumber(), stringifyValueOptions(value.GetOptions().GetUninterpretedOption()))
190-
}
191-
buf.Printf("%s}", indent)
192-
}
193-
194-
func generateMessage(buf *Buffer, indentLevel int, message *descriptorpb.DescriptorProto) {
195-
indent := strings.Repeat(" ", indentLevel*4)
196-
buf.Printf("%smessage %s {", indent, message.GetName())
197-
generateHeadOptions(buf, indent, message.GetOptions().GetUninterpretedOption())
198-
generateExtendedMessage(buf, indentLevel, message)
199-
for _, field := range message.GetField() {
200-
buf.Printf("%s %s %s = %d%s;", indent, stringifyField(message, field), field.GetName(), field.GetNumber(), stringifyValueOptions(field.GetOptions().GetUninterpretedOption()))
201-
}
202-
203-
for _, enum := range message.EnumType {
204-
buf.Printf("")
205-
generateEnum(buf, indentLevel+1, enum)
206-
}
207-
208-
for _, nested := range message.NestedType {
209-
if nested.GetOptions().GetMapEntry() {
210-
continue
211-
}
212-
buf.Printf("")
213-
generateMessage(buf, indentLevel+1, nested)
214-
}
215-
buf.Printf("%s}", indent)
216-
}
217-
218-
func generateExtendedMessage(buf *Buffer, indentLevel int, message *descriptorpb.DescriptorProto) {
219-
indent := strings.Repeat(" ", indentLevel*4)
220-
for _, opt := range message.GetOptions().GetUninterpretedOption() {
221-
if isOptionOneProtoExtends(opt) {
222-
name := trimPackageFromName(string(opt.GetStringValue()))
223-
buf.Printf("%s // ↓↓↓↓↓ extends %s", indent, name)
224-
parent := allMessageDescriptors[name]
225-
generateExtendedMessage(buf, indentLevel, parent)
226-
for _, field := range parent.GetField() {
227-
buf.Printf("%s %s %s = %d%s;", indent, stringifyField(message, field), field.GetName(), field.GetNumber(), stringifyValueOptions(field.GetOptions().GetUninterpretedOption()))
119+
func resolveMessageExtends(buf *oneprotou_til.Buffer, indentLevel int, message *descriptorpb.DescriptorProto) []*descriptorpb.FieldDescriptorProto {
120+
if parentResolvedMap[message] {
121+
return nil
122+
}
123+
parentResolvedMap[message] = true
124+
var fields []*descriptorpb.FieldDescriptorProto
125+
for i, option := range message.GetOptions().GetUninterpretedOption() {
126+
if isOptionOneProtoExtends(option) {
127+
message.Options.UninterpretedOption = append(message.Options.UninterpretedOption[:i], message.Options.UninterpretedOption[i+1:]...)
128+
buf.Printf("%s// extends %s", strings.Repeat(" ", 4*indentLevel), option.GetStringValue())
129+
parent := allMessageDescriptors[trimPackageFromName(string(option.GetStringValue()))]
130+
if parent == nil {
131+
log.Fatalf("unable to find message %s", option.GetStringValue())
228132
}
229-
buf.Printf("%s // ↑↑↑↑↑ extends %s", indent, name)
230-
buf.Printf("")
133+
fields = append(fields, parent.Field...)
134+
fields = append(fields, resolveMessageExtends(buf, indentLevel, parent)...)
231135
}
232136
}
137+
return fields
233138
}
234139

235-
func generateHeadOptions(buf *Buffer, indent string, options []*descriptorpb.UninterpretedOption) {
236-
if len(options) == 0 {
237-
return
238-
}
239-
for _, opt := range options {
240-
if isOptionOneProtoExtends(opt) {
241-
continue
242-
}
243-
buf.Printf("%s option %s;", indent, stringifyUninterpretedOption(opt))
244-
}
245-
buf.Printf("")
246-
}
247-
248-
func stringifyValueOptions(options []*descriptorpb.UninterpretedOption) string {
249-
if len(options) == 0 {
250-
return ""
251-
}
252-
var opts []string
253-
for _, opt := range options {
254-
opts = append(opts, stringifyUninterpretedOption(opt))
255-
}
256-
return fmt.Sprintf(" [%s]", strings.Join(opts, ", "))
140+
func trimPackageFromName(name string) string {
141+
return strings.TrimPrefix(name, *pPackage+".")
257142
}
258143

259144
func isOptionOneProtoExtends(option *descriptorpb.UninterpretedOption) bool {
@@ -262,7 +147,3 @@ func isOptionOneProtoExtends(option *descriptorpb.UninterpretedOption) bool {
262147
}
263148
return false
264149
}
265-
266-
func trimPackageFromName(name string) string {
267-
return strings.TrimPrefix(name, *pPackage+".")
268-
}

pb/oneproto.pb.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

util/buffer.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package oneprotou_til
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
type Buffer struct {
9+
buf *bytes.Buffer
10+
}
11+
12+
func NewBuffer() *Buffer {
13+
return &Buffer{buf: &bytes.Buffer{}}
14+
}
15+
16+
func (b *Buffer) Printf(f string, i ...any) {
17+
_, _ = b.buf.WriteString(fmt.Sprintf(f+"\n", i...))
18+
}
19+
20+
func (b *Buffer) String() string {
21+
return b.buf.String()
22+
}
23+
24+
func (b *Buffer) Bytes() []byte {
25+
return b.buf.Bytes()
26+
}

0 commit comments

Comments
 (0)