| 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 |