Implement oneof support.

This includes the code generation changes,
and the infrastructure to wire it up to the encode/decode machinery.

The overall API changes are these:
  - oneofs in a message are replaced by a single interface field
  - each field in a oneof gets a distinguished type that satisfies
    the corresponding interface
  - a type switch may be used to distinguish between oneof fields

Fixes #29.
diff --git a/jsonpb/jsonpb.go b/jsonpb/jsonpb.go
index fb5e087..2663c92 100644
--- a/jsonpb/jsonpb.go
+++ b/jsonpb/jsonpb.go
@@ -111,6 +111,18 @@
 			}
 		}
 
+		// Oneof fields need special handling.
+		if valueField.Tag.Get("protobuf_oneof") != "" {
+			// value is an interface containing &T{real_value}.
+			sv := value.Elem().Elem() // interface -> *T -> T
+			value = sv.Field(0)
+			valueField = sv.Type().Field(0)
+
+			var p proto.Properties
+			p.Parse(sv.Type().Field(0).Tag.Get("protobuf"))
+			fieldName = p.OrigName
+		}
+
 		out.write(writeBeforeField)
 		if m.Indent != "" {
 			out.write(indent)
@@ -319,6 +331,44 @@
 				delete(jsonFields, fieldName)
 			}
 		}
+		// Check for any oneof fields.
+		// This might be slow; we can optimise it if it becomes a problem.
+		type oneofMessage interface {
+			XXX_OneofFuncs() (func(proto.Message, *proto.Buffer) error, func(proto.Message, int, int, *proto.Buffer) (bool, error), []interface{})
+		}
+		var oneofTypes []interface{}
+		if om, ok := reflect.Zero(reflect.PtrTo(targetType)).Interface().(oneofMessage); ok {
+			_, _, oneofTypes = om.XXX_OneofFuncs()
+		}
+		for fname, raw := range jsonFields {
+			for _, oot := range oneofTypes {
+				sp := reflect.ValueOf(oot).Type() // *T
+				var props proto.Properties
+				props.Parse(sp.Elem().Field(0).Tag.Get("protobuf"))
+				if props.OrigName != fname {
+					continue
+				}
+				nv := reflect.New(sp.Elem())
+				// There will be exactly one interface field that
+				// this new value is assignable to.
+				for i := 0; i < targetType.NumField(); i++ {
+					f := targetType.Field(i)
+					if f.Type.Kind() != reflect.Interface {
+						continue
+					}
+					if !nv.Type().AssignableTo(f.Type) {
+						continue
+					}
+					target.Field(i).Set(nv)
+					break
+				}
+				if err := unmarshalValue(nv.Elem().Field(0), raw); err != nil {
+					return err
+				}
+				delete(jsonFields, fname)
+				break
+			}
+		}
 		if len(jsonFields) > 0 {
 			// Pick any field to be the scapegoat.
 			var f string
diff --git a/jsonpb/jsonpb_test.go b/jsonpb/jsonpb_test.go
index 180d5d2..200e02c 100644
--- a/jsonpb/jsonpb_test.go
+++ b/jsonpb/jsonpb_test.go
@@ -32,6 +32,7 @@
 package jsonpb
 
 import (
+	"reflect"
 	"testing"
 
 	pb "github.com/golang/protobuf/jsonpb/jsonpb_test_proto"
@@ -291,6 +292,8 @@
 	{"proto2 map<bool, Object>", marshaler,
 		&pb.Maps{MBoolSimple: map[bool]*pb.Simple{true: &pb.Simple{OInt32: proto.Int32(1)}}},
 		`{"m_bool_simple":{"true":{"o_int32":1}}}`},
+	{"oneof, not set", marshaler, &pb.MsgWithOneof{}, `{}`},
+	{"oneof, set", marshaler, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Title{"Grand Poobah"}}, `{"title":"Grand Poobah"}`},
 }
 
 func TestMarshaling(t *testing.T) {
@@ -325,13 +328,13 @@
 	{"map<int64, int32>", `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}},
 	{"map<string, string>", `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}},
 	{"map<int32, Object>", `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}},
+	{"oneof", `{"salary":31000}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Salary{31000}}},
 }
 
 func TestUnmarshaling(t *testing.T) {
 	for _, tt := range unmarshalingTests {
 		// Make a new instance of the type of our expected object.
-		p := proto.Clone(tt.pb)
-		p.Reset()
+		p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message)
 
 		err := UnmarshalString(tt.json, p)
 		if err != nil {
diff --git a/jsonpb/jsonpb_test_proto/more_test_objects.pb.go b/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
index 615d57a..2634853 100644
--- a/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
+++ b/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
@@ -16,9 +16,13 @@
 package jsonpb
 
 import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 type Simple3 struct {
 	Dub float64 `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"`
@@ -74,6 +78,3 @@
 	}
 	return nil
 }
-
-func init() {
-}
diff --git a/jsonpb/jsonpb_test_proto/test_objects.pb.go b/jsonpb/jsonpb_test_proto/test_objects.pb.go
index 1f2f061..8c5b025 100644
--- a/jsonpb/jsonpb_test_proto/test_objects.pb.go
+++ b/jsonpb/jsonpb_test_proto/test_objects.pb.go
@@ -5,10 +5,12 @@
 package jsonpb
 
 import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
 import math "math"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
+var _ = fmt.Errorf
 var _ = math.Inf
 
 type Widget_Color int32
@@ -322,6 +324,100 @@
 	return nil
 }
 
