1 2 import com.google.protobuf.conformance.Conformance; 3 import com.google.protobuf.InvalidProtocolBufferException; 4 5 class ConformanceJavaLite { 6 private int testCount = 0; 7 readFromStdin(byte[] buf, int len)8 private boolean readFromStdin(byte[] buf, int len) throws Exception { 9 int ofs = 0; 10 while (len > 0) { 11 int read = System.in.read(buf, ofs, len); 12 if (read == -1) { 13 return false; // EOF 14 } 15 ofs += read; 16 len -= read; 17 } 18 19 return true; 20 } 21 writeToStdout(byte[] buf)22 private void writeToStdout(byte[] buf) throws Exception { 23 System.out.write(buf); 24 } 25 26 // Returns -1 on EOF (the actual values will always be positive). readLittleEndianIntFromStdin()27 private int readLittleEndianIntFromStdin() throws Exception { 28 byte[] buf = new byte[4]; 29 if (!readFromStdin(buf, 4)) { 30 return -1; 31 } 32 return (buf[0] & 0xff) 33 | ((buf[1] & 0xff) << 8) 34 | ((buf[2] & 0xff) << 16) 35 | ((buf[3] & 0xff) << 24); 36 } 37 writeLittleEndianIntToStdout(int val)38 private void writeLittleEndianIntToStdout(int val) throws Exception { 39 byte[] buf = new byte[4]; 40 buf[0] = (byte)val; 41 buf[1] = (byte)(val >> 8); 42 buf[2] = (byte)(val >> 16); 43 buf[3] = (byte)(val >> 24); 44 writeToStdout(buf); 45 } 46 doTest(Conformance.ConformanceRequest request)47 private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) { 48 Conformance.TestAllTypes testMessage; 49 50 switch (request.getPayloadCase()) { 51 case PROTOBUF_PAYLOAD: { 52 try { 53 testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload()); 54 } catch (InvalidProtocolBufferException e) { 55 return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build(); 56 } 57 break; 58 } 59 case JSON_PAYLOAD: { 60 return Conformance.ConformanceResponse.newBuilder().setSkipped( 61 "Lite runtime does not support JSON format.").build(); 62 } 63 case PAYLOAD_NOT_SET: { 64 throw new RuntimeException("Request didn't have payload."); 65 } 66 67 default: { 68 throw new RuntimeException("Unexpected payload case."); 69 } 70 } 71 72 switch (request.getRequestedOutputFormat()) { 73 case UNSPECIFIED: 74 throw new RuntimeException("Unspecified output format."); 75 76 case PROTOBUF: 77 return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build(); 78 79 case JSON: 80 return Conformance.ConformanceResponse.newBuilder().setSkipped( 81 "Lite runtime does not support JSON format.").build(); 82 83 default: { 84 throw new RuntimeException("Unexpected request output."); 85 } 86 } 87 } 88 doTestIo()89 private boolean doTestIo() throws Exception { 90 int bytes = readLittleEndianIntFromStdin(); 91 92 if (bytes == -1) { 93 return false; // EOF 94 } 95 96 byte[] serializedInput = new byte[bytes]; 97 98 if (!readFromStdin(serializedInput, bytes)) { 99 throw new RuntimeException("Unexpected EOF from test program."); 100 } 101 102 Conformance.ConformanceRequest request = 103 Conformance.ConformanceRequest.parseFrom(serializedInput); 104 Conformance.ConformanceResponse response = doTest(request); 105 byte[] serializedOutput = response.toByteArray(); 106 107 writeLittleEndianIntToStdout(serializedOutput.length); 108 writeToStdout(serializedOutput); 109 110 return true; 111 } 112 run()113 public void run() throws Exception { 114 while (doTestIo()) { 115 this.testCount++; 116 } 117 118 System.err.println("ConformanceJavaLite: received EOF from test runner after " + 119 this.testCount + " tests"); 120 } 121 main(String[] args)122 public static void main(String[] args) throws Exception { 123 new ConformanceJavaLite().run(); 124 } 125 } 126