1*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format 2*1b3f573fSAndroid Build Coastguard Worker // Copyright 2008 Google Inc. All rights reserved. 3*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/ 4*1b3f573fSAndroid Build Coastguard Worker // 5*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without 6*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are 7*1b3f573fSAndroid Build Coastguard Worker // met: 8*1b3f573fSAndroid Build Coastguard Worker // 9*1b3f573fSAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright 10*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer. 11*1b3f573fSAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above 12*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer 13*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the 14*1b3f573fSAndroid Build Coastguard Worker // distribution. 15*1b3f573fSAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its 16*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from 17*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission. 18*1b3f573fSAndroid Build Coastguard Worker // 19*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*1b3f573fSAndroid Build Coastguard Worker 31*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.ByteString; 32*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.CodedInputStream; 33*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.ExtensionRegistryLite; 34*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.InvalidProtocolBufferException; 35*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.MessageLite; 36*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.Parser; 37*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf.conformance.Conformance; 38*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf_test_messages.proto2.TestMessagesProto2; 39*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf_test_messages.proto2.TestMessagesProto2.TestAllTypesProto2; 40*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf_test_messages.proto3.TestMessagesProto3; 41*1b3f573fSAndroid Build Coastguard Worker import com.google.protobuf_test_messages.proto3.TestMessagesProto3.TestAllTypesProto3; 42*1b3f573fSAndroid Build Coastguard Worker import java.nio.ByteBuffer; 43*1b3f573fSAndroid Build Coastguard Worker import java.util.ArrayList; 44*1b3f573fSAndroid Build Coastguard Worker 45*1b3f573fSAndroid Build Coastguard Worker class ConformanceJavaLite { 46*1b3f573fSAndroid Build Coastguard Worker private int testCount = 0; 47*1b3f573fSAndroid Build Coastguard Worker readFromStdin(byte[] buf, int len)48*1b3f573fSAndroid Build Coastguard Worker private boolean readFromStdin(byte[] buf, int len) throws Exception { 49*1b3f573fSAndroid Build Coastguard Worker int ofs = 0; 50*1b3f573fSAndroid Build Coastguard Worker while (len > 0) { 51*1b3f573fSAndroid Build Coastguard Worker int read = System.in.read(buf, ofs, len); 52*1b3f573fSAndroid Build Coastguard Worker if (read == -1) { 53*1b3f573fSAndroid Build Coastguard Worker return false; // EOF 54*1b3f573fSAndroid Build Coastguard Worker } 55*1b3f573fSAndroid Build Coastguard Worker ofs += read; 56*1b3f573fSAndroid Build Coastguard Worker len -= read; 57*1b3f573fSAndroid Build Coastguard Worker } 58*1b3f573fSAndroid Build Coastguard Worker 59*1b3f573fSAndroid Build Coastguard Worker return true; 60*1b3f573fSAndroid Build Coastguard Worker } 61*1b3f573fSAndroid Build Coastguard Worker writeToStdout(byte[] buf)62*1b3f573fSAndroid Build Coastguard Worker private void writeToStdout(byte[] buf) throws Exception { 63*1b3f573fSAndroid Build Coastguard Worker System.out.write(buf); 64*1b3f573fSAndroid Build Coastguard Worker } 65*1b3f573fSAndroid Build Coastguard Worker 66*1b3f573fSAndroid Build Coastguard Worker // Returns -1 on EOF (the actual values will always be positive). readLittleEndianIntFromStdin()67*1b3f573fSAndroid Build Coastguard Worker private int readLittleEndianIntFromStdin() throws Exception { 68*1b3f573fSAndroid Build Coastguard Worker byte[] buf = new byte[4]; 69*1b3f573fSAndroid Build Coastguard Worker if (!readFromStdin(buf, 4)) { 70*1b3f573fSAndroid Build Coastguard Worker return -1; 71*1b3f573fSAndroid Build Coastguard Worker } 72*1b3f573fSAndroid Build Coastguard Worker return (buf[0] & 0xff) 73*1b3f573fSAndroid Build Coastguard Worker | ((buf[1] & 0xff) << 8) 74*1b3f573fSAndroid Build Coastguard Worker | ((buf[2] & 0xff) << 16) 75*1b3f573fSAndroid Build Coastguard Worker | ((buf[3] & 0xff) << 24); 76*1b3f573fSAndroid Build Coastguard Worker } 77*1b3f573fSAndroid Build Coastguard Worker writeLittleEndianIntToStdout(int val)78*1b3f573fSAndroid Build Coastguard Worker private void writeLittleEndianIntToStdout(int val) throws Exception { 79*1b3f573fSAndroid Build Coastguard Worker byte[] buf = new byte[4]; 80*1b3f573fSAndroid Build Coastguard Worker buf[0] = (byte) val; 81*1b3f573fSAndroid Build Coastguard Worker buf[1] = (byte) (val >> 8); 82*1b3f573fSAndroid Build Coastguard Worker buf[2] = (byte) (val >> 16); 83*1b3f573fSAndroid Build Coastguard Worker buf[3] = (byte) (val >> 24); 84*1b3f573fSAndroid Build Coastguard Worker writeToStdout(buf); 85*1b3f573fSAndroid Build Coastguard Worker } 86*1b3f573fSAndroid Build Coastguard Worker 87*1b3f573fSAndroid Build Coastguard Worker private enum BinaryDecoderType { 88*1b3f573fSAndroid Build Coastguard Worker BTYE_STRING_DECODER, 89*1b3f573fSAndroid Build Coastguard Worker BYTE_ARRAY_DECODER, 90*1b3f573fSAndroid Build Coastguard Worker ARRAY_BYTE_BUFFER_DECODER, 91*1b3f573fSAndroid Build Coastguard Worker READONLY_ARRAY_BYTE_BUFFER_DECODER, 92*1b3f573fSAndroid Build Coastguard Worker DIRECT_BYTE_BUFFER_DECODER, 93*1b3f573fSAndroid Build Coastguard Worker READONLY_DIRECT_BYTE_BUFFER_DECODER, 94*1b3f573fSAndroid Build Coastguard Worker INPUT_STREAM_DECODER; 95*1b3f573fSAndroid Build Coastguard Worker } 96*1b3f573fSAndroid Build Coastguard Worker 97*1b3f573fSAndroid Build Coastguard Worker private static class BinaryDecoder<T extends MessageLite> { decode( ByteString bytes, BinaryDecoderType type, Parser<T> parser, ExtensionRegistryLite extensions)98*1b3f573fSAndroid Build Coastguard Worker public T decode( 99*1b3f573fSAndroid Build Coastguard Worker ByteString bytes, 100*1b3f573fSAndroid Build Coastguard Worker BinaryDecoderType type, 101*1b3f573fSAndroid Build Coastguard Worker Parser<T> parser, 102*1b3f573fSAndroid Build Coastguard Worker ExtensionRegistryLite extensions) 103*1b3f573fSAndroid Build Coastguard Worker throws InvalidProtocolBufferException { 104*1b3f573fSAndroid Build Coastguard Worker switch (type) { 105*1b3f573fSAndroid Build Coastguard Worker case BTYE_STRING_DECODER: 106*1b3f573fSAndroid Build Coastguard Worker case BYTE_ARRAY_DECODER: 107*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom(bytes, extensions); 108*1b3f573fSAndroid Build Coastguard Worker case ARRAY_BYTE_BUFFER_DECODER: 109*1b3f573fSAndroid Build Coastguard Worker { 110*1b3f573fSAndroid Build Coastguard Worker ByteBuffer buffer = ByteBuffer.allocate(bytes.size()); 111*1b3f573fSAndroid Build Coastguard Worker bytes.copyTo(buffer); 112*1b3f573fSAndroid Build Coastguard Worker buffer.flip(); 113*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); 114*1b3f573fSAndroid Build Coastguard Worker } 115*1b3f573fSAndroid Build Coastguard Worker case READONLY_ARRAY_BYTE_BUFFER_DECODER: 116*1b3f573fSAndroid Build Coastguard Worker { 117*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom( 118*1b3f573fSAndroid Build Coastguard Worker CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()), extensions); 119*1b3f573fSAndroid Build Coastguard Worker } 120*1b3f573fSAndroid Build Coastguard Worker case DIRECT_BYTE_BUFFER_DECODER: 121*1b3f573fSAndroid Build Coastguard Worker { 122*1b3f573fSAndroid Build Coastguard Worker ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); 123*1b3f573fSAndroid Build Coastguard Worker bytes.copyTo(buffer); 124*1b3f573fSAndroid Build Coastguard Worker buffer.flip(); 125*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); 126*1b3f573fSAndroid Build Coastguard Worker } 127*1b3f573fSAndroid Build Coastguard Worker case READONLY_DIRECT_BYTE_BUFFER_DECODER: 128*1b3f573fSAndroid Build Coastguard Worker { 129*1b3f573fSAndroid Build Coastguard Worker ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); 130*1b3f573fSAndroid Build Coastguard Worker bytes.copyTo(buffer); 131*1b3f573fSAndroid Build Coastguard Worker buffer.flip(); 132*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom( 133*1b3f573fSAndroid Build Coastguard Worker CodedInputStream.newInstance(buffer.asReadOnlyBuffer()), extensions); 134*1b3f573fSAndroid Build Coastguard Worker } 135*1b3f573fSAndroid Build Coastguard Worker case INPUT_STREAM_DECODER: 136*1b3f573fSAndroid Build Coastguard Worker { 137*1b3f573fSAndroid Build Coastguard Worker return parser.parseFrom(bytes.newInput(), extensions); 138*1b3f573fSAndroid Build Coastguard Worker } 139*1b3f573fSAndroid Build Coastguard Worker } 140*1b3f573fSAndroid Build Coastguard Worker return null; 141*1b3f573fSAndroid Build Coastguard Worker } 142*1b3f573fSAndroid Build Coastguard Worker } 143*1b3f573fSAndroid Build Coastguard Worker parseBinary( ByteString bytes, Parser<T> parser, ExtensionRegistryLite extensions)144*1b3f573fSAndroid Build Coastguard Worker private <T extends MessageLite> T parseBinary( 145*1b3f573fSAndroid Build Coastguard Worker ByteString bytes, Parser<T> parser, ExtensionRegistryLite extensions) 146*1b3f573fSAndroid Build Coastguard Worker throws InvalidProtocolBufferException { 147*1b3f573fSAndroid Build Coastguard Worker ArrayList<T> messages = new ArrayList<>(); 148*1b3f573fSAndroid Build Coastguard Worker ArrayList<InvalidProtocolBufferException> exceptions = new ArrayList<>(); 149*1b3f573fSAndroid Build Coastguard Worker 150*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < BinaryDecoderType.values().length; i++) { 151*1b3f573fSAndroid Build Coastguard Worker messages.add(null); 152*1b3f573fSAndroid Build Coastguard Worker exceptions.add(null); 153*1b3f573fSAndroid Build Coastguard Worker } 154*1b3f573fSAndroid Build Coastguard Worker if (messages.isEmpty()) { 155*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("binary decoder types missing"); 156*1b3f573fSAndroid Build Coastguard Worker } 157*1b3f573fSAndroid Build Coastguard Worker 158*1b3f573fSAndroid Build Coastguard Worker BinaryDecoder<T> decoder = new BinaryDecoder<>(); 159*1b3f573fSAndroid Build Coastguard Worker 160*1b3f573fSAndroid Build Coastguard Worker boolean hasMessage = false; 161*1b3f573fSAndroid Build Coastguard Worker boolean hasException = false; 162*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < BinaryDecoderType.values().length; ++i) { 163*1b3f573fSAndroid Build Coastguard Worker try { 164*1b3f573fSAndroid Build Coastguard Worker messages.set(i, decoder.decode(bytes, BinaryDecoderType.values()[i], parser, extensions)); 165*1b3f573fSAndroid Build Coastguard Worker hasMessage = true; 166*1b3f573fSAndroid Build Coastguard Worker } catch (InvalidProtocolBufferException e) { 167*1b3f573fSAndroid Build Coastguard Worker exceptions.set(i, e); 168*1b3f573fSAndroid Build Coastguard Worker hasException = true; 169*1b3f573fSAndroid Build Coastguard Worker } 170*1b3f573fSAndroid Build Coastguard Worker } 171*1b3f573fSAndroid Build Coastguard Worker 172*1b3f573fSAndroid Build Coastguard Worker if (hasMessage && hasException) { 173*1b3f573fSAndroid Build Coastguard Worker StringBuilder sb = 174*1b3f573fSAndroid Build Coastguard Worker new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n"); 175*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < BinaryDecoderType.values().length; ++i) { 176*1b3f573fSAndroid Build Coastguard Worker sb.append(BinaryDecoderType.values()[i].name()); 177*1b3f573fSAndroid Build Coastguard Worker if (messages.get(i) != null) { 178*1b3f573fSAndroid Build Coastguard Worker sb.append(" accepted the payload.\n"); 179*1b3f573fSAndroid Build Coastguard Worker } else { 180*1b3f573fSAndroid Build Coastguard Worker sb.append(" rejected the payload.\n"); 181*1b3f573fSAndroid Build Coastguard Worker } 182*1b3f573fSAndroid Build Coastguard Worker } 183*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException(sb.toString()); 184*1b3f573fSAndroid Build Coastguard Worker } 185*1b3f573fSAndroid Build Coastguard Worker 186*1b3f573fSAndroid Build Coastguard Worker if (hasException) { 187*1b3f573fSAndroid Build Coastguard Worker // We do not check if exceptions are equal. Different implementations may return different 188*1b3f573fSAndroid Build Coastguard Worker // exception messages. Throw an arbitrary one out instead. 189*1b3f573fSAndroid Build Coastguard Worker InvalidProtocolBufferException exception = null; 190*1b3f573fSAndroid Build Coastguard Worker for (InvalidProtocolBufferException e : exceptions) { 191*1b3f573fSAndroid Build Coastguard Worker if (exception != null) { 192*1b3f573fSAndroid Build Coastguard Worker exception.addSuppressed(e); 193*1b3f573fSAndroid Build Coastguard Worker } else { 194*1b3f573fSAndroid Build Coastguard Worker exception = e; 195*1b3f573fSAndroid Build Coastguard Worker } 196*1b3f573fSAndroid Build Coastguard Worker } 197*1b3f573fSAndroid Build Coastguard Worker throw exception; 198*1b3f573fSAndroid Build Coastguard Worker } 199*1b3f573fSAndroid Build Coastguard Worker 200*1b3f573fSAndroid Build Coastguard Worker // Fast path comparing all the messages with the first message, assuming equality being 201*1b3f573fSAndroid Build Coastguard Worker // symmetric and transitive. 202*1b3f573fSAndroid Build Coastguard Worker boolean allEqual = true; 203*1b3f573fSAndroid Build Coastguard Worker for (int i = 1; i < messages.size(); ++i) { 204*1b3f573fSAndroid Build Coastguard Worker if (!messages.get(0).equals(messages.get(i))) { 205*1b3f573fSAndroid Build Coastguard Worker allEqual = false; 206*1b3f573fSAndroid Build Coastguard Worker break; 207*1b3f573fSAndroid Build Coastguard Worker } 208*1b3f573fSAndroid Build Coastguard Worker } 209*1b3f573fSAndroid Build Coastguard Worker 210*1b3f573fSAndroid Build Coastguard Worker // Slow path: compare and find out all unequal pairs. 211*1b3f573fSAndroid Build Coastguard Worker if (!allEqual) { 212*1b3f573fSAndroid Build Coastguard Worker StringBuilder sb = new StringBuilder(); 213*1b3f573fSAndroid Build Coastguard Worker for (int i = 0; i < messages.size() - 1; ++i) { 214*1b3f573fSAndroid Build Coastguard Worker for (int j = i + 1; j < messages.size(); ++j) { 215*1b3f573fSAndroid Build Coastguard Worker if (!messages.get(i).equals(messages.get(j))) { 216*1b3f573fSAndroid Build Coastguard Worker sb.append(BinaryDecoderType.values()[i].name()) 217*1b3f573fSAndroid Build Coastguard Worker .append(" and ") 218*1b3f573fSAndroid Build Coastguard Worker .append(BinaryDecoderType.values()[j].name()) 219*1b3f573fSAndroid Build Coastguard Worker .append(" parsed the payload differently.\n"); 220*1b3f573fSAndroid Build Coastguard Worker } 221*1b3f573fSAndroid Build Coastguard Worker } 222*1b3f573fSAndroid Build Coastguard Worker } 223*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException(sb.toString()); 224*1b3f573fSAndroid Build Coastguard Worker } 225*1b3f573fSAndroid Build Coastguard Worker 226*1b3f573fSAndroid Build Coastguard Worker return messages.get(0); 227*1b3f573fSAndroid Build Coastguard Worker } 228*1b3f573fSAndroid Build Coastguard Worker doTest(Conformance.ConformanceRequest request)229*1b3f573fSAndroid Build Coastguard Worker private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) { 230*1b3f573fSAndroid Build Coastguard Worker com.google.protobuf.MessageLite testMessage; 231*1b3f573fSAndroid Build Coastguard Worker boolean isProto3 = 232*1b3f573fSAndroid Build Coastguard Worker request.getMessageType().equals("protobuf_test_messages.proto3.TestAllTypesProto3"); 233*1b3f573fSAndroid Build Coastguard Worker boolean isProto2 = 234*1b3f573fSAndroid Build Coastguard Worker request.getMessageType().equals("protobuf_test_messages.proto2.TestAllTypesProto2"); 235*1b3f573fSAndroid Build Coastguard Worker 236*1b3f573fSAndroid Build Coastguard Worker switch (request.getPayloadCase()) { 237*1b3f573fSAndroid Build Coastguard Worker case PROTOBUF_PAYLOAD: 238*1b3f573fSAndroid Build Coastguard Worker { 239*1b3f573fSAndroid Build Coastguard Worker if (isProto3) { 240*1b3f573fSAndroid Build Coastguard Worker try { 241*1b3f573fSAndroid Build Coastguard Worker ExtensionRegistryLite extensions = ExtensionRegistryLite.newInstance(); 242*1b3f573fSAndroid Build Coastguard Worker TestMessagesProto3.registerAllExtensions(extensions); 243*1b3f573fSAndroid Build Coastguard Worker testMessage = 244*1b3f573fSAndroid Build Coastguard Worker parseBinary( 245*1b3f573fSAndroid Build Coastguard Worker request.getProtobufPayload(), TestAllTypesProto3.parser(), extensions); 246*1b3f573fSAndroid Build Coastguard Worker } catch (InvalidProtocolBufferException e) { 247*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 248*1b3f573fSAndroid Build Coastguard Worker .setParseError(e.getMessage()) 249*1b3f573fSAndroid Build Coastguard Worker .build(); 250*1b3f573fSAndroid Build Coastguard Worker } 251*1b3f573fSAndroid Build Coastguard Worker } else if (isProto2) { 252*1b3f573fSAndroid Build Coastguard Worker try { 253*1b3f573fSAndroid Build Coastguard Worker ExtensionRegistryLite extensions = ExtensionRegistryLite.newInstance(); 254*1b3f573fSAndroid Build Coastguard Worker TestMessagesProto2.registerAllExtensions(extensions); 255*1b3f573fSAndroid Build Coastguard Worker testMessage = 256*1b3f573fSAndroid Build Coastguard Worker parseBinary( 257*1b3f573fSAndroid Build Coastguard Worker request.getProtobufPayload(), TestAllTypesProto2.parser(), extensions); 258*1b3f573fSAndroid Build Coastguard Worker } catch (InvalidProtocolBufferException e) { 259*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 260*1b3f573fSAndroid Build Coastguard Worker .setParseError(e.getMessage()) 261*1b3f573fSAndroid Build Coastguard Worker .build(); 262*1b3f573fSAndroid Build Coastguard Worker } 263*1b3f573fSAndroid Build Coastguard Worker } else { 264*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Protobuf request doesn't have specific payload type."); 265*1b3f573fSAndroid Build Coastguard Worker } 266*1b3f573fSAndroid Build Coastguard Worker break; 267*1b3f573fSAndroid Build Coastguard Worker } 268*1b3f573fSAndroid Build Coastguard Worker case JSON_PAYLOAD: 269*1b3f573fSAndroid Build Coastguard Worker { 270*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 271*1b3f573fSAndroid Build Coastguard Worker .setSkipped("Lite runtime does not support JSON format.") 272*1b3f573fSAndroid Build Coastguard Worker .build(); 273*1b3f573fSAndroid Build Coastguard Worker } 274*1b3f573fSAndroid Build Coastguard Worker case TEXT_PAYLOAD: 275*1b3f573fSAndroid Build Coastguard Worker { 276*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 277*1b3f573fSAndroid Build Coastguard Worker .setSkipped("Lite runtime does not support Text format.") 278*1b3f573fSAndroid Build Coastguard Worker .build(); 279*1b3f573fSAndroid Build Coastguard Worker } 280*1b3f573fSAndroid Build Coastguard Worker case PAYLOAD_NOT_SET: 281*1b3f573fSAndroid Build Coastguard Worker { 282*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Request didn't have payload."); 283*1b3f573fSAndroid Build Coastguard Worker } 284*1b3f573fSAndroid Build Coastguard Worker default: 285*1b3f573fSAndroid Build Coastguard Worker { 286*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected payload case."); 287*1b3f573fSAndroid Build Coastguard Worker } 288*1b3f573fSAndroid Build Coastguard Worker } 289*1b3f573fSAndroid Build Coastguard Worker 290*1b3f573fSAndroid Build Coastguard Worker switch (request.getRequestedOutputFormat()) { 291*1b3f573fSAndroid Build Coastguard Worker case UNSPECIFIED: 292*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Unspecified output format."); 293*1b3f573fSAndroid Build Coastguard Worker 294*1b3f573fSAndroid Build Coastguard Worker case PROTOBUF: 295*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 296*1b3f573fSAndroid Build Coastguard Worker .setProtobufPayload(testMessage.toByteString()) 297*1b3f573fSAndroid Build Coastguard Worker .build(); 298*1b3f573fSAndroid Build Coastguard Worker 299*1b3f573fSAndroid Build Coastguard Worker case JSON: 300*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 301*1b3f573fSAndroid Build Coastguard Worker .setSkipped("Lite runtime does not support JSON format.") 302*1b3f573fSAndroid Build Coastguard Worker .build(); 303*1b3f573fSAndroid Build Coastguard Worker 304*1b3f573fSAndroid Build Coastguard Worker case TEXT_FORMAT: 305*1b3f573fSAndroid Build Coastguard Worker return Conformance.ConformanceResponse.newBuilder() 306*1b3f573fSAndroid Build Coastguard Worker .setSkipped("Lite runtime does not support Text format.") 307*1b3f573fSAndroid Build Coastguard Worker .build(); 308*1b3f573fSAndroid Build Coastguard Worker default: 309*1b3f573fSAndroid Build Coastguard Worker { 310*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected request output."); 311*1b3f573fSAndroid Build Coastguard Worker } 312*1b3f573fSAndroid Build Coastguard Worker } 313*1b3f573fSAndroid Build Coastguard Worker } 314*1b3f573fSAndroid Build Coastguard Worker doTestIo()315*1b3f573fSAndroid Build Coastguard Worker private boolean doTestIo() throws Exception { 316*1b3f573fSAndroid Build Coastguard Worker int bytes = readLittleEndianIntFromStdin(); 317*1b3f573fSAndroid Build Coastguard Worker 318*1b3f573fSAndroid Build Coastguard Worker if (bytes == -1) { 319*1b3f573fSAndroid Build Coastguard Worker return false; // EOF 320*1b3f573fSAndroid Build Coastguard Worker } 321*1b3f573fSAndroid Build Coastguard Worker 322*1b3f573fSAndroid Build Coastguard Worker byte[] serializedInput = new byte[bytes]; 323*1b3f573fSAndroid Build Coastguard Worker 324*1b3f573fSAndroid Build Coastguard Worker if (!readFromStdin(serializedInput, bytes)) { 325*1b3f573fSAndroid Build Coastguard Worker throw new RuntimeException("Unexpected EOF from test program."); 326*1b3f573fSAndroid Build Coastguard Worker } 327*1b3f573fSAndroid Build Coastguard Worker 328*1b3f573fSAndroid Build Coastguard Worker Conformance.ConformanceRequest request = 329*1b3f573fSAndroid Build Coastguard Worker Conformance.ConformanceRequest.parseFrom(serializedInput); 330*1b3f573fSAndroid Build Coastguard Worker Conformance.ConformanceResponse response = doTest(request); 331*1b3f573fSAndroid Build Coastguard Worker byte[] serializedOutput = response.toByteArray(); 332*1b3f573fSAndroid Build Coastguard Worker 333*1b3f573fSAndroid Build Coastguard Worker writeLittleEndianIntToStdout(serializedOutput.length); 334*1b3f573fSAndroid Build Coastguard Worker writeToStdout(serializedOutput); 335*1b3f573fSAndroid Build Coastguard Worker 336*1b3f573fSAndroid Build Coastguard Worker return true; 337*1b3f573fSAndroid Build Coastguard Worker } 338*1b3f573fSAndroid Build Coastguard Worker run()339*1b3f573fSAndroid Build Coastguard Worker public void run() throws Exception { 340*1b3f573fSAndroid Build Coastguard Worker while (doTestIo()) { 341*1b3f573fSAndroid Build Coastguard Worker this.testCount++; 342*1b3f573fSAndroid Build Coastguard Worker } 343*1b3f573fSAndroid Build Coastguard Worker 344*1b3f573fSAndroid Build Coastguard Worker System.err.println( 345*1b3f573fSAndroid Build Coastguard Worker "ConformanceJavaLite: received EOF from test runner after " + this.testCount + " tests"); 346*1b3f573fSAndroid Build Coastguard Worker } 347*1b3f573fSAndroid Build Coastguard Worker main(String[] args)348*1b3f573fSAndroid Build Coastguard Worker public static void main(String[] args) throws Exception { 349*1b3f573fSAndroid Build Coastguard Worker new ConformanceJavaLite().run(); 350*1b3f573fSAndroid Build Coastguard Worker } 351*1b3f573fSAndroid Build Coastguard Worker } 352