+type MsgWithOneof struct {
+	// Types that are valid to be assigned to Union:
+	//	*MsgWithOneof_Title
+	//	*MsgWithOneof_Salary
+	Union            isMsgWithOneof_Union `protobuf_oneof:"union"`
+	XXX_unrecognized []byte               `json:"-"`
+}
+
+func (m *MsgWithOneof) Reset()         { *m = MsgWithOneof{} }
+func (m *MsgWithOneof) String() string { return proto.CompactTextString(m) }
+func (*MsgWithOneof) ProtoMessage()    {}
+
+type isMsgWithOneof_Union interface {
+	isMsgWithOneof_Union()
+}
+
+type MsgWithOneof_Title struct {
+	Title string `protobuf:"bytes,1,opt,name=title"`
+}
+type MsgWithOneof_Salary struct {
+	Salary int64 `protobuf:"varint,2,opt,name=salary"`
+}
+
+func (*MsgWithOneof_Title) isMsgWithOneof_Union()  {}
+func (*MsgWithOneof_Salary) isMsgWithOneof_Union() {}
+
+func (m *MsgWithOneof) GetUnion() isMsgWithOneof_Union {
+	if m != nil {
+		return m.Union
+	}
+	return nil
+}
+
+func (m *MsgWithOneof) GetTitle() string {
+	if x, ok := m.GetUnion().(*MsgWithOneof_Title); ok {
+		return x.Title
+	}
+	return ""
+}
+
+func (m *MsgWithOneof) GetSalary() int64 {
+	if x, ok := m.GetUnion().(*MsgWithOneof_Salary); ok {
+		return x.Salary
+	}
+	return 0
+}
+
+// XXX_OneofFuncs is for the internal use of the proto package.
+func (*MsgWithOneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) {
+	return _MsgWithOneof_OneofMarshaler, _MsgWithOneof_OneofUnmarshaler, []interface{}{
+		(*MsgWithOneof_Title)(nil),
+		(*MsgWithOneof_Salary)(nil),
+	}
+}
+
+func _MsgWithOneof_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
+	m := msg.(*MsgWithOneof)
+	// union
+	switch x := m.Union.(type) {
+	case *MsgWithOneof_Title:
+		b.EncodeVarint(1<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.Title)
+	case *MsgWithOneof_Salary:
+		b.EncodeVarint(2<<3 | proto.WireVarint)
+		b.EncodeVarint(uint64(x.Salary))
+	case nil:
+	default:
+		return fmt.Errorf("MsgWithOneof.Union has unexpected type %T", x)
+	}
+	return nil
+}
+
+func _MsgWithOneof_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
+	m := msg.(*MsgWithOneof)
+	switch tag {
+	case 1: // union.title
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Union = &MsgWithOneof_Title{x}
+		return true, err
+	case 2: // union.salary
+		if wire != proto.WireVarint {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeVarint()
+		m.Union = &MsgWithOneof_Salary{int64(x)}
+		return true, err
+	default:
+		return false, nil
+	}
+}
+
 func init() {
 	proto.RegisterEnum("jsonpb.Widget_Color", Widget_Color_name, Widget_Color_value)
 }
diff --git a/jsonpb/jsonpb_test_proto/test_objects.proto b/jsonpb/jsonpb_test_proto/test_objects.proto
index e48a3e8..85700bf 100644
--- a/jsonpb/jsonpb_test_proto/test_objects.proto
+++ b/jsonpb/jsonpb_test_proto/test_objects.proto
@@ -84,3 +84,10 @@
   map<int64, string> m_int64_str = 1;
   map<bool, Simple> m_bool_simple = 2;
 }
+
+message MsgWithOneof {
+  oneof union {
+    string title = 1;
+    int64 salary = 2;
+  }
+}