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. 34 package main 35 36 import ( 37 "encoding/binary" 38 "fmt" 39 "io" 40 "os" 41 42 pb "github.com/golang/protobuf/_conformance/conformance_proto" 43 "github.com/golang/protobuf/jsonpb" 44 "github.com/golang/protobuf/proto" 45 ) 46 47 func 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 92 var jsonMarshaler = jsonpb.Marshaler{ 93 OrigName: true, 94 } 95 96 func 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 if err != nil && err.Error() == "unmarshaling Any not supported yet" { 105 return &pb.ConformanceResponse{ 106 Result: &pb.ConformanceResponse_Skipped{ 107 Skipped: err.Error(), 108 }, 109 } 110 } 111 default: 112 return &pb.ConformanceResponse{ 113 Result: &pb.ConformanceResponse_RuntimeError{ 114 RuntimeError: "unknown request payload type", 115 }, 116 } 117 } 118 if err != nil { 119 return &pb.ConformanceResponse{ 120 Result: &pb.ConformanceResponse_ParseError{ 121 ParseError: err.Error(), 122 }, 123 } 124 } 125 switch req.RequestedOutputFormat { 126 case pb.WireFormat_PROTOBUF: 127 p, err := proto.Marshal(&msg) 128 if err != nil { 129 return &pb.ConformanceResponse{ 130 Result: &pb.ConformanceResponse_SerializeError{ 131 SerializeError: err.Error(), 132 }, 133 } 134 } 135 return &pb.ConformanceResponse{ 136 Result: &pb.ConformanceResponse_ProtobufPayload{ 137 ProtobufPayload: p, 138 }, 139 } 140 case pb.WireFormat_JSON: 141 p, err := jsonMarshaler.MarshalToString(&msg) 142 if err != nil { 143 return &pb.ConformanceResponse{ 144 Result: &pb.ConformanceResponse_SerializeError{ 145 SerializeError: err.Error(), 146 }, 147 } 148 } 149 return &pb.ConformanceResponse{ 150 Result: &pb.ConformanceResponse_JsonPayload{ 151 JsonPayload: p, 152 }, 153 } 154 default: 155 return &pb.ConformanceResponse{ 156 Result: &pb.ConformanceResponse_RuntimeError{ 157 RuntimeError: "unknown output format", 158 }, 159 } 160 } 161 } 162