Skip to content

Commit dc63c20

Browse files
author
Alex Davies-Moore
committed
Added support for imported types
This commit enables the generator to correctly resolve imported types from other proto files and correctly reference the types.
1 parent c5999cf commit dc63c20

File tree

12 files changed

+248
-61
lines changed

12 files changed

+248
-61
lines changed

plugin/src/main/java/com/flit/protoc/gen/server/BaseGenerator.java

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,24 @@
77
import java.time.Instant;
88
import java.util.List;
99

10+
import static com.flit.protoc.gen.server.TypeMapper.getClassname;
11+
1012
public abstract class BaseGenerator {
11-
protected Buffer b = new Buffer();
1213

13-
protected DescriptorProtos.ServiceDescriptorProto service;
14-
protected String javaPackage;
15-
protected String clazz;
14+
protected final Buffer b = new Buffer();
15+
protected final DescriptorProtos.ServiceDescriptorProto service;
16+
protected final String javaPackage;
17+
protected final String clazz;
18+
protected final TypeMapper mapper;
1619

1720
protected DescriptorProtos.FileDescriptorProto proto;
1821

19-
protected BaseGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto s) {
20-
this.clazz = proto.getOptions().getJavaOuterClassname();
21-
22-
if (this.clazz == null || this.clazz.isEmpty()) {
23-
24-
char[] classname = proto.getName().substring(0, proto.getName().lastIndexOf('.')).toCharArray();
25-
StringBuilder sb = new StringBuilder();
26-
27-
char previous = '_';
28-
for (char c : classname) {
29-
if (c == '_') {
30-
previous = c;
31-
continue;
32-
}
33-
34-
if (previous == '_') {
35-
sb.append(Character.toUpperCase(c));
36-
} else {
37-
sb.append(c);
38-
}
39-
40-
previous = c;
41-
}
42-
43-
this.clazz = sb.toString();
44-
45-
// check to see if there are any messages with this same class name as per java proto specs
46-
// note that we also check the services too as the protoc compiler does that as well
47-
proto.getMessageTypeList().forEach(m -> {
48-
if (m.getName().equals(this.clazz)) {
49-
this.clazz += "OuterClass";
50-
}
51-
});
52-
53-
proto.getServiceList().forEach(m -> {
54-
if (m.getName().equals(this.clazz)) {
55-
this.clazz += "OuterClass";
56-
}
57-
});
58-
}
59-
22+
protected BaseGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto s, TypeMapper mapper) {
23+
this.clazz = getClassname(proto);
6024
this.javaPackage = proto.getOptions().getJavaPackage();
6125
this.proto = proto;
6226
this.service = s;
27+
this.mapper = mapper;
6328
}
6429

