protobuf-go/internal/cmd/conformance/main.go
Joe Tsai cdb7773569 encoding: switch ordering of Unmarshal arguments
While it is general convention that the receiver being mutated
is the first argument, the standard library specifically goes against
this convention when it comes to the Unmarshal function.

Switch the ordering of the Unmarshal function to match the Go stdlib.

Change-Id: I893346680233ef9fec7104415a54a0a7ae353378
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/177258
Reviewed-by: Damien Neil <dneil@google.com>
2019-05-14 23:18:07 +00:00

127 lines
3.2 KiB
Go

// 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"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
pb "google.golang.org/protobuf/internal/testprotos/conformance"
)
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:
err = protojson.UnmarshalOptions{
DiscardUnknown: req.TestCategory == pb.TestCategory_JSON_IGNORE_UNKNOWN_PARSING_TEST,
}.Unmarshal([]byte(p.JsonPayload), msg)
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:
p, err := protojson.Marshal(msg)
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",
},
}
}
}