xref: /aosp_15_r20/external/protobuf/conformance/ConformanceJavaLite.java (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
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