6530
public void writeProlog() {

plugin/src/main/java/com/flit/protoc/gen/server/ServiceGenerator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class ServiceGenerator extends BaseGenerator {
1010

1111
private final String filename;
1212

13-
public ServiceGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto s) {
14-
super(proto, s);
13+
public ServiceGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto s, TypeMapper mapper) {
14+
super(proto, s, mapper);
1515
this.filename = javaPackage.replace(".", "/") + "/Rpc" + service.getName() + "Service.java";
1616
}
1717

@@ -29,7 +29,7 @@ public void close() {
2929
public void writeService(DescriptorProtos.ServiceDescriptorProto s) {
3030

3131
s.getMethodList().forEach(m -> {
32-
b.iwn(clazz, ".", basename(m.getOutputType()), " handle", m.getName(), "(", clazz, ".", basename(m.getInputType())," in);");
32+
b.iwn(mapper.get(m.getOutputType()), " handle", m.getName(), "(", mapper.get(m.getInputType())," in);");
3333
b.n();
3434
});
3535

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.flit.protoc.gen.server;
2+
3+
import com.google.protobuf.DescriptorProtos;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
8+
public class TypeMapper {
9+
10+
// holds the qualified class name to the short class reference
11+
private final Map<String, String> mapping = new HashMap<>();
12+
13+
public void add(DescriptorProtos.FileDescriptorProto proto) {
14+
proto.getMessageTypeList().forEach(m -> {
15+
mapping.put("." + proto.getPackage() + "." + m.getName(), getClassname(proto) + "." + m.getName());
16+
});
17+
}
18+
19+
public String get(String fqn) {
20+
return mapping.get(fqn);
21+
}
22+
23+
public static String getClassname(DescriptorProtos.FileDescriptorProto proto) {
24+
String clazz = proto.getOptions().getJavaOuterClassname();
25+
26+
if (clazz == null || clazz.isEmpty()) {
27+
28+
char[] classname = proto.getName().substring(0, proto.getName().lastIndexOf('.')).toCharArray();
29+
StringBuilder sb = new StringBuilder();
30+
31+
char previous = '_';
32+
for (char c : classname) {
33+
if (c == '_') {
34+
previous = c;
35+
continue;
36+
}
37+
38+
if (previous == '_') {
39+
sb.append(Character.toUpperCase(c));
40+
} else {
41+
sb.append(c);
42+
}
43+
44+
previous = c;
45+
}
46+
47+
clazz = sb.toString();
48+
49+
// check to see if there are any messages with this same class name as per java proto specs
50+
// note that we also check the services too as the protoc compiler does that as well
51+
for (DescriptorProtos.DescriptorProto type: proto.getMessageTypeList()) {
52+
if (type.getName().equals(clazz)) {
53+
return clazz + "OuterClass";
54+
}
55+
}
56+
57+
for (DescriptorProtos.ServiceDescriptorProto service: proto.getServiceList()) {
58+
if (service.getName().equals(clazz)) {
59+
return clazz + "OuterClass";
60+
}
61+
}
62+
}
63+
64+
return clazz;
65+
}
66+
67+
}

plugin/src/main/java/com/flit/protoc/gen/server/spring/RpcGenerator.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.flit.protoc.gen.server.spring;
22

33
import com.flit.protoc.gen.server.BaseGenerator;
4+
import com.flit.protoc.gen.server.TypeMapper;
45
import com.google.protobuf.DescriptorProtos;
56
import com.google.protobuf.compiler.PluginProtos;
67

@@ -12,8 +13,8 @@ class RpcGenerator extends BaseGenerator {
1213
private final String filename;
1314
private final String context;
1415

15-
RpcGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto service, String context) {
16-
super(proto, service);
16+
RpcGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto service, String context, TypeMapper mapper) {
17+
super(proto, service, mapper);
1718
this.filename = javaPackage.replace(".", "/") + "/Rpc" + this.service.getName() + "Controller.java";
1819

1920
if (context == null) {

plugin/src/main/java/com/flit/protoc/gen/server/spring/SpringGenerator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.flit.protoc.Parameter;
44
import com.flit.protoc.gen.Generator;
55
import com.flit.protoc.gen.server.ServiceGenerator;
6+
import com.flit.protoc.gen.server.TypeMapper;
67
import com.google.protobuf.compiler.PluginProtos;
78

89
import java.util.ArrayList;
@@ -21,19 +22,23 @@ public List<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeG
2122

2223
List<PluginProtos.CodeGeneratorResponse.File> files = new ArrayList<>();
2324

25+
TypeMapper mapper = new TypeMapper();
26+
2427
request.getProtoFileList().forEach(proto -> {
2528

2629
// Provide handlers for each service entry
2730
proto.getServiceList().forEach(s -> {
2831

32+
mapper.add(proto);
33+
2934
String context = null;
3035

3136
if (params.containsKey(PARAM_CONTEXT)) {
3237
context = params.get(PARAM_CONTEXT).getValue();
3338
}
3439

35-
ServiceGenerator sgen = new ServiceGenerator(proto, s);
36-
RpcGenerator rgen = new RpcGenerator(proto, s, context);
40+
ServiceGenerator sgen = new ServiceGenerator(proto, s, mapper);
41+
RpcGenerator rgen = new RpcGenerator(proto, s, context, mapper);
3742

3843
rgen.writeProlog();
3944
rgen.writePackage();

plugin/src/main/java/com/flit/protoc/gen/server/undertow/RpcGenerator.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.flit.protoc.gen.server.undertow;
22

33
import com.flit.protoc.gen.server.BaseGenerator;
4+
import com.flit.protoc.gen.server.TypeMapper;
45
import com.google.protobuf.DescriptorProtos;
56
import com.google.protobuf.compiler.PluginProtos;
67

@@ -12,8 +13,8 @@ class RpcGenerator extends BaseGenerator {
1213
private final String filename;
1314
private final String context;
1415

15-
RpcGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto service, String context) {
16-
super(proto, service);
16+
RpcGenerator(DescriptorProtos.FileDescriptorProto proto, DescriptorProtos.ServiceDescriptorProto service, String context, TypeMapper mapper) {
17+
super(proto, service, mapper);
1718
this.filename = javaPackage.replace(".", "/") + "/Rpc" + this.service.getName() + "Handler.java";
1819

1920
if (context == null) {
@@ -139,15 +140,15 @@ void writeService(DescriptorProtos.ServiceDescriptorProto s) {
139140

140141
// bind the data
141142
b.iwn("boolean json = false;");
142-
b.iwn(clazz, ".", basename(m.getInputType()), " data;");
143+
b.iwn(mapper.get(m.getInputType()), " data;");
143144
b.iwn("if (exchange.getRequestHeaders().get(Headers.CONTENT_TYPE).getFirst().equals(\"application/protobuf\")) {");
144145
b.inc();
145-
b.iwn("data = ", clazz, ".", basename(m.getInputType()), ".parseFrom(exchange.getInputStream());");
146+
b.iwn("data = ", mapper.get(m.getInputType()), ".parseFrom(exchange.getInputStream());");
146147
b.dec();
147148
b.iwn("} else if (exchange.getRequestHeaders().get(Headers.CONTENT_TYPE).getFirst().startsWith(\"application/json\")) {");
148149
b.inc();
149150
b.iwn("json = true;");
150-
b.iwn(clazz, ".", basename(m.getInputType()), ".Builder builder = ", clazz, ".", basename(m.getInputType()), ".newBuilder();");
151+
b.iwn(mapper.get(m.getInputType()), ".Builder builder = ", mapper.get(m.getInputType()), ".newBuilder();");
151152
b.iwn("JsonFormat.parser().merge(new InputStreamReader(exchange.getInputStream(), Charset.forName(\"UTF-8\")), builder);");
152153
b.iwn("data = builder.build();");
153154
b.dec();
@@ -160,7 +161,7 @@ void writeService(DescriptorProtos.ServiceDescriptorProto s) {
160161
b.n();
161162

162163
// route to the service
163-
b.iwn(clazz, ".", basename(m.getOutputType()), " retval = ", "service.handle", m.getName(), "(data);");
164+
b.iwn(mapper.get(m.getOutputType()), " retval = ", "service.handle", m.getName(), "(data);");
164165
b.iwn("exchange.setStatusCode(200);");
165166

166167
b.iwn("if (json) {");

plugin/src/main/java/com/flit/protoc/gen/server/undertow/UndertowGenerator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.flit.protoc.Parameter;
44
import com.flit.protoc.gen.Generator;
55
import com.flit.protoc.gen.server.ServiceGenerator;
6+
import com.flit.protoc.gen.server.TypeMapper;
67
import com.google.protobuf.compiler.PluginProtos;
78

89
import java.util.ArrayList;
@@ -16,8 +17,12 @@ public class UndertowGenerator implements Generator {
1617
public List<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeGeneratorRequest request, Map<String, Parameter> params) {
1718
List<PluginProtos.CodeGeneratorResponse.File> files = new ArrayList<>();
1819

20+
TypeMapper mapper = new TypeMapper();
21+
1922
request.getProtoFileList().forEach(proto -> {
2023

24+
mapper.add(proto);
25+
2126
// Provide handlers for each service entry
2227
proto.getServiceList().forEach(s -> {
2328

@@ -27,8 +32,8 @@ public List<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeG
2732
context = params.get(PARAM_CONTEXT).getValue();
2833
}
2934

30-
ServiceGenerator sgen = new ServiceGenerator(proto, s);
31-
RpcGenerator rgen = new RpcGenerator(proto, s, context);
35+
ServiceGenerator sgen = new ServiceGenerator(proto, s, mapper);
36+
RpcGenerator rgen = new RpcGenerator(proto, s, context, mapper);
3237

3338
rgen.writeProlog();
3439
rgen.writePackage();

plugin/src/test/java/com/flit/protoc/gen/server/undertow/UndertowGeneratorTest.java renamed to plugin/src/test/java/com/flit/protoc/gen/server/undertow/HelloworldGeneratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import static org.junit.Assert.assertNotNull;
1717
import static org.junit.Assert.assertTrue;
1818

19-
public class UndertowGeneratorTest extends BaseGeneratorTest {
19+
public class HelloworldGeneratorTest extends BaseGeneratorTest {
2020

2121
@Test
2222
public void test_Generate() throws Exception {

0 commit comments

Comments
 (0)