blob: 43787ffcb274033008a8c020565f71dd0a4693e4 [file] [log] [blame]
Josh Haberman420f9382015-04-16 12:50:39 -07001
2import com.google.protobuf.conformance.Conformance;
Feng Xiaoe841bac2015-12-11 17:09:20 -08003import com.google.protobuf.util.JsonFormat;
4import com.google.protobuf.util.JsonFormat.TypeRegistry;
Josh Haberman420f9382015-04-16 12:50:39 -07005import com.google.protobuf.InvalidProtocolBufferException;
6
7class ConformanceJava {
8 private int testCount = 0;
Feng Xiaoe841bac2015-12-11 17:09:20 -08009 private TypeRegistry typeRegistry;
Josh Haberman420f9382015-04-16 12:50:39 -070010
11 private boolean readFromStdin(byte[] buf, int len) throws Exception {
12 int ofs = 0;
13 while (len > 0) {
14 int read = System.in.read(buf, ofs, len);
15 if (read == -1) {
16 return false; // EOF
17 }
18 ofs += read;
19 len -= read;
20 }
21
22 return true;
23 }
24
25 private void writeToStdout(byte[] buf) throws Exception {
26 System.out.write(buf);
27 }
28
29 // Returns -1 on EOF (the actual values will always be positive).
30 private int readLittleEndianIntFromStdin() throws Exception {
31 byte[] buf = new byte[4];
32 if (!readFromStdin(buf, 4)) {
33 return -1;
34 }
Feng Xiaoe841bac2015-12-11 17:09:20 -080035 return (buf[0] & 0xff)
36 | ((buf[1] & 0xff) << 8)
37 | ((buf[2] & 0xff) << 16)
38 | ((buf[3] & 0xff) << 24);
Josh Haberman420f9382015-04-16 12:50:39 -070039 }
40
41 private void writeLittleEndianIntToStdout(int val) throws Exception {
42 byte[] buf = new byte[4];
43 buf[0] = (byte)val;
44 buf[1] = (byte)(val >> 8);
45 buf[2] = (byte)(val >> 16);
46 buf[3] = (byte)(val >> 24);
47 writeToStdout(buf);
48 }
49
50 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
51 Conformance.TestAllTypes testMessage;
52
53 switch (request.getPayloadCase()) {
54 case PROTOBUF_PAYLOAD: {
55 try {
56 testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
57 } catch (InvalidProtocolBufferException e) {
58 return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
59 }
60 break;
61 }
62 case JSON_PAYLOAD: {
Feng Xiaoe841bac2015-12-11 17:09:20 -080063 try {
64 Conformance.TestAllTypes.Builder builder = Conformance.TestAllTypes.newBuilder();
65 JsonFormat.parser().usingTypeRegistry(typeRegistry)
66 .merge(request.getJsonPayload(), builder);
67 testMessage = builder.build();
68 } catch (InvalidProtocolBufferException e) {
69 return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
70 }
71 break;
Josh Haberman420f9382015-04-16 12:50:39 -070072 }
73 case PAYLOAD_NOT_SET: {
74 throw new RuntimeException("Request didn't have payload.");
75 }
76
77 default: {
78 throw new RuntimeException("Unexpected payload case.");
79 }
80 }
81
Josh Habermanb0500b32015-07-10 16:36:59 -070082 switch (request.getRequestedOutputFormat()) {
Josh Haberman420f9382015-04-16 12:50:39 -070083 case UNSPECIFIED:
84 throw new RuntimeException("Unspecified output format.");
85
86 case PROTOBUF:
87 return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
88
89 case JSON:
Feng Xiaoe841bac2015-12-11 17:09:20 -080090 try {
91 return Conformance.ConformanceResponse.newBuilder().setJsonPayload(
92 JsonFormat.printer().usingTypeRegistry(typeRegistry).print(testMessage)).build();
93 } catch (InvalidProtocolBufferException | IllegalArgumentException e) {
94 return Conformance.ConformanceResponse.newBuilder().setSerializeError(
95 e.getMessage()).build();
96 }
Josh Haberman420f9382015-04-16 12:50:39 -070097
98 default: {
99 throw new RuntimeException("Unexpected request output.");
100 }
101 }
102 }
103
104 private boolean doTestIo() throws Exception {
105 int bytes = readLittleEndianIntFromStdin();
106
107 if (bytes == -1) {
108 return false; // EOF
109 }
110
111 byte[] serializedInput = new byte[bytes];
112
113 if (!readFromStdin(serializedInput, bytes)) {
114 throw new RuntimeException("Unexpected EOF from test program.");
115 }
116
117 Conformance.ConformanceRequest request =
118 Conformance.ConformanceRequest.parseFrom(serializedInput);
119 Conformance.ConformanceResponse response = doTest(request);
120 byte[] serializedOutput = response.toByteArray();
121
122 writeLittleEndianIntToStdout(serializedOutput.length);
123 writeToStdout(serializedOutput);
124
125 return true;
126 }
127
128 public void run() throws Exception {
Feng Xiaoe841bac2015-12-11 17:09:20 -0800129 typeRegistry = TypeRegistry.newBuilder().add(
130 Conformance.TestAllTypes.getDescriptor()).build();
Josh Haberman420f9382015-04-16 12:50:39 -0700131 while (doTestIo()) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700132 this.testCount++;
Josh Haberman420f9382015-04-16 12:50:39 -0700133 }
134
135 System.err.println("ConformanceJava: received EOF from test runner after " +
136 this.testCount + " tests");
137 }
138
139 public static void main(String[] args) throws Exception {
140 new ConformanceJava().run();
141 }
142}