2019-04-25 01:19:57 -07:00
|
|
|
// Copyright 2019 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// This binary implements the conformance test subprocess protocol as documented
|
|
|
|
// in conformance.proto.
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
|
2019-05-14 12:44:37 -07:00
|
|
|
"google.golang.org/protobuf/encoding/protojson"
|
2019-05-13 23:55:40 -07:00
|
|
|
"google.golang.org/protobuf/proto"
|
2019-04-25 01:19:57 -07:00
|
|
|
|
2019-05-13 23:55:40 -07:00
|
|
|
pb "google.golang.org/protobuf/internal/testprotos/conformance"
|
2019-04-25 01:19:57 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var sizeBuf [4]byte
|
|
|
|
inbuf := make([]byte, 0, 4096)
|
|
|
|
for {
|
|
|
|
_, err := io.ReadFull(os.Stdin, sizeBuf[:])
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("conformance: read request: %v", err)
|
|
|
|
}
|
|
|
|
size := binary.LittleEndian.Uint32(sizeBuf[:])
|
|
|
|
if int(size) > cap(inbuf) {
|
|
|
|
inbuf = make([]byte, size)
|
|
|
|
}
|
|
|
|
inbuf = inbuf[:size]
|
|
|
|
if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
|
|
|
|
log.Fatalf("conformance: read request: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req := &pb.ConformanceRequest{}
|
|
|
|
if err := proto.Unmarshal(inbuf, req); err != nil {
|
|
|
|
log.Fatalf("conformance: parse request: %v", err)
|
|
|
|
}
|
|
|
|
res := handle(req)
|
|
|
|
|
|
|
|
out, err := proto.Marshal(res)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("conformance: marshal response: %v", err)
|
|
|
|
}
|
|
|
|
binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(out)))
|
|
|
|
if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
|
|
|
|
log.Fatalf("conformance: write response: %v", err)
|
|
|
|
}
|
|
|
|
if _, err := os.Stdout.Write(out); err != nil {
|
|
|
|
log.Fatalf("conformance: write response: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse {
|
|
|
|
var err error
|
|
|
|
var msg proto.Message = &pb.TestAllTypesProto2{}
|
|
|
|
if req.GetMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3" {
|
|
|
|
msg = &pb.TestAllTypesProto3{}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch p := req.Payload.(type) {
|
|
|
|
case *pb.ConformanceRequest_ProtobufPayload:
|
|
|
|
err = proto.Unmarshal(p.ProtobufPayload, msg)
|
|
|
|
case *pb.ConformanceRequest_JsonPayload:
|
2019-05-14 12:44:37 -07:00
|
|
|
err = protojson.UnmarshalOptions{
|
2019-04-25 17:57:12 -07:00
|
|
|
DiscardUnknown: req.TestCategory == pb.TestCategory_JSON_IGNORE_UNKNOWN_PARSING_TEST,
|
2019-05-14 16:05:06 -07:00
|
|
|
}.Unmarshal([]byte(p.JsonPayload), msg)
|
2019-04-25 01:19:57 -07:00
|
|
|
default:
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_RuntimeError{
|
|
|
|
RuntimeError: "unknown request payload type",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_ParseError{
|
|
|
|
ParseError: err.Error(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch req.RequestedOutputFormat {
|
|
|
|
case pb.WireFormat_PROTOBUF:
|
|
|
|
p, err := proto.Marshal(msg)
|
|
|
|
if err != nil {
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_SerializeError{
|
|
|
|
SerializeError: err.Error(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_ProtobufPayload{
|
|
|
|
ProtobufPayload: p,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
case pb.WireFormat_JSON:
|
2019-05-14 12:44:37 -07:00
|
|
|
p, err := protojson.Marshal(msg)
|
2019-04-25 01:19:57 -07:00
|
|
|
if err != nil {
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_SerializeError{
|
|
|
|
SerializeError: err.Error(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_JsonPayload{
|
|
|
|
JsonPayload: string(p),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return &pb.ConformanceResponse{
|
|
|
|
Result: &pb.ConformanceResponse_RuntimeError{
|
|
|
|
RuntimeError: "unknown output format",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|