1// Go support for Protocol Buffers - Google's data interchange format 2// 3// Copyright 2016 The Go Authors. All rights reserved. 4// https://github.com/golang/protobuf 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: 9// 10// * Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// * Redistributions in binary form must reproduce the above 13// copyright notice, this list of conditions and the following disclaimer 14// in the documentation and/or other materials provided with the 15// distribution. 16// * Neither the name of Google Inc. nor the names of its 17// contributors may be used to endorse or promote products derived from 18// this software without specific prior written permission. 19// 20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32// conformance implements the conformance test subprocess protocol as 33// documented in conformance.proto. 34package main 35 36import ( 37 "encoding/binary" 38 "fmt" 39 "io" 40 "os" 41 42 pb "github.com/golang/protobuf/conformance/internal/conformance_proto" 43 "github.com/golang/protobuf/jsonpb" 44 "github.com/golang/protobuf/proto" 45) 46 47func main() { 48 var sizeBuf [4]byte 49 inbuf := make([]byte, 0, 4096) 50 outbuf := proto.NewBuffer(nil) 51 for { 52 if _, err := io.ReadFull(os.Stdin, sizeBuf[:]); err == io.EOF { 53 break 54 } else if err != nil { 55 fmt.Fprintln(os.Stderr, "go conformance: read request:", err) 56 os.Exit(1) 57 } 58 size := binary.LittleEndian.Uint32(sizeBuf[:]) 59 if int(size) > cap(inbuf) { 60 inbuf = make([]byte, size) 61 } 62 inbuf = inbuf[:size] 63 if _, err := io.ReadFull(os.Stdin, inbuf); err != nil { 64 fmt.Fprintln(os.Stderr, "go conformance: read request:", err) 65 os.Exit(1) 66 } 67 68 req := new(pb.ConformanceRequest) 69 if err := proto.Unmarshal(inbuf, req); err != nil { 70 fmt.Fprintln(os.Stderr, "go conformance: parse request:", err) 71 os.Exit(1) 72 } 73 res := handle(req) 74 75 if err := outbuf.Marshal(res); err != nil { 76 fmt.Fprintln(os.Stderr, "go conformance: marshal response:", err) 77 os.Exit(1) 78 } 79 binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(outbuf.Bytes()))) 80 if _, err := os.Stdout.Write(sizeBuf[:]); err != nil { 81 fmt.Fprintln(os.Stderr, "go conformance: write response:", err) 82 os.Exit(1) 83 } 84 if _, err := os.Stdout.Write(outbuf.Bytes()); err != nil { 85 fmt.Fprintln(os.Stderr, "go conformance: write response:", err) 86 os.Exit(1) 87 } 88 outbuf.Reset() 89 } 90} 91 92var jsonMarshaler = jsonpb.Marshaler{ 93 OrigName: true, 94} 95 96func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse { 97 var err error 98 var msg pb.TestAllTypes 99 switch p := req.Payload.(type) { 100 case *pb.ConformanceRequest_ProtobufPayload: 101 err = proto.Unmarshal(p.ProtobufPayload, &msg) 102 case *pb.ConformanceRequest_JsonPayload: 103 err = jsonpb.UnmarshalString(p.JsonPayload, &msg) 104 default: 105 return &pb.ConformanceResponse{ 106 Result: &pb.ConformanceResponse_RuntimeError{ 107 RuntimeError: "unknown request payload type", 108 }, 109 } 110 } 111 if err != nil { 112 return &pb.ConformanceResponse{ 113 Result: &pb.ConformanceResponse_ParseError{ 114 ParseError: err.Error(), 115 }, 116 } 117 } 118 switch req.RequestedOutputFormat { 119 case pb.WireFormat_PROTOBUF: 120 p, err := proto.Marshal(&msg) 121 if err != nil { 122 return &pb.ConformanceResponse{ 123 Result: &pb.ConformanceResponse_SerializeError{ 124 SerializeError: err.Error(), 125 }, 126 } 127 } 128 return &pb.ConformanceResponse{ 129 Result: &pb.ConformanceResponse_ProtobufPayload{ 130 ProtobufPayload: p, 131 }, 132 } 133 case pb.WireFormat_JSON: 134 p, err := jsonMarshaler.MarshalToString(&msg) 135 if err != nil { 136 return &pb.ConformanceResponse{ 137 Result: &pb.ConformanceResponse_SerializeError{ 138 SerializeError: err.Error(), 139 }, 140 } 141 } 142 return &pb.ConformanceResponse{ 143 Result: &pb.ConformanceResponse_JsonPayload{ 144 JsonPayload: p, 145 }, 146 } 147 default: 148 return &pb.ConformanceResponse{ 149 Result: &pb.ConformanceResponse_RuntimeError{ 150 RuntimeError: "unknown output format", 151 }, 152 } 153 } 154} 155