Adds fuzz target for oss-fuzz integration
diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am
index 0dfa5fa..2971cfd 100644
--- a/lib/go/Makefile.am
+++ b/lib/go/Makefile.am
@@ -20,7 +20,7 @@
 SUBDIRS = .
 
 if WITH_TESTS
-SUBDIRS += test
+SUBDIRS += test test/fuzz
 endif
 
 install:
diff --git a/lib/go/test/fuzz/Makefile.am b/lib/go/test/fuzz/Makefile.am
new file mode 100644
index 0000000..41f8b45
--- /dev/null
+++ b/lib/go/test/fuzz/Makefile.am
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+gopathfuzz: $(THRIFT) fuzz.go
+	$(THRIFT) -r --gen go ../../../../tutorial/tutorial.thrift
+	GO111MODULE=on go mod init fuzz
+	GO111MODULE=on cd gen-go/shared && go mod init shared
+	GO111MODULE=on cd gen-go/tutorial && go mod init tutorial
+	GO111MODULE=on go mod edit -replace shared=./gen-go/shared
+	GO111MODULE=on go mod edit -replace tutorial=./gen-go/tutorial
+	GO111MODULE=on cd ../../../../lib/go/thrift && go mod init github.com/apache/thrift/lib/go/thrift
+	GO111MODULE=on go mod edit -replace github.com/apache/thrift/lib/go/thrift=../../../../lib/go/thrift
+	GO111MODULE=on go mod tidy
+	touch gopathfuzz
+
+check: gopathfuzz
+	go test -tags gofuzz
+
+clean-local:
+	$(RM) -r gopathfuzz gen-go
+
diff --git a/lib/go/test/fuzz/fuzz.go b/lib/go/test/fuzz/fuzz.go
new file mode 100644
index 0000000..388524c
--- /dev/null
+++ b/lib/go/test/fuzz/fuzz.go
@@ -0,0 +1,143 @@
+// +build gofuzz
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package fuzz
+
+import (
+	"context"
+	"fmt"
+	"shared"
+	"strconv"
+	"tutorial"
+
+	"github.com/apache/thrift/lib/go/thrift"
+)
+
+const nbFuzzedProtocols = 2
+
+func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol {
+	switch d % nbFuzzedProtocols {
+	default:
+		fallthrough
+	case 0:
+		return thrift.NewTBinaryProtocolFactoryConf(nil).GetProtocol(t)
+	case 1:
+		return thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(t)
+	}
+}
+
+func Fuzz(data []byte) int {
+	if len(data) < 2 {
+		return 0
+	}
+	inputTransport := thrift.NewTMemoryBuffer()
+	inputTransport.Buffer.Write(data[2:])
+	outputTransport := thrift.NewTMemoryBuffer()
+	outputProtocol := fuzzChooseProtocol(data[0], outputTransport)
+	inputProtocol := fuzzChooseProtocol(data[1], inputTransport)
+	ctx := thrift.SetResponseHelper(
+		context.Background(),
+		thrift.TResponseHelper{
+			THeaderResponseHelper: thrift.NewTHeaderResponseHelper(outputProtocol),
+		},
+	)
+	handler := NewCalculatorHandler()
+	processor := tutorial.NewCalculatorProcessor(handler)
+	ok := true
+	var err error
+	for ok {
+		ok, err = processor.Process(ctx, inputProtocol, outputProtocol)
+		if err != nil {
+			// Handle parse error
+			return 0
+		}
+		res := make([]byte, 1024)
+		n, err := outputTransport.Buffer.Read(res)
+		fmt.Printf("lol %d %s %v\n", n, err, res)
+	}
+	return 1
+}
+
+type CalculatorHandler struct {
+	log map[int]*shared.SharedStruct
+}
+
+func NewCalculatorHandler() *CalculatorHandler {
+	return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)}
+}
+
+func (p *CalculatorHandler) Ping(ctx context.Context) (err error) {
+	fmt.Print("ping()\n")
+	return nil
+}
+
+func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) {
+	fmt.Print("add(", num1, ",", num2, ")\n")
+	return num1 + num2, nil
+}
+
+func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) {
+	fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
+	switch w.Op {
+	case tutorial.Operation_ADD:
+		val = w.Num1 + w.Num2
+		break
+	case tutorial.Operation_SUBTRACT:
+		val = w.Num1 - w.Num2
+		break
+	case tutorial.Operation_MULTIPLY:
+		val = w.Num1 * w.Num2
+		break
+	case tutorial.Operation_DIVIDE:
+		if w.Num2 == 0 {
+			ouch := tutorial.NewInvalidOperation()
+			ouch.WhatOp = int32(w.Op)
+			ouch.Why = "Cannot divide by 0"
+			err = ouch
+			return
+		}
+		val = w.Num1 / w.Num2
+		break
+	default:
+		ouch := tutorial.NewInvalidOperation()
+		ouch.WhatOp = int32(w.Op)
+		ouch.Why = "Unknown operation"
+		err = ouch
+		return
+	}
+	entry := shared.NewSharedStruct()
+	entry.Key = logid
+	entry.Value = strconv.Itoa(int(val))
+	k := int(logid)
+	p.log[k] = entry
+	return val, err
+}
+
+func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) {
+	fmt.Print("getStruct(", key, ")\n")
+	v, _ := p.log[int(key)]
+	return v, nil
+}
+
+func (p *CalculatorHandler) Zip(ctx context.Context) (err error) {
+	fmt.Print("zip()\n")
+	return nil
+}
diff --git a/lib/go/test/fuzz/fuzz_test.go b/lib/go/test/fuzz/fuzz_test.go
new file mode 100644
index 0000000..2983e0f
--- /dev/null
+++ b/lib/go/test/fuzz/fuzz_test.go
@@ -0,0 +1,30 @@
+// +build gofuzz
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package fuzz
+
+import (
+	"testing"
+)
+
+func TestFuzz(t *testing.T) {
+	Fuzz([]byte{1, 2, 3})
+}