OLD | NEW |
1 | 1 import com.google.protobuf.ByteString; |
| 2 import com.google.protobuf.CodedInputStream; |
2 import com.google.protobuf.conformance.Conformance; | 3 import com.google.protobuf.conformance.Conformance; |
| 4 import com.google.protobuf.InvalidProtocolBufferException; |
| 5 import com.google.protobuf_test_messages.proto3.TestMessagesProto3; |
3 import com.google.protobuf.util.JsonFormat; | 6 import com.google.protobuf.util.JsonFormat; |
4 import com.google.protobuf.util.JsonFormat.TypeRegistry; | 7 import com.google.protobuf.util.JsonFormat.TypeRegistry; |
5 import com.google.protobuf.InvalidProtocolBufferException; | 8 import java.io.IOException; |
| 9 import java.nio.ByteBuffer; |
6 | 10 |
7 class ConformanceJava { | 11 class ConformanceJava { |
8 private int testCount = 0; | 12 private int testCount = 0; |
9 private TypeRegistry typeRegistry; | 13 private TypeRegistry typeRegistry; |
10 | 14 |
11 private boolean readFromStdin(byte[] buf, int len) throws Exception { | 15 private boolean readFromStdin(byte[] buf, int len) throws Exception { |
12 int ofs = 0; | 16 int ofs = 0; |
13 while (len > 0) { | 17 while (len > 0) { |
14 int read = System.in.read(buf, ofs, len); | 18 int read = System.in.read(buf, ofs, len); |
15 if (read == -1) { | 19 if (read == -1) { |
(...skipping 24 matching lines...) Expand all Loading... |
40 | 44 |
41 private void writeLittleEndianIntToStdout(int val) throws Exception { | 45 private void writeLittleEndianIntToStdout(int val) throws Exception { |
42 byte[] buf = new byte[4]; | 46 byte[] buf = new byte[4]; |
43 buf[0] = (byte)val; | 47 buf[0] = (byte)val; |
44 buf[1] = (byte)(val >> 8); | 48 buf[1] = (byte)(val >> 8); |
45 buf[2] = (byte)(val >> 16); | 49 buf[2] = (byte)(val >> 16); |
46 buf[3] = (byte)(val >> 24); | 50 buf[3] = (byte)(val >> 24); |
47 writeToStdout(buf); | 51 writeToStdout(buf); |
48 } | 52 } |
49 | 53 |
| 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 |
50 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest
request) { | 223 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest
request) { |
51 Conformance.TestAllTypes testMessage; | 224 TestMessagesProto3.TestAllTypes testMessage; |
52 | 225 |
53 switch (request.getPayloadCase()) { | 226 switch (request.getPayloadCase()) { |
54 case PROTOBUF_PAYLOAD: { | 227 case PROTOBUF_PAYLOAD: { |
55 try { | 228 try { |
56 testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPa
yload()); | 229 testMessage = parseBinary(request.getProtobufPayload()); |
57 } catch (InvalidProtocolBufferException e) { | 230 } catch (InvalidProtocolBufferException e) { |
58 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); | 231 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); |
59 } | 232 } |
60 break; | 233 break; |
61 } | 234 } |
62 case JSON_PAYLOAD: { | 235 case JSON_PAYLOAD: { |
63 try { | 236 try { |
64 Conformance.TestAllTypes.Builder builder = Conformance.TestAllTypes.ne
wBuilder(); | 237 TestMessagesProto3.TestAllTypes.Builder builder = TestMessagesProto3.T
estAllTypes.newBuilder(); |
65 JsonFormat.parser().usingTypeRegistry(typeRegistry) | 238 JsonFormat.parser().usingTypeRegistry(typeRegistry) |
66 .merge(request.getJsonPayload(), builder); | 239 .merge(request.getJsonPayload(), builder); |
67 testMessage = builder.build(); | 240 testMessage = builder.build(); |
68 } catch (InvalidProtocolBufferException e) { | 241 } catch (InvalidProtocolBufferException e) { |
69 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); | 242 return Conformance.ConformanceResponse.newBuilder().setParseError(e.ge
tMessage()).build(); |
70 } | 243 } |
71 break; | 244 break; |
72 } | 245 } |
73 case PAYLOAD_NOT_SET: { | 246 case PAYLOAD_NOT_SET: { |
74 throw new RuntimeException("Request didn't have payload."); | 247 throw new RuntimeException("Request didn't have payload."); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 byte[] serializedOutput = response.toByteArray(); | 293 byte[] serializedOutput = response.toByteArray(); |
121 | 294 |
122 writeLittleEndianIntToStdout(serializedOutput.length); | 295 writeLittleEndianIntToStdout(serializedOutput.length); |
123 writeToStdout(serializedOutput); | 296 writeToStdout(serializedOutput); |
124 | 297 |
125 return true; | 298 return true; |
126 } | 299 } |
127 | 300 |
128 public void run() throws Exception { | 301 public void run() throws Exception { |
129 typeRegistry = TypeRegistry.newBuilder().add( | 302 typeRegistry = TypeRegistry.newBuilder().add( |
130 Conformance.TestAllTypes.getDescriptor()).build(); | 303 TestMessagesProto3.TestAllTypes.getDescriptor()).build(); |
131 while (doTestIo()) { | 304 while (doTestIo()) { |
132 this.testCount++; | 305 this.testCount++; |
133 } | 306 } |
134 | 307 |
135 System.err.println("ConformanceJava: received EOF from test runner after " + | 308 System.err.println("ConformanceJava: received EOF from test runner after " + |
136 this.testCount + " tests"); | 309 this.testCount + " tests"); |
137 } | 310 } |
138 | 311 |
139 public static void main(String[] args) throws Exception { | 312 public static void main(String[] args) throws Exception { |
140 new ConformanceJava().run(); | 313 new ConformanceJava().run(); |
141 } | 314 } |
142 } | 315 } |
OLD | NEW |