blob: 52623761b499ae92c471c48eddb694fd509b42d9 [file] [log] [blame]
Herbie Ongd64dceb2019-04-25 01:19:57 -07001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This binary implements the conformance test subprocess protocol as documented
6// in conformance.proto.
7package main
8
9import (
10 "encoding/binary"
11 "io"
12 "log"
13 "os"
14
Damien Neil5c5b5312019-05-14 12:44:37 -070015 "google.golang.org/protobuf/encoding/protojson"
Damien Neile89e6242019-05-13 23:55:40 -070016 "google.golang.org/protobuf/proto"
Herbie Ongd64dceb2019-04-25 01:19:57 -070017
Damien Neile89e6242019-05-13 23:55:40 -070018 pb "google.golang.org/protobuf/internal/testprotos/conformance"
Herbie Ongd64dceb2019-04-25 01:19:57 -070019)
20
21func main() {
22 var sizeBuf [4]byte
23 inbuf := make([]byte, 0, 4096)
24 for {
25 _, err := io.ReadFull(os.Stdin, sizeBuf[:])
26 if err == io.EOF {
27 break
28 }
29 if err != nil {
30 log.Fatalf("conformance: read request: %v", err)
31 }
32 size := binary.LittleEndian.Uint32(sizeBuf[:])
33 if int(size) > cap(inbuf) {
34 inbuf = make([]byte, size)
35 }
36 inbuf = inbuf[:size]
37 if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
38 log.Fatalf("conformance: read request: %v", err)
39 }
40
41 req := &pb.ConformanceRequest{}
42 if err := proto.Unmarshal(inbuf, req); err != nil {
43 log.Fatalf("conformance: parse request: %v", err)
44 }
45 res := handle(req)
46
47 out, err := proto.Marshal(res)
48 if err != nil {
49 log.Fatalf("conformance: marshal response: %v", err)
50 }
51 binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(out)))
52 if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
53 log.Fatalf("conformance: write response: %v", err)
54 }
55 if _, err := os.Stdout.Write(out); err != nil {
56 log.Fatalf("conformance: write response: %v", err)
57 }
58 }
59}
60
61func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse {
62 var err error
63 var msg proto.Message = &pb.TestAllTypesProto2{}
64 if req.GetMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3" {
65 msg = &pb.TestAllTypesProto3{}
66 }
67
68 switch p := req.Payload.(type) {
69 case *pb.ConformanceRequest_ProtobufPayload:
70 err = proto.Unmarshal(p.ProtobufPayload, msg)
71 case *pb.ConformanceRequest_JsonPayload:
Damien Neil5c5b5312019-05-14 12:44:37 -070072 err = protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -070073 DiscardUnknown: req.TestCategory == pb.TestCategory_JSON_IGNORE_UNKNOWN_PARSING_TEST,
74 }.Unmarshal(msg, []byte(p.JsonPayload))
Herbie Ongd64dceb2019-04-25 01:19:57 -070075 default:
76 return &pb.ConformanceResponse{
77 Result: &pb.ConformanceResponse_RuntimeError{
78 RuntimeError: "unknown request payload type",
79 },
80 }
81 }
82 if err != nil {
83 return &pb.ConformanceResponse{
84 Result: &pb.ConformanceResponse_ParseError{
85 ParseError: err.Error(),
86 },
87 }
88 }
89
90 switch req.RequestedOutputFormat {
91 case pb.WireFormat_PROTOBUF:
92 p, err := proto.Marshal(msg)
93 if err != nil {
94 return &pb.ConformanceResponse{
95 Result: &pb.ConformanceResponse_SerializeError{
96 SerializeError: err.Error(),
97 },
98 }
99 }
100 return &pb.ConformanceResponse{
101 Result: &pb.ConformanceResponse_ProtobufPayload{
102 ProtobufPayload: p,
103 },
104 }
105 case pb.WireFormat_JSON:
Damien Neil5c5b5312019-05-14 12:44:37 -0700106 p, err := protojson.Marshal(msg)
Herbie Ongd64dceb2019-04-25 01:19:57 -0700107 if err != nil {
108 return &pb.ConformanceResponse{
109 Result: &pb.ConformanceResponse_SerializeError{
110 SerializeError: err.Error(),
111 },
112 }
113 }
114 return &pb.ConformanceResponse{
115 Result: &pb.ConformanceResponse_JsonPayload{
116 JsonPayload: string(p),
117 },
118 }
119 default:
120 return &pb.ConformanceResponse{
121 Result: &pb.ConformanceResponse_RuntimeError{
122 RuntimeError: "unknown output format",
123 },
124 }
125 }
126}