• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import 'dart:io';
2
3import 'package:pb_runtime/pb_runtime.dart' as pb;
4import 'package:third_party.protobuf/test_messages_proto2.upb.dart';
5import 'package:third_party.protobuf/test_messages_proto3.upb.dart';
6import 'package:third_party.protobuf.conformance/conformance.upb.dart';
7
8List<int>? readFromStdin(int numBytes) {
9  final bytesOut = <int>[];
10  for (var i = 0; i < numBytes; i++) {
11    final byte = stdin.readByteSync();
12    if (byte == -1) return null;
13    bytesOut.add(byte);
14  }
15  return bytesOut;
16}
17
18int readLittleEndianIntFromStdin() {
19  final buf = readFromStdin(4);
20  if (buf == null) return -1;
21  return (buf[0] & 0xff) |
22      ((buf[1] & 0xff) << 8) |
23      ((buf[2] & 0xff) << 16) |
24      ((buf[3] & 0xff) << 24);
25}
26
27void writeLittleEndianIntToStdout(int value) {
28  final buf = <int>[];
29  buf.add(value & 0xff);
30  buf.add((value >> 8) & 0xff);
31  buf.add((value >> 16) & 0xff);
32  buf.add((value >> 24) & 0xff);
33  stdout.add(buf);
34}
35
36ConformanceResponse doTest(ConformanceRequest request) {
37  final response = ConformanceResponse();
38  pb.GeneratedMessage? testMessage;
39  final messageType = request.messageType;
40  final isProto3 =
41      messageType == 'protobuf_test_messages.proto3.TestAllTypesProto3';
42
43  if (!isProto3 &&
44      messageType != 'protobuf_test_messages.proto2.TestAllTypesProto2') {
45    throw ArgumentError('Invalid message type $messageType');
46  }
47
48  switch (request.whichPayload) {
49    case ConformanceRequest_payload.protobufPayload:
50      try {
51        testMessage = isProto3
52            ? TestAllTypesProto3.fromBuffer(request.protobufPayload)
53            : TestAllTypesProto2.fromBuffer(request.protobufPayload);
54      } catch (e) {
55        final parseErrorResponse = ConformanceResponse();
56        parseErrorResponse.parseError = '$e';
57        return parseErrorResponse;
58      }
59      break;
60    default:
61      response.skipped = 'Only protobuf payload input is supported';
62      return response;
63  }
64
65  switch (request.requestedOutputFormat) {
66    case WireFormat.PROTOBUF:
67      try {
68        response.protobufPayload = pb.GeneratedMessage.toBinary(testMessage);
69      } catch (e) {
70        response.serializeError = '$e';
71      }
72      break;
73    default:
74      response.skipped = 'Only protobuf payload output is supported';
75  }
76
77  return response;
78}
79
80Future<bool> doTestIo() async {
81  final msgLength = readLittleEndianIntFromStdin();
82  if (msgLength == -1) return false; // EOF
83  final serializedMsg = readFromStdin(msgLength);
84  if (serializedMsg == null) {
85    throw 'Unexpected EOF from test program.';
86  }
87  final request = ConformanceRequest.fromBuffer(serializedMsg);
88  final response = doTest(request);
89  final serializedOutput = pb.GeneratedMessage.toBinary(response);
90  writeLittleEndianIntToStdout(serializedOutput.length);
91  stdout.add(serializedOutput);
92  await stdout.flush();
93  return true;
94}
95
96void main() async {
97  await pb.initGlobalInstance();
98  var testCount = 0;
99  while (await doTestIo()) {
100    testCount++;
101  }
102  stderr.writeln(
103      'ConformanceDart: received EOF from test runner after $testCount tests');
104}
105