Skip to content

Commit 8afce83

Browse files
committed
add extension generations
1 parent 35cfbc5 commit 8afce83

File tree

7 files changed

+92
-26
lines changed

7 files changed

+92
-26
lines changed

example/output.proto

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,32 @@ option go_package = 'generated/proto;pb';
55

66
package example.com;
77

8+
import 'google/protobuf/descriptor.proto';
9+
10+
extend google.protobuf.MessageOptions {
11+
string test = 3001;
12+
string abc = 3002;
13+
}
14+
815
message Base {
916
option (test) = 'hello';
1017

1118
int64 id = 1;
19+
1220
}
1321

14-
// extends example.com.Base
22+
1523
message Intermediate {
1624
option (test) = 'hello';
1725

1826
int64 id = 1;
1927
int64 createdAt = 2;
2028
int64 updatedAt = 3;
29+
2130
}
2231

32+
2333
message groups {
24-
// extends example.com.Intermediate
2534
message Group {
2635
option (test) = 'hello';
2736

@@ -30,12 +39,13 @@ message groups {
3039
int64 updatedAt = 3;
3140
string name = 11;
3241
repeated users.User users = 12;
42+
3343
}
3444

45+
3546
}
3647

3748
message users {
38-
// extends example.com.Intermediate
3949
message User {
4050
option (test) = 'hello';
4151

@@ -46,19 +56,22 @@ message users {
4656
string email = 12;
4757
string password = 13;
4858
repeated groups.Group groups = 14;
59+
4960
}
5061

62+
5163
message nested {
52-
// extends example.com.Intermediate
5364
message Test {
5465
option (test) = 'hello';
5566

5667
int64 id = 1;
5768
int64 createdAt = 2;
5869
int64 updatedAt = 3;
5970
string name = 11;
71+
6072
}
6173

74+
6275
}
6376

6477
}

example/proto/annotation.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ import 'google/protobuf/descriptor.proto';
77

88
extend google.protobuf.MessageOptions {
99
string test = 3001;
10+
}
11+
12+
extend google.protobuf.MessageOptions {
13+
string abc = 3002;
1014
}

example/template.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ syntax = 'proto3';
44
option go_package = 'generated/proto;pb';
55

66
package example.com;
7+
8+
import 'google/protobuf/descriptor.proto';

main.go

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"github.com/spf13/pflag"
1515
"google.golang.org/protobuf/types/descriptorpb"
1616

17-
oneprotou_til "github.com/joesonw/oneproto/util"
17+
oneproto_util "github.com/joesonw/oneproto/util"
1818
)
1919

2020
var (
@@ -71,7 +71,7 @@ func main() {
7171
log.Fatalln(err)
7272
}
7373

74-
buf := oneprotou_til.NewBuffer()
74+
buf := oneproto_util.NewBuffer()
7575
buf.Printf(string(templateContent))
7676

7777
// group files by package name
@@ -115,20 +115,23 @@ func main() {
115115

116116
for _, file := range group.files {
117117
for _, enum := range file.EnumType {
118-
oneprotou_til.GenerateEnum(buf, identLevel+1, enum)
118+
oneproto_util.GenerateEnum(buf, identLevel+1, enum)
119119
buf.Printf("")
120120
}
121121

122122
for _, service := range file.Service {
123-
oneprotou_til.GenerateService(buf, identLevel+1, service)
123+
oneproto_util.GenerateService(buf, identLevel+1, service)
124124
buf.Printf("")
125125
}
126126

127127
for _, message := range file.GetMessageType() {
128-
resolveMessageExtends(buf, identLevel+1, message)
129-
oneprotou_til.GenerateMessage(buf, identLevel+1, message)
128+
resolveMessageExtends(message)
129+
oneproto_util.GenerateMessage(buf, identLevel+1, message)
130130
buf.Printf("")
131131
}
132+
133+
oneproto_util.GenerateExtensions(buf, identLevel+1, nil, file.GetExtension())
134+
buf.Printf("")
132135
}
133136

134137
for _, subPackage := range group.subPackages {
@@ -146,29 +149,42 @@ func main() {
146149
}
147150
}
148151

149-
func resolveMessageExtends(buf *oneprotou_til.Buffer, indentLevel int, message *descriptorpb.DescriptorProto) {
152+
func resolveMessageExtends(message *descriptorpb.DescriptorProto) {
150153
if parentResolvedMap[message] {
151154
return
152155
}
156+
for _, nested := range message.GetNestedType() {
157+
resolveMessageExtends(nested)
158+
}
159+
153160
parentResolvedMap[message] = true
161+
var options []*descriptorpb.UninterpretedOption
162+
var fields []*descriptorpb.FieldDescriptorProto
154163
for i, option := range message.GetOptions().GetUninterpretedOption() {
155164
if isOptionOneProtoExtends(option) {
156165
message.Options.UninterpretedOption = append(message.Options.UninterpretedOption[:i], message.Options.UninterpretedOption[i+1:]...)
157-
buf.Printf("%s// extends %s", strings.Repeat(" ", 4*indentLevel), option.GetStringValue())
158166
parent := allMessageDescriptors[trimPackageFromName(string(option.GetStringValue()))]
159167
if parent == nil {
160168
log.Fatalf("unable to find message %s", option.GetStringValue())
161169
}
162-
resolveMessageExtends(buf, indentLevel, parent)
163-
message.Field = append(message.Field, parent.Field...)
164-
if message.Options == nil {
165-
message.Options = &descriptorpb.MessageOptions{}
166-
}
167-
if *pOptions {
168-
message.Options.UninterpretedOption = append(message.Options.UninterpretedOption, parent.GetOptions().GetUninterpretedOption()...)
170+
resolveMessageExtends(parent)
171+
fields = append(fields, parent.Field...)
172+
options = append(options, parent.GetOptions().GetUninterpretedOption()...)
173+
}
174+
}
175+
176+
message.Field = append(message.Field, fields...)
177+
if *pOptions {
178+
if message.Options == nil {
179+
message.Options = &descriptorpb.MessageOptions{}
180+
}
181+
for i := range options {
182+
if isOptionOneProtoExtends(options[i]) {
183+
options = append(options[:i], options[i+1:]...)
169184
}
170185
}
171186
}
187+
message.Options.UninterpretedOption = append(message.Options.UninterpretedOption, options...)
172188
sort.Slice(message.Field, func(i, j int) bool {
173189
return message.Field[i].GetNumber() < message.Field[j].GetNumber()
174190
})

util/buffer.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,15 @@ func (b *Buffer) String() string {
2424
func (b *Buffer) Bytes() []byte {
2525
return b.buf.Bytes()
2626
}
27+
28+
func (b *Buffer) Close() error {
29+
return nil
30+
}
31+
32+
func (b *Buffer) Write(p []byte) (int, error) {
33+
return b.buf.Write(p)
34+
}
35+
36+
func (b *Buffer) Read(p []byte) (int, error) {
37+
return b.buf.Read(p)
38+
}

util/generate.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
func GenerateService(buf *Buffer, indentLevel int, service *descriptorpb.ServiceDescriptorProto) {
1010
indent := strings.Repeat(" ", indentLevel*4)
1111
buf.Printf("%sservice %s {", indent, service.GetName())
12-
GenerateHeadOptions(buf, indent, service.GetOptions().GetUninterpretedOption())
12+
generateHeadOptions(buf, indent, service.GetOptions().GetUninterpretedOption())
1313
for _, method := range service.Method {
1414
buf.Printf("%s rpc %s(%s) returns (%s) {", indent, method.GetName(), method.GetInputType(), method.GetOutputType())
1515
for _, opt := range method.GetOptions().GetUninterpretedOption() {
@@ -24,7 +24,7 @@ func GenerateService(buf *Buffer, indentLevel int, service *descriptorpb.Service
2424
func GenerateEnum(buf *Buffer, indentLevel int, enum *descriptorpb.EnumDescriptorProto) {
2525
indent := strings.Repeat(" ", indentLevel*4)
2626
buf.Printf("%senum %s {", indent, enum.GetName())
27-
GenerateHeadOptions(buf, indent, enum.GetOptions().GetUninterpretedOption())
27+
generateHeadOptions(buf, indent, enum.GetOptions().GetUninterpretedOption())
2828

2929
for _, value := range enum.Value {
3030
buf.Printf("%s %s = %d%s;", indent, value.GetName(), value.GetNumber(), StringifyValueOptions(value.GetOptions().GetUninterpretedOption()))
@@ -35,27 +35,30 @@ func GenerateEnum(buf *Buffer, indentLevel int, enum *descriptorpb.EnumDescripto
3535
func GenerateMessage(buf *Buffer, indentLevel int, message *descriptorpb.DescriptorProto) {
3636
indent := strings.Repeat(" ", indentLevel*4)
3737
buf.Printf("%smessage %s {", indent, message.GetName())
38-
GenerateHeadOptions(buf, indent, message.GetOptions().GetUninterpretedOption())
38+
generateHeadOptions(buf, indent, message.GetOptions().GetUninterpretedOption())
3939
for _, field := range message.GetField() {
4040
buf.Printf("%s %s %s = %d%s;", indent, StringifyField(message, field), field.GetName(), field.GetNumber(), StringifyValueOptions(field.GetOptions().GetUninterpretedOption()))
4141
}
4242

43-
for _, enum := range message.EnumType {
43+
for _, enum := range message.GetEnumType() {
4444
buf.Printf("")
4545
GenerateEnum(buf, indentLevel+1, enum)
4646
}
4747

48-
for _, nested := range message.NestedType {
48+
for _, nested := range message.GetNestedType() {
4949
if nested.GetOptions().GetMapEntry() {
5050
continue
5151
}
5252
buf.Printf("")
5353
GenerateMessage(buf, indentLevel+1, nested)
5454
}
55+
56+
buf.Printf("")
57+
GenerateExtensions(buf, indentLevel+1, message, message.GetExtension())
5558
buf.Printf("%s}", indent)
5659
}
5760

58-
func GenerateHeadOptions(buf *Buffer, indent string, options []*descriptorpb.UninterpretedOption) {
61+
func generateHeadOptions(buf *Buffer, indent string, options []*descriptorpb.UninterpretedOption) {
5962
if len(options) == 0 {
6063
return
6164
}
@@ -64,3 +67,19 @@ func GenerateHeadOptions(buf *Buffer, indent string, options []*descriptorpb.Uni
6467
}
6568
buf.Printf("")
6669
}
70+
71+
func GenerateExtensions(buf *Buffer, indentLevel int, message *descriptorpb.DescriptorProto, extensions []*descriptorpb.FieldDescriptorProto) {
72+
grouped := map[string][]*descriptorpb.FieldDescriptorProto{}
73+
for _, ext := range extensions {
74+
grouped[ext.GetExtendee()] = append(grouped[ext.GetExtendee()], ext)
75+
}
76+
indent := strings.Repeat(" ", indentLevel*4)
77+
for extendee, exts := range grouped {
78+
79+
buf.Printf("%sextend %s {", indent, extendee)
80+
for _, ext := range exts {
81+
buf.Printf("%s %s %s = %d%s;", indent, StringifyField(message, ext), ext.GetName(), ext.GetNumber(), StringifyValueOptions(ext.GetOptions().GetUninterpretedOption()))
82+
}
83+
buf.Printf("%s}", indent)
84+
}
85+
}

util/stringify.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func StringifyField(message *descriptorpb.DescriptorProto, field *descriptorpb.F
3333
repeated := field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED
3434
if field.Type == nil {
3535
name := field.GetTypeName()
36-
for _, nested := range message.NestedType {
36+
for _, nested := range message.GetNestedType() {
3737
if name == nested.GetName() && strings.HasSuffix(name, "Entry") { // map entry
3838
return fmt.Sprintf("map<%s,%s>", StringifyField(nested, nested.Field[0]), StringifyField(nested, nested.Field[1]))
3939
}

0 commit comments

Comments
 (0)