OLD | NEW |
1 import com.google.protobuf.ByteString; | 1 |
2 import com.google.protobuf.CodedInputStream; | |
3 import com.google.protobuf.conformance.Conformance; | 2 import com.google.protobuf.conformance.Conformance; |
4 import com.google.protobuf.InvalidProtocolBufferException; | |
5 import com.google.protobuf_test_messages.proto3.TestMessagesProto3; | |
6 import com.google.protobuf.util.JsonFormat; | 3 import com.google.protobuf.util.JsonFormat; |
7 import com.google.protobuf.util.JsonFormat.TypeRegistry; | 4 import com.google.protobuf.util.JsonFormat.TypeRegistry; |
8 import java.io.IOException; | 5 import com.google.protobuf.InvalidProtocolBufferException; |
9 import java.nio.ByteBuffer; | |
10 | 6 |
11 class ConformanceJava { | 7 class ConformanceJava { |
12 private int testCount = 0; | 8 private int testCount = 0; |
13 private TypeRegistry typeRegistry; | 9 private TypeRegistry typeRegistry; |
14 | 10 |
15 private boolean readFromStdin(byte[] buf, int len) throws Exception { | 11 private boolean readFromStdin(byte[] buf, int len) throws Exception { |
16 int ofs = 0; | 12 int ofs = 0; |
17 while (len > 0) { | 13 while (len > 0) { |
18 int read = System.in.read(buf, ofs, len); | 14 int read = System.in.read(buf, ofs, len); |
19 if (read == -1) { | 15 if (read == -1) { |
(...skipping 24 matching lines...) Expand all Loading... |
44 | 40 |
45 private void writeLittleEndianIntToStdout(int val) throws Exception { | 41 private void writeLittleEndianIntToStdout(int val) throws Exception { |
46 byte[] buf = new byte[4]; | 42 byte[] buf = new byte[4]; |
47 buf[0] = (byte)val; | 43 buf[0] = (byte)val; |
48 buf[1] = (byte)(val >> 8); | 44 buf[1] = (byte)(val >> 8); |
49 buf[2] = (byte)(val >> 16); | 45 buf[2] = (byte)(val >> 16); |
50 buf[3] = (byte)(val >> 24); | 46 buf[3] = (byte)(val >> 24); |
51 writeToStdout(buf); | 47 writeToStdout(buf); |
52 } | 48 } |
53 | 49 |
54 private enum BinaryDecoder { | |
55 BYTE_STRING_DECODER() { | |
56 @Override | |
57 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
58 throws InvalidProtocolBufferException { | |
59 return TestMessagesProto3.TestAllTypes.parseFrom(bytes); | |
60 } | |
61 }, | |
62 BYTE_ARRAY_DECODER() { | |
63 @Override | |
64 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
65 throws InvalidProtocolBufferException { | |
66 return TestMessagesProto3.TestAllTypes.parseFrom(bytes.toByteArray()); | |
67 } | |
68 }, | |
69 ARRAY_BYTE_BUFFER_DECODER() { | |
70 @Override | |
71 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
72 throws InvalidProtocolBufferException { | |
73 ByteBuffer buffer = ByteBuffer.allocate(bytes.size()); | |
74 bytes.copyTo(buffer); | |
75 buffer.flip(); | |
76 try { | |
77 return TestMessagesProto3.TestAllTypes.parseFrom(CodedInputStream.newI
nstance(buffer)); | |
78 } catch (InvalidProtocolBufferException e) { | |
79 throw e; | |
80 } catch (IOException e) { | |
81 throw new RuntimeException( | |
82 "ByteString based ByteBuffer should not throw IOException.", e); | |
83 } | |
84 } | |
85 }, | |
86 READONLY_ARRAY_BYTE_BUFFER_DECODER() { | |
87 @Override | |
88 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
89 throws InvalidProtocolBufferException { | |
90 try { | |
91 return TestMessagesProto3.TestAllTypes.parseFrom( | |
92 CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer())); | |
93 } catch (InvalidProtocolBufferException e) { | |
94 throw e; | |
95 } catch (IOException e) { | |
96 throw new RuntimeException( | |
97 "ByteString based ByteBuffer should not throw IOException.", e); | |
98 } | |
99 } | |
100 }, | |
101 DIRECT_BYTE_BUFFER_DECODER() { | |
102 @Override | |
103 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
104 throws InvalidProtocolBufferException { | |
105 ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); | |
106 bytes.copyTo(buffer); | |
107 buffer.flip(); | |
108 try { | |
109 return TestMessagesProto3.TestAllTypes.parseFrom(CodedInputStream.newI
nstance(buffer)); | |
110 } catch (InvalidProtocolBufferException e) { | |
111 throw e; | |
112 } catch (IOException e) { | |
113 throw new RuntimeException( | |
114 "ByteString based ByteBuffer should not throw IOException.", e); | |
115 } | |
116 } | |
117 }, | |
118 READONLY_DIRECT_BYTE_BUFFER_DECODER() { | |
119 @Override | |
120 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
121 throws InvalidProtocolBufferException { | |
122 ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); | |
123 bytes.copyTo(buffer); | |
124 buffer.flip(); | |
125 try { | |
126 return TestMessagesProto3.TestAllTypes.parseFrom( | |
127 CodedInputStream.newInstance(buffer.asReadOnlyBuffer())); | |
128 } catch (InvalidProtocolBufferException e) { | |
129 throw e; | |
130 } catch (IOException e) { | |
131 throw new RuntimeException( | |
132 "ByteString based ByteBuffer should not throw IOException.", e); | |
133 } | |
134 } | |
135 }, | |
136 INPUT_STREAM_DECODER() { | |
137 @Override | |
138 public TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
139 throws InvalidProtocolBufferException { | |
140 try { | |
141 return TestMessagesProto3.TestAllTypes.parseFrom(bytes.newInput()); | |
142 } catch (InvalidProtocolBufferException e) { | |
143 throw e; | |
144 } catch (IOException e) { | |
145 throw new RuntimeException( | |
146 "ByteString based InputStream should not throw IOException.", e); | |
147 } | |
148 } | |
149 }; | |
150 | |
151 public abstract TestMessagesProto3.TestAllTypes parse(ByteString bytes) | |
152 throws InvalidProtocolBufferException; | |
153 } | |
154 | |
155 private TestMessagesProto3.TestAllTypes parseBinary(ByteString bytes) | |
156 throws InvalidProtocolBufferException { | |
157 TestMessagesProto3.TestAllTypes[] messages = | |
158 new TestMessagesProto3.TestAllTypes[BinaryDecoder.values().length]; | |
159 InvalidProtocolBufferException[] exceptions = | |
160 new InvalidProtocolBufferException[BinaryDecoder.values().length]; | |
161 | |
162 boolean hasMessage = false; | |
163 boolean hasException = false; | |
164 for (int i = 0; i < BinaryDecoder.values().length; ++i) { | |
165 try { | |
166 messages[i] = BinaryDecoder.values()[i].parse(bytes); | |
167 hasMessage = true; | |
168 } catch (InvalidProtocolBufferException e) { | |
169 exceptions[i] = e; | |
170 hasException = true; | |
171 } | |
172 } | |
173 | |
174 if (hasMessage && hasException) { | |
175 StringBuilder sb = | |
176 new StringBuilder("Binary decoders disagreed on whether the payload wa
s valid.\n"); | |
177 for (int i = 0; i < BinaryDecoder.values().length; ++i) { | |
178 sb.append(BinaryDecoder.values()[i].name()); | |
179 if (messages[i] != null) { | |
180 sb.append(" accepted the payload.\n"); | |
181 } else { | |
182 sb.append(" rejected the payload.\n"); | |
183 } | |
184 } | |
185 throw new RuntimeException(sb.toString()); | |
186 } | |
187 | |
188 if (hasException) { | |
189 // We do not check if exceptions are equal. Different implementations may
return different | |
190 // exception messages. Throw an arbitrary one out instead. | |
191 throw exceptions[0]; | |
192 } | |
193 | |
194 // Fast path comparing all the messages with the first message, assuming equ
ality being | |
195 // symmetric and transitive. | |
196 boolean allEqual = true; | |
197 for (int i = 1; i < messages.length; ++i) { | |
198 if (!messages[0].equals(messages[i])) { | |
199 allEqual = false; | |
200 break; | |
201 } | |
202 } | |
203 | |
204 // Slow path: compare and find out all unequal pairs. | |
205 if (!allEqual) { | |
206 StringBuilder sb = new StringBuilder(); | |
207 for (int i = 0; i < messages.length - 1; ++i) { | |
208 for (int j = i + 1; j < messages.length; ++j) { | |
209 if (!messages[i].equals(messages[j])) { | |
210 sb.append(BinaryDecoder.values()[i].name()) | |
211 .append(" and ") | |
212 .append(BinaryDecoder.values()[j].name()) | |
213 .append(" parsed the payload differently.\n"); | |
214 } | |
215 } | |
216 } | |
217 throw new RuntimeException(sb.toString()); | |
218 } | |
219 | |
220 return messages[0]; | |
221 } | |
222 | |
223 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest
request) { | 50 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest
request) { |
224 TestMessagesProto3.TestAllTypes testMessage; | 51 Conformance.TestAllTypes testMessage; |
225 | 52 |
226 switch (request.getPayloadCase()) { | 53 switch (request.getPayloadCase()) { |
227 case PROTOBUF_PAYLOAD: { | 54 case PROTOBUF_PAYLOAD: { |
228 try { | 55 try { |
229 testMessage = parseBinary(request.getProtobufPayload()); | 56 testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPa
yload()); |
230 } catch (InvalidProtocolBufferException e) { | 57 } catch (InvalidProtocolBufferException e) { |
231 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); | 58 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); |
232 } | 59 } |
233 break; | 60 break; |
234 } | 61 } |
235 case JSON_PAYLOAD: { | 62 case JSON_PAYLOAD: { |
236 try { | 63 try { |
237 TestMessagesProto3.TestAllTypes.Builder builder = TestMessagesProto3.T
estAllTypes.newBuilder(); | 64 Conformance.TestAllTypes.Builder builder = Conformance.TestAllTypes.ne
wBuilder(); |
238 JsonFormat.parser().usingTypeRegistry(typeRegistry) | 65 JsonFormat.parser().usingTypeRegistry(typeRegistry) |
239 .merge(request.getJsonPayload(), builder); | 66 .merge(request.getJsonPayload(), builder); |
240 testMessage = builder.build(); | 67 testMessage = builder.build(); |
241 } catch (InvalidProtocolBufferException e) { | 68 } catch (InvalidProtocolBufferException e) { |
242 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); | 69 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); |
243 } | 70 } |
244 break; | 71 break; |
245 } | 72 } |
246 case PAYLOAD_NOT_SET: { | 73 case PAYLOAD_NOT_SET: { |
247 throw new RuntimeException("Request didn't have payload."); | 74 throw new RuntimeException("Request didn't have payload."); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 byte[] serializedOutput = response.toByteArray(); | 120 byte[] serializedOutput = response.toByteArray(); |
294 | 121 |
295 writeLittleEndianIntToStdout(serializedOutput.length); | 122 writeLittleEndianIntToStdout(serializedOutput.length); |
296 writeToStdout(serializedOutput); | 123 writeToStdout(serializedOutput); |
297 | 124 |
298 return true; | 125 return true; |
299 } | 126 } |
300 | 127 |
301 public void run() throws Exception { | 128 public void run() throws Exception { |
302 typeRegistry = TypeRegistry.newBuilder().add( | 129 typeRegistry = TypeRegistry.newBuilder().add( |
303 TestMessagesProto3.TestAllTypes.getDescriptor()).build(); | 130 Conformance.TestAllTypes.getDescriptor()).build(); |
304 while (doTestIo()) { | 131 while (doTestIo()) { |
305 this.testCount++; | 132 this.testCount++; |
306 } | 133 } |
307 | 134 |
308 System.err.println("ConformanceJava: received EOF from test runner after " + | 135 System.err.println("ConformanceJava: received EOF from test runner after " + |
309 this.testCount + " tests"); | 136 this.testCount + " tests"); |
310 } | 137 } |
311 | 138 |
312 public static void main(String[] args) throws Exception { | 139 public static void main(String[] args) throws Exception { |
313 new ConformanceJava().run(); | 140 new ConformanceJava().run(); |
314 } | 141 } |
315 } | 142 } |
OLD | NEW |