goprotobuf: update to new reflect interface.
Also update the compiler golden file.

R=rsc, dsymonds
CC=golang-dev
http://codereview.appspot.com/4383050
diff --git a/proto/decode.go b/proto/decode.go
index 4eff414..572b508 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -211,7 +211,7 @@
 // Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
 // If the protocol buffer has extensions, and the field matches, add it as an extension.
 // Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
-func (o *Buffer) skipAndSave(t *reflect.StructType, tag, wire int, base uintptr) os.Error {
+func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base uintptr) os.Error {
 
 	oi := o.index
 
@@ -247,7 +247,7 @@
 }
 
 // Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-func (o *Buffer) skip(t *reflect.StructType, tag, wire int) os.Error {
+func (o *Buffer) skip(t reflect.Type, tag, wire int) os.Error {
 
 	var u uint64
 	var err os.Error
@@ -329,8 +329,8 @@
 }
 
 // unmarshalType does the work of unmarshaling a structure.
-func (o *Buffer) unmarshalType(t *reflect.PtrType, is_group bool, base uintptr) os.Error {
-	st := t.Elem().(*reflect.StructType)
+func (o *Buffer) unmarshalType(t reflect.Type, is_group bool, base uintptr) os.Error {
+	st := t.Elem()
 	prop := GetProperties(st)
 	required, reqFields := prop.reqCount, uint64(0)
 	sbase := getsbase(prop) // scratch area for data items
@@ -696,7 +696,7 @@
 // Decode a group.
 func (o *Buffer) dec_struct_group(p *Properties, base uintptr, sbase uintptr) os.Error {
 	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 	structv := unsafe.New(typ)
 	bas := uintptr(structv)
 	*ptr = (*struct{})(structv)
@@ -714,7 +714,7 @@
 	}
 
 	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 	structv := unsafe.New(typ)
 	bas := uintptr(structv)
 	*ptr = (*struct{})(structv)
@@ -757,7 +757,7 @@
 		y = *x
 	}
 
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 	structv := unsafe.New(typ)
 	bas := uintptr(structv)
 	y = append(y, (*struct{})(structv))
diff --git a/proto/encode.go b/proto/encode.go
index d7a5605..62674d1 100644
--- a/proto/encode.go
+++ b/proto/encode.go
@@ -226,7 +226,7 @@
 
 	t, b, err := getbase(pb)
 	if err == nil {
-		err = p.enc_struct(t.Elem().(*reflect.StructType), b)
+		err = p.enc_struct(t.Elem(), b)
 	}
 
 	mstat = runtime.MemStats.Mallocs - mstat
@@ -289,12 +289,21 @@
 	return nil
 }
 
+// All protocol buffer fields are nillable, but be careful.
+func isNil(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return v.IsNil()
+	}
+	return false
+}
+
 // Encode a message struct.
 func (o *Buffer) enc_struct_message(p *Properties, base uintptr) os.Error {
 	// Can the object marshal itself?
 	iv := unsafe.Unreflect(p.stype, unsafe.Pointer(base+p.offset))
 	if m, ok := iv.(Marshaler); ok {
-		if n, ok := reflect.NewValue(iv).(nillable); ok && n.IsNil() {
+		if isNil(reflect.NewValue(iv)) {
 			return ErrNil
 		}
 		data, err := m.Marshal()
@@ -316,7 +325,7 @@
 	o.buf = o.bufalloc()
 
 	b := uintptr(unsafe.Pointer(v))
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 	err := o.enc_struct(typ, b)
 
 	nbuf := o.buf
@@ -340,7 +349,7 @@
 
 	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
 	b := uintptr(unsafe.Pointer(v))
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 	err := o.enc_struct(typ, b)
 	if err != nil {
 		return err
@@ -494,7 +503,7 @@
 func (o *Buffer) enc_slice_struct_message(p *Properties, base uintptr) os.Error {
 	s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
 	l := len(s)
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 
 	for i := 0; i < l; i++ {
 		v := s[i]
@@ -505,7 +514,7 @@
 		// Can the object marshal itself?
 		iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&s[i]))
 		if m, ok := iv.(Marshaler); ok {
-			if n, ok := reflect.NewValue(iv).(nillable); ok && n.IsNil() {
+			if reflect.NewValue(iv).IsNil() {
 				return ErrNil
 			}
 			data, err := m.Marshal()
@@ -544,7 +553,7 @@
 func (o *Buffer) enc_slice_struct_group(p *Properties, base uintptr) os.Error {
 	s := *(*[]*struct{})(unsafe.Pointer(base + p.offset))
 	l := len(s)
-	typ := p.stype.Elem().(*reflect.StructType)
+	typ := p.stype.Elem()
 
 	for i := 0; i < l; i++ {
 		v := s[i]
@@ -579,7 +588,7 @@
 }
 
 // Encode a struct.
-func (o *Buffer) enc_struct(t *reflect.StructType, base uintptr) os.Error {
+func (o *Buffer) enc_struct(t reflect.Type, base uintptr) os.Error {
 	prop := GetProperties(t)
 	required := prop.reqCount
 	for _, p := range prop.Prop {
diff --git a/proto/extensions.go b/proto/extensions.go
index 65eea2c..aec2f2d 100644
--- a/proto/extensions.go
+++ b/proto/extensions.go
@@ -115,13 +115,13 @@
 	_, n := DecodeVarint(b)
 	o := NewBuffer(b[n:])
 
-	t := reflect.Typeof(extension.ExtensionType).(*reflect.PtrType)
+	t := reflect.Typeof(extension.ExtensionType)
 	props := &Properties{}
 	props.Init(t, "irrelevant_name", extension.Tag, 0)
 
 	base := unsafe.New(t)
 	var sbase uintptr
-	if _, ok := t.Elem().(*reflect.StructType); ok {
+	if t.Elem().Kind() == reflect.Struct {
 		// props.dec will be dec_struct_message, which does not refer to sbase.
 		*(*unsafe.Pointer)(base) = unsafe.New(t.Elem())
 	} else {
diff --git a/proto/properties.go b/proto/properties.go
index 4d15b28..b347efc 100644
--- a/proto/properties.go
+++ b/proto/properties.go
@@ -39,7 +39,6 @@
 	"fmt"
 	"os"
 	"reflect"
-	"runtime"
 	"strconv"
 	"strings"
 	"sync"
@@ -105,7 +104,7 @@
 	offset  uintptr
 	tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
 	tagbuf  [8]byte
-	stype   *reflect.PtrType
+	stype   reflect.Type
 
 	dec     decoder
 	valDec  valueDecoder // set for bool and numeric types only
@@ -231,23 +230,23 @@
 	p.enc = nil
 	p.dec = nil
 
-	switch t1 := typ.(type) {
+	switch t1 := typ; t1.Kind() {
 	default:
 		fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1)
 		break
 
-	case *reflect.PtrType:
-		switch t2 := t1.Elem().(type) {
+	case reflect.Ptr:
+		switch t2 := t1.Elem(); t2.Kind() {
 		default:
 		BadType:
 			fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
 			break
-		case *reflect.BoolType:
+		case reflect.Bool:
 			p.enc = (*Buffer).enc_bool
 			p.dec = (*Buffer).dec_bool
 			p.alignof = unsafe.Alignof(vbool)
 			p.sizeof = unsafe.Sizeof(vbool)
-		case *reflect.IntType, *reflect.UintType:
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 			switch t2.Bits() {
 			case 32:
 				p.enc = (*Buffer).enc_int32
@@ -262,7 +261,7 @@
 			default:
 				goto BadType
 			}
-		case *reflect.FloatType:
+		case reflect.Float32, reflect.Float64:
 			switch t2.Bits() {
 			case 32:
 				p.enc = (*Buffer).enc_int32 // can just treat them as bits
@@ -277,12 +276,12 @@
 			default:
 				goto BadType
 			}
-		case *reflect.StringType:
+		case reflect.String:
 			p.enc = (*Buffer).enc_string
 			p.dec = (*Buffer).dec_string
 			p.alignof = unsafe.Alignof(vstring)
 			p.sizeof = unsafe.Sizeof(vstring) + startSize*unsafe.Sizeof(vbyte)
-		case *reflect.StructType:
+		case reflect.Struct:
 			p.stype = t1
 			if p.Wire == "bytes" {
 				p.enc = (*Buffer).enc_struct_message
@@ -293,13 +292,13 @@
 			}
 		}
 
-	case *reflect.SliceType:
-		switch t2 := t1.Elem().(type) {
+	case reflect.Slice:
+		switch t2 := t1.Elem(); t2.Kind() {
 		default:
 		BadSliceType:
 			fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
 			break
-		case *reflect.BoolType:
+		case reflect.Bool:
 			if p.Packed {
 				p.enc = (*Buffer).enc_slice_packed_bool
 			} else {
@@ -309,7 +308,7 @@
 			p.packedDec = (*Buffer).dec_slice_packed_bool
 			p.alignof = unsafe.Alignof(vbool)
 			p.sizeof = startSize * unsafe.Sizeof(vbool)
-		case *reflect.IntType, *reflect.UintType:
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 			switch t2.Bits() {
 			case 32:
 				if p.Packed {
@@ -341,7 +340,7 @@
 			default:
 				goto BadSliceType
 			}
-		case *reflect.FloatType:
+		case reflect.Float32, reflect.Float64:
 			switch t2.Bits() {
 			case 32:
 				// can just treat them as bits
@@ -368,17 +367,17 @@
 			default:
 				goto BadSliceType
 			}
-		case *reflect.StringType:
+		case reflect.String:
 			p.enc = (*Buffer).enc_slice_string
 			p.dec = (*Buffer).dec_slice_string
 			p.alignof = unsafe.Alignof(vstring)
 			p.sizeof = startSize * unsafe.Sizeof(vstring)
-		case *reflect.PtrType:
-			switch t3 := t2.Elem().(type) {
+		case reflect.Ptr:
+			switch t3 := t2.Elem(); t3.Kind() {
 			default:
 				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
 				break
-			case *reflect.StructType:
+			case reflect.Struct:
 				p.stype = t2
 				p.enc = (*Buffer).enc_slice_struct_group
 				p.dec = (*Buffer).dec_slice_struct_group
@@ -389,7 +388,7 @@
 				p.alignof = unsafe.Alignof(vslice)
 				p.sizeof = startSize * unsafe.Sizeof(vslice)
 			}
-		case *reflect.SliceType:
+		case reflect.Slice:
 			switch t2.Elem().Kind() {
 			default:
 				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
@@ -435,11 +434,11 @@
 
 var (
 	mutex         sync.Mutex
-	propertiesMap = make(map[*reflect.StructType]*StructProperties)
+	propertiesMap = make(map[reflect.Type]*StructProperties)
 )
 
 // GetProperties returns the list of properties for the type represented by t.
-func GetProperties(t *reflect.StructType) *StructProperties {
+func GetProperties(t reflect.Type) *StructProperties {
 	mutex.Lock()
 	if prop, ok := propertiesMap[t]; ok {
 		mutex.Unlock()
@@ -514,7 +513,7 @@
 
 // Return the field index of the named field.
 // Returns nil if there is no such field.
-func fieldIndex(t *reflect.StructType, name string) []int {
+func fieldIndex(t reflect.Type, name string) []int {
 	if field, ok := t.FieldByName(name); ok {
 		return field.Index
 	}
@@ -522,7 +521,7 @@
 }
 
 // Return the Properties object for the x[0]'th field of the structure.
-func propByIndex(t *reflect.StructType, x []int) *Properties {
+func propByIndex(t reflect.Type, x []int) *Properties {
 	if len(x) != 1 {
 		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
 		return nil
@@ -533,7 +532,7 @@
 
 // Get the address and type of a pointer to the structure from an interface.
 // unsafe.Reflect can do this, but does multiple mallocs.
-func getbase(pb interface{}) (t *reflect.PtrType, b uintptr, err os.Error) {
+func getbase(pb interface{}) (t reflect.Type, b uintptr, err os.Error) {
 	// get pointer
 	x := *(*[2]uintptr)(unsafe.Pointer(&pb))
 	b = x[1]
@@ -543,8 +542,7 @@
 	}
 
 	// get the reflect type of the struct.
-	t1 := unsafe.Typeof(pb).(*runtime.PtrType)
-	t = (*reflect.PtrType)(unsafe.Pointer(t1))
+	t = reflect.Typeof(pb)
 	return
 }
 
diff --git a/proto/testdata/test.pb.go b/proto/testdata/test.pb.go
index 8025482..6b00d87 100644
--- a/proto/testdata/test.pb.go
+++ b/proto/testdata/test.pb.go
@@ -14,15 +14,18 @@
 
 
 type FOO int32
+
 const (
 	FOO_FOO1 = 1
 )
+
 var FOO_name = map[int32]string{
 	1: "FOO1",
 }
 var FOO_value = map[string]int32{
 	"FOO1": 1,
 }
+
 func NewFOO(x int32) *FOO {
 	e := FOO(x)
 	return &e
@@ -32,51 +35,54 @@
 }
 
 type GoTest_KIND int32
+
 const (
-	GoTest_VOID = 0
-	GoTest_BOOL = 1
-	GoTest_BYTES = 2
-	GoTest_FINGERPRINT = 3
-	GoTest_FLOAT = 4
-	GoTest_INT = 5
-	GoTest_STRING = 6
-	GoTest_TIME = 7
-	GoTest_TUPLE = 8
-	GoTest_ARRAY = 9
-	GoTest_MAP = 10
-	GoTest_TABLE = 11
-	GoTest_FUNCTION = 12
+	GoTest_VOID		= 0
+	GoTest_BOOL		= 1
+	GoTest_BYTES		= 2
+	GoTest_FINGERPRINT	= 3
+	GoTest_FLOAT		= 4
+	GoTest_INT		= 5
+	GoTest_STRING		= 6
+	GoTest_TIME		= 7
+	GoTest_TUPLE		= 8
+	GoTest_ARRAY		= 9
+	GoTest_MAP		= 10
+	GoTest_TABLE		= 11
+	GoTest_FUNCTION		= 12
 )
+
 var GoTest_KIND_name = map[int32]string{
-	0: "VOID",
-	1: "BOOL",
-	2: "BYTES",
-	3: "FINGERPRINT",
-	4: "FLOAT",
-	5: "INT",
-	6: "STRING",
-	7: "TIME",
-	8: "TUPLE",
-	9: "ARRAY",
-	10: "MAP",
-	11: "TABLE",
-	12: "FUNCTION",
+	0:	"VOID",
+	1:	"BOOL",
+	2:	"BYTES",
+	3:	"FINGERPRINT",
+	4:	"FLOAT",
+	5:	"INT",
+	6:	"STRING",
+	7:	"TIME",
+	8:	"TUPLE",
+	9:	"ARRAY",
+	10:	"MAP",
+	11:	"TABLE",
+	12:	"FUNCTION",
 }
 var GoTest_KIND_value = map[string]int32{
-	"VOID": 0,
-	"BOOL": 1,
-	"BYTES": 2,
-	"FINGERPRINT": 3,
-	"FLOAT": 4,
-	"INT": 5,
-	"STRING": 6,
-	"TIME": 7,
-	"TUPLE": 8,
-	"ARRAY": 9,
-	"MAP": 10,
-	"TABLE": 11,
-	"FUNCTION": 12,
+	"VOID":		0,
+	"BOOL":		1,
+	"BYTES":	2,
+	"FINGERPRINT":	3,
+	"FLOAT":	4,
+	"INT":		5,
+	"STRING":	6,
+	"TIME":		7,
+	"TUPLE":	8,
+	"ARRAY":	9,
+	"MAP":		10,
+	"TABLE":	11,
+	"FUNCTION":	12,
 }
+
 func NewGoTest_KIND(x int32) *GoTest_KIND {
 	e := GoTest_KIND(x)
 	return &e
@@ -86,21 +92,24 @@
 }
 
 type MyMessage_Color int32
+
 const (
-	MyMessage_RED = 0
-	MyMessage_GREEN = 1
-	MyMessage_BLUE = 2
+	MyMessage_RED	= 0
+	MyMessage_GREEN	= 1
+	MyMessage_BLUE	= 2
 )
+
 var MyMessage_Color_name = map[int32]string{
-	0: "RED",
-	1: "GREEN",
-	2: "BLUE",
+	0:	"RED",
+	1:	"GREEN",
+	2:	"BLUE",
 }
 var MyMessage_Color_value = map[string]int32{
-	"RED": 0,
-	"GREEN": 1,
-	"BLUE": 2,
+	"RED":		0,
+	"GREEN":	1,
+	"BLUE":		2,
 }
+
 func NewMyMessage_Color(x int32) *MyMessage_Color {
 	e := MyMessage_Color(x)
 	return &e
@@ -110,100 +119,104 @@
 }
 
 type GoEnum struct {
-	Foo	*FOO	"PB(varint,1,req,name=foo,enum=test_proto.FOO)"
+	Foo			*FOO	"PB(varint,1,req,name=foo,enum=test_proto.FOO)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoEnum) Reset() {
 	*this = GoEnum{}
 }
 
 type GoTestField struct {
-	Label	*string	"PB(bytes,1,req)"
-	Type	*string	"PB(bytes,2,req)"
+	Label			*string	"PB(bytes,1,req)"
+	Type			*string	"PB(bytes,2,req)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoTestField) Reset() {
 	*this = GoTestField{}
 }
 
 type GoTest struct {
-	Kind	*int32	"PB(varint,1,req)"
-	Table	*string	"PB(bytes,2,opt)"
-	Param	*int32	"PB(varint,3,opt)"
-	RequiredField	*GoTestField	"PB(bytes,4,req)"
-	RepeatedField	[]*GoTestField	"PB(bytes,5,rep)"
-	OptionalField	*GoTestField	"PB(bytes,6,opt)"
-	F_BoolRequired	*bool	"PB(varint,10,req,name=F_Bool_required)"
-	F_Int32Required	*int32	"PB(varint,11,req,name=F_Int32_required)"
-	F_Int64Required	*int64	"PB(varint,12,req,name=F_Int64_required)"
-	F_Fixed32Required	*uint32	"PB(fixed32,13,req,name=F_Fixed32_required)"
-	F_Fixed64Required	*uint64	"PB(fixed64,14,req,name=F_Fixed64_required)"
-	F_Uint32Required	*uint32	"PB(varint,15,req,name=F_Uint32_required)"
-	F_Uint64Required	*uint64	"PB(varint,16,req,name=F_Uint64_required)"
-	F_FloatRequired	*float32	"PB(fixed32,17,req,name=F_Float_required)"
-	F_DoubleRequired	*float64	"PB(fixed64,18,req,name=F_Double_required)"
-	F_StringRequired	*string	"PB(bytes,19,req,name=F_String_required)"
-	F_BytesRequired	[]byte	"PB(bytes,101,req,name=F_Bytes_required)"
-	F_Sint32Required	*int32	"PB(zigzag32,102,req,name=F_Sint32_required)"
-	F_Sint64Required	*int64	"PB(zigzag64,103,req,name=F_Sint64_required)"
-	F_BoolRepeated	[]bool	"PB(varint,20,rep,name=F_Bool_repeated)"
-	F_Int32Repeated	[]int32	"PB(varint,21,rep,name=F_Int32_repeated)"
-	F_Int64Repeated	[]int64	"PB(varint,22,rep,name=F_Int64_repeated)"
-	F_Fixed32Repeated	[]uint32	"PB(fixed32,23,rep,name=F_Fixed32_repeated)"
-	F_Fixed64Repeated	[]uint64	"PB(fixed64,24,rep,name=F_Fixed64_repeated)"
-	F_Uint32Repeated	[]uint32	"PB(varint,25,rep,name=F_Uint32_repeated)"
-	F_Uint64Repeated	[]uint64	"PB(varint,26,rep,name=F_Uint64_repeated)"
-	F_FloatRepeated	[]float32	"PB(fixed32,27,rep,name=F_Float_repeated)"
-	F_DoubleRepeated	[]float64	"PB(fixed64,28,rep,name=F_Double_repeated)"
-	F_StringRepeated	[]string	"PB(bytes,29,rep,name=F_String_repeated)"
-	F_BytesRepeated	[][]byte	"PB(bytes,201,rep,name=F_Bytes_repeated)"
-	F_Sint32Repeated	[]int32	"PB(zigzag32,202,rep,name=F_Sint32_repeated)"
-	F_Sint64Repeated	[]int64	"PB(zigzag64,203,rep,name=F_Sint64_repeated)"
-	F_BoolOptional	*bool	"PB(varint,30,opt,name=F_Bool_optional)"
-	F_Int32Optional	*int32	"PB(varint,31,opt,name=F_Int32_optional)"
-	F_Int64Optional	*int64	"PB(varint,32,opt,name=F_Int64_optional)"
-	F_Fixed32Optional	*uint32	"PB(fixed32,33,opt,name=F_Fixed32_optional)"
-	F_Fixed64Optional	*uint64	"PB(fixed64,34,opt,name=F_Fixed64_optional)"
-	F_Uint32Optional	*uint32	"PB(varint,35,opt,name=F_Uint32_optional)"
-	F_Uint64Optional	*uint64	"PB(varint,36,opt,name=F_Uint64_optional)"
-	F_FloatOptional	*float32	"PB(fixed32,37,opt,name=F_Float_optional)"
-	F_DoubleOptional	*float64	"PB(fixed64,38,opt,name=F_Double_optional)"
-	F_StringOptional	*string	"PB(bytes,39,opt,name=F_String_optional)"
-	F_BytesOptional	[]byte	"PB(bytes,301,opt,name=F_Bytes_optional)"
-	F_Sint32Optional	*int32	"PB(zigzag32,302,opt,name=F_Sint32_optional)"
-	F_Sint64Optional	*int64	"PB(zigzag64,303,opt,name=F_Sint64_optional)"
-	F_BoolDefaulted	*bool	"PB(varint,40,opt,name=F_Bool_defaulted,def=1)"
-	F_Int32Defaulted	*int32	"PB(varint,41,opt,name=F_Int32_defaulted,def=32)"
-	F_Int64Defaulted	*int64	"PB(varint,42,opt,name=F_Int64_defaulted,def=64)"
-	F_Fixed32Defaulted	*uint32	"PB(fixed32,43,opt,name=F_Fixed32_defaulted,def=320)"
-	F_Fixed64Defaulted	*uint64	"PB(fixed64,44,opt,name=F_Fixed64_defaulted,def=640)"
-	F_Uint32Defaulted	*uint32	"PB(varint,45,opt,name=F_Uint32_defaulted,def=3200)"
-	F_Uint64Defaulted	*uint64	"PB(varint,46,opt,name=F_Uint64_defaulted,def=6400)"
-	F_FloatDefaulted	*float32	"PB(fixed32,47,opt,name=F_Float_defaulted,def=314159)"
-	F_DoubleDefaulted	*float64	"PB(fixed64,48,opt,name=F_Double_defaulted,def=271828)"
-	F_StringDefaulted	*string	"PB(bytes,49,opt,name=F_String_defaulted,def=hello, \\\"world!\\\"\\n)"
-	F_BytesDefaulted	[]byte	"PB(bytes,401,opt,name=F_Bytes_defaulted,def=Bignose)"
-	F_Sint32Defaulted	*int32	"PB(zigzag32,402,opt,name=F_Sint32_defaulted,def=-32)"
-	F_Sint64Defaulted	*int64	"PB(zigzag64,403,opt,name=F_Sint64_defaulted,def=-64)"
-	F_BoolRepeatedPacked	[]bool	"PB(varint,50,rep,packed,name=F_Bool_repeated_packed)"
-	F_Int32RepeatedPacked	[]int32	"PB(varint,51,rep,packed,name=F_Int32_repeated_packed)"
-	F_Int64RepeatedPacked	[]int64	"PB(varint,52,rep,packed,name=F_Int64_repeated_packed)"
-	F_Fixed32RepeatedPacked	[]uint32	"PB(fixed32,53,rep,packed,name=F_Fixed32_repeated_packed)"
-	F_Fixed64RepeatedPacked	[]uint64	"PB(fixed64,54,rep,packed,name=F_Fixed64_repeated_packed)"
-	F_Uint32RepeatedPacked	[]uint32	"PB(varint,55,rep,packed,name=F_Uint32_repeated_packed)"
-	F_Uint64RepeatedPacked	[]uint64	"PB(varint,56,rep,packed,name=F_Uint64_repeated_packed)"
-	F_FloatRepeatedPacked	[]float32	"PB(fixed32,57,rep,packed,name=F_Float_repeated_packed)"
-	F_DoubleRepeatedPacked	[]float64	"PB(fixed64,58,rep,packed,name=F_Double_repeated_packed)"
-	F_Sint32RepeatedPacked	[]int32	"PB(zigzag32,502,rep,packed,name=F_Sint32_repeated_packed)"
-	F_Sint64RepeatedPacked	[]int64	"PB(zigzag64,503,rep,packed,name=F_Sint64_repeated_packed)"
-	Requiredgroup	*GoTest_RequiredGroup	"PB(group,70,req,name=requiredgroup)"
-	Repeatedgroup	[]*GoTest_RepeatedGroup	"PB(group,80,rep,name=repeatedgroup)"
-	Optionalgroup	*GoTest_OptionalGroup	"PB(group,90,opt,name=optionalgroup)"
+	Kind			*int32			"PB(varint,1,req)"
+	Table			*string			"PB(bytes,2,opt)"
+	Param			*int32			"PB(varint,3,opt)"
+	RequiredField		*GoTestField		"PB(bytes,4,req)"
+	RepeatedField		[]*GoTestField		"PB(bytes,5,rep)"
+	OptionalField		*GoTestField		"PB(bytes,6,opt)"
+	F_BoolRequired		*bool			"PB(varint,10,req,name=F_Bool_required)"
+	F_Int32Required		*int32			"PB(varint,11,req,name=F_Int32_required)"
+	F_Int64Required		*int64			"PB(varint,12,req,name=F_Int64_required)"
+	F_Fixed32Required	*uint32			"PB(fixed32,13,req,name=F_Fixed32_required)"
+	F_Fixed64Required	*uint64			"PB(fixed64,14,req,name=F_Fixed64_required)"
+	F_Uint32Required	*uint32			"PB(varint,15,req,name=F_Uint32_required)"
+	F_Uint64Required	*uint64			"PB(varint,16,req,name=F_Uint64_required)"
+	F_FloatRequired		*float32		"PB(fixed32,17,req,name=F_Float_required)"
+	F_DoubleRequired	*float64		"PB(fixed64,18,req,name=F_Double_required)"
+	F_StringRequired	*string			"PB(bytes,19,req,name=F_String_required)"
+	F_BytesRequired		[]byte			"PB(bytes,101,req,name=F_Bytes_required)"
+	F_Sint32Required	*int32			"PB(zigzag32,102,req,name=F_Sint32_required)"
+	F_Sint64Required	*int64			"PB(zigzag64,103,req,name=F_Sint64_required)"
+	F_BoolRepeated		[]bool			"PB(varint,20,rep,name=F_Bool_repeated)"
+	F_Int32Repeated		[]int32			"PB(varint,21,rep,name=F_Int32_repeated)"
+	F_Int64Repeated		[]int64			"PB(varint,22,rep,name=F_Int64_repeated)"
+	F_Fixed32Repeated	[]uint32		"PB(fixed32,23,rep,name=F_Fixed32_repeated)"
+	F_Fixed64Repeated	[]uint64		"PB(fixed64,24,rep,name=F_Fixed64_repeated)"
+	F_Uint32Repeated	[]uint32		"PB(varint,25,rep,name=F_Uint32_repeated)"
+	F_Uint64Repeated	[]uint64		"PB(varint,26,rep,name=F_Uint64_repeated)"
+	F_FloatRepeated		[]float32		"PB(fixed32,27,rep,name=F_Float_repeated)"
+	F_DoubleRepeated	[]float64		"PB(fixed64,28,rep,name=F_Double_repeated)"
+	F_StringRepeated	[]string		"PB(bytes,29,rep,name=F_String_repeated)"
+	F_BytesRepeated		[][]byte		"PB(bytes,201,rep,name=F_Bytes_repeated)"
+	F_Sint32Repeated	[]int32			"PB(zigzag32,202,rep,name=F_Sint32_repeated)"
+	F_Sint64Repeated	[]int64			"PB(zigzag64,203,rep,name=F_Sint64_repeated)"
+	F_BoolOptional		*bool			"PB(varint,30,opt,name=F_Bool_optional)"
+	F_Int32Optional		*int32			"PB(varint,31,opt,name=F_Int32_optional)"
+	F_Int64Optional		*int64			"PB(varint,32,opt,name=F_Int64_optional)"
+	F_Fixed32Optional	*uint32			"PB(fixed32,33,opt,name=F_Fixed32_optional)"
+	F_Fixed64Optional	*uint64			"PB(fixed64,34,opt,name=F_Fixed64_optional)"
+	F_Uint32Optional	*uint32			"PB(varint,35,opt,name=F_Uint32_optional)"
+	F_Uint64Optional	*uint64			"PB(varint,36,opt,name=F_Uint64_optional)"
+	F_FloatOptional		*float32		"PB(fixed32,37,opt,name=F_Float_optional)"
+	F_DoubleOptional	*float64		"PB(fixed64,38,opt,name=F_Double_optional)"
+	F_StringOptional	*string			"PB(bytes,39,opt,name=F_String_optional)"
+	F_BytesOptional		[]byte			"PB(bytes,301,opt,name=F_Bytes_optional)"
+	F_Sint32Optional	*int32			"PB(zigzag32,302,opt,name=F_Sint32_optional)"
+	F_Sint64Optional	*int64			"PB(zigzag64,303,opt,name=F_Sint64_optional)"
+	F_BoolDefaulted		*bool			"PB(varint,40,opt,name=F_Bool_defaulted,def=1)"
+	F_Int32Defaulted	*int32			"PB(varint,41,opt,name=F_Int32_defaulted,def=32)"
+	F_Int64Defaulted	*int64			"PB(varint,42,opt,name=F_Int64_defaulted,def=64)"
+	F_Fixed32Defaulted	*uint32			"PB(fixed32,43,opt,name=F_Fixed32_defaulted,def=320)"
+	F_Fixed64Defaulted	*uint64			"PB(fixed64,44,opt,name=F_Fixed64_defaulted,def=640)"
+	F_Uint32Defaulted	*uint32			"PB(varint,45,opt,name=F_Uint32_defaulted,def=3200)"
+	F_Uint64Defaulted	*uint64			"PB(varint,46,opt,name=F_Uint64_defaulted,def=6400)"
+	F_FloatDefaulted	*float32		"PB(fixed32,47,opt,name=F_Float_defaulted,def=314159)"
+	F_DoubleDefaulted	*float64		"PB(fixed64,48,opt,name=F_Double_defaulted,def=271828)"
+	F_StringDefaulted	*string			"PB(bytes,49,opt,name=F_String_defaulted,def=hello, \\\"world!\\\"\\n)"
+	F_BytesDefaulted	[]byte			"PB(bytes,401,opt,name=F_Bytes_defaulted,def=Bignose)"
+	F_Sint32Defaulted	*int32			"PB(zigzag32,402,opt,name=F_Sint32_defaulted,def=-32)"
+	F_Sint64Defaulted	*int64			"PB(zigzag64,403,opt,name=F_Sint64_defaulted,def=-64)"
+	F_BoolRepeatedPacked	[]bool			"PB(varint,50,rep,packed,name=F_Bool_repeated_packed)"
+	F_Int32RepeatedPacked	[]int32			"PB(varint,51,rep,packed,name=F_Int32_repeated_packed)"
+	F_Int64RepeatedPacked	[]int64			"PB(varint,52,rep,packed,name=F_Int64_repeated_packed)"
+	F_Fixed32RepeatedPacked	[]uint32		"PB(fixed32,53,rep,packed,name=F_Fixed32_repeated_packed)"
+	F_Fixed64RepeatedPacked	[]uint64		"PB(fixed64,54,rep,packed,name=F_Fixed64_repeated_packed)"
+	F_Uint32RepeatedPacked	[]uint32		"PB(varint,55,rep,packed,name=F_Uint32_repeated_packed)"
+	F_Uint64RepeatedPacked	[]uint64		"PB(varint,56,rep,packed,name=F_Uint64_repeated_packed)"
+	F_FloatRepeatedPacked	[]float32		"PB(fixed32,57,rep,packed,name=F_Float_repeated_packed)"
+	F_DoubleRepeatedPacked	[]float64		"PB(fixed64,58,rep,packed,name=F_Double_repeated_packed)"
+	F_Sint32RepeatedPacked	[]int32			"PB(zigzag32,502,rep,packed,name=F_Sint32_repeated_packed)"
+	F_Sint64RepeatedPacked	[]int64			"PB(zigzag64,503,rep,packed,name=F_Sint64_repeated_packed)"
+	Requiredgroup		*GoTest_RequiredGroup	"PB(group,70,req,name=requiredgroup)"
+	Repeatedgroup		[]*GoTest_RepeatedGroup	"PB(group,80,rep,name=repeatedgroup)"
+	Optionalgroup		*GoTest_OptionalGroup	"PB(group,90,opt,name=optionalgroup)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoTest) Reset() {
 	*this = GoTest{}
 }
+
 const Default_GoTest_F_BoolDefaulted bool = true
 const Default_GoTest_F_Int32Defaulted int32 = 32
 const Default_GoTest_F_Int64Defaulted int64 = 64
@@ -214,120 +227,135 @@
 const Default_GoTest_F_FloatDefaulted float32 = 314159
 const Default_GoTest_F_DoubleDefaulted float64 = 271828
 const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n"
+
 var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose")
+
 const Default_GoTest_F_Sint32Defaulted int32 = -32
 const Default_GoTest_F_Sint64Defaulted int64 = -64
 
 type GoTest_RequiredGroup struct {
-	RequiredField	*string	"PB(bytes,71,req)"
+	RequiredField		*string	"PB(bytes,71,req)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoTest_RequiredGroup) Reset() {
 	*this = GoTest_RequiredGroup{}
 }
 
 type GoTest_RepeatedGroup struct {
-	RequiredField	*string	"PB(bytes,81,req)"
+	RequiredField		*string	"PB(bytes,81,req)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoTest_RepeatedGroup) Reset() {
 	*this = GoTest_RepeatedGroup{}
 }
 
 type GoTest_OptionalGroup struct {
-	RequiredField	*string	"PB(bytes,91,req)"
+	RequiredField		*string	"PB(bytes,91,req)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoTest_OptionalGroup) Reset() {
 	*this = GoTest_OptionalGroup{}
 }
 
 type GoSkipTest struct {
-	SkipInt32	*int32	"PB(varint,11,req,name=skip_int32)"
-	SkipFixed32	*uint32	"PB(fixed32,12,req,name=skip_fixed32)"
-	SkipFixed64	*uint64	"PB(fixed64,13,req,name=skip_fixed64)"
-	SkipString	*string	"PB(bytes,14,req,name=skip_string)"
-	Skipgroup	*GoSkipTest_SkipGroup	"PB(group,15,req,name=skipgroup)"
+	SkipInt32		*int32			"PB(varint,11,req,name=skip_int32)"
+	SkipFixed32		*uint32			"PB(fixed32,12,req,name=skip_fixed32)"
+	SkipFixed64		*uint64			"PB(fixed64,13,req,name=skip_fixed64)"
+	SkipString		*string			"PB(bytes,14,req,name=skip_string)"
+	Skipgroup		*GoSkipTest_SkipGroup	"PB(group,15,req,name=skipgroup)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoSkipTest) Reset() {
 	*this = GoSkipTest{}
 }
 
 type GoSkipTest_SkipGroup struct {
-	GroupInt32	*int32	"PB(varint,16,req,name=group_int32)"
-	GroupString	*string	"PB(bytes,17,req,name=group_string)"
+	GroupInt32		*int32	"PB(varint,16,req,name=group_int32)"
+	GroupString		*string	"PB(bytes,17,req,name=group_string)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *GoSkipTest_SkipGroup) Reset() {
 	*this = GoSkipTest_SkipGroup{}
 }
 
 type NonPackedTest struct {
-	A	[]int32	"PB(varint,1,rep,name=a)"
+	A			[]int32	"PB(varint,1,rep,name=a)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *NonPackedTest) Reset() {
 	*this = NonPackedTest{}
 }
 
 type PackedTest struct {
-	B	[]int32	"PB(varint,1,rep,packed,name=b)"
+	B			[]int32	"PB(varint,1,rep,packed,name=b)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *PackedTest) Reset() {
 	*this = PackedTest{}
 }
 
 type InnerMessage struct {
-	Host	*string	"PB(bytes,1,req,name=host)"
-	Port	*int32	"PB(varint,2,opt,name=port,def=4000)"
-	Connected	*bool	"PB(varint,3,opt,name=connected)"
+	Host			*string	"PB(bytes,1,req,name=host)"
+	Port			*int32	"PB(varint,2,opt,name=port,def=4000)"
+	Connected		*bool	"PB(varint,3,opt,name=connected)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *InnerMessage) Reset() {
 	*this = InnerMessage{}
 }
+
 const Default_InnerMessage_Port int32 = 4000
 
 type OtherMessage struct {
-	Key	*int64	"PB(varint,1,opt,name=key)"
-	Value	[]byte	"PB(bytes,2,opt,name=value)"
-	Weight	*float32	"PB(fixed32,3,opt,name=weight)"
-	Inner	*InnerMessage	"PB(bytes,4,opt,name=inner)"
+	Key			*int64		"PB(varint,1,opt,name=key)"
+	Value			[]byte		"PB(bytes,2,opt,name=value)"
+	Weight			*float32	"PB(fixed32,3,opt,name=weight)"
+	Inner			*InnerMessage	"PB(bytes,4,opt,name=inner)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *OtherMessage) Reset() {
 	*this = OtherMessage{}
 }
 
 type MyMessage struct {
-	Count	*int32	"PB(varint,1,req,name=count)"
-	Name	*string	"PB(bytes,2,opt,name=name)"
-	Quote	*string	"PB(bytes,3,opt,name=quote)"
-	Pet	[]string	"PB(bytes,4,rep,name=pet)"
-	Inner	*InnerMessage	"PB(bytes,5,opt,name=inner)"
-	Others	[]*OtherMessage	"PB(bytes,6,rep,name=others)"
-	Bikeshed	*MyMessage_Color	"PB(varint,7,opt,name=bikeshed,enum=test_proto.MyMessage_Color)"
+	Count			*int32			"PB(varint,1,req,name=count)"
+	Name			*string			"PB(bytes,2,opt,name=name)"
+	Quote			*string			"PB(bytes,3,opt,name=quote)"
+	Pet			[]string		"PB(bytes,4,rep,name=pet)"
+	Inner			*InnerMessage		"PB(bytes,5,opt,name=inner)"
+	Others			[]*OtherMessage		"PB(bytes,6,rep,name=others)"
+	Bikeshed		*MyMessage_Color	"PB(varint,7,opt,name=bikeshed,enum=test_proto.MyMessage_Color)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *MyMessage) Reset() {
 	*this = MyMessage{}
 }
 
 type MessageList struct {
-	Message	[]*MessageList_Message	"PB(group,1,rep,name=message)"
+	Message			[]*MessageList_Message	"PB(group,1,rep,name=message)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *MessageList) Reset() {
 	*this = MessageList{}
 }
 
 type MessageList_Message struct {
-	Name	*string	"PB(bytes,2,req,name=name)"
-	Count	*int32	"PB(varint,3,req,name=count)"
+	Name			*string	"PB(bytes,2,req,name=name)"
+	Count			*int32	"PB(varint,3,req,name=count)"
 	XXX_unrecognized	[]byte
 }
+
 func (this *MessageList_Message) Reset() {
 	*this = MessageList_Message{}
 }
diff --git a/proto/text.go b/proto/text.go
index 371b020..fac3c2d 100644
--- a/proto/text.go
+++ b/proto/text.go
@@ -90,8 +90,8 @@
 	}
 }
 
-func writeStruct(w *textWriter, sv *reflect.StructValue) {
-	st := sv.Type().(*reflect.StructType)
+func writeStruct(w *textWriter, sv reflect.Value) {
+	st := sv.Type()
 	sprops := GetProperties(st)
 	for i := 0; i < sv.NumField(); i++ {
 		if strings.HasPrefix(st.Field(i).Name, "XXX_") {
@@ -99,26 +99,26 @@
 		}
 		props := sprops.Prop[i]
 		fv := sv.Field(i)
-		if pv, ok := fv.(*reflect.PtrValue); ok && pv.IsNil() {
+		if pv := fv; pv.Kind() == reflect.Ptr && pv.IsNil() {
 			// Field not filled in. This could be an optional field or
 			// a required field that wasn't filled in. Either way, there
 			// isn't anything we can show for it.
 			continue
 		}
-		if av, ok := fv.(*reflect.SliceValue); ok && av.IsNil() {
+		if av := fv; av.Kind() == reflect.Slice && av.IsNil() {
 			// Repeated field that is empty, or a bytes field that is unused.
 			continue
 		}
 
 		if props.Repeated {
-			if av, ok := fv.(*reflect.SliceValue); ok {
+			if av := fv; av.Kind() == reflect.Slice {
 				// Repeated field.
 				for j := 0; j < av.Len(); j++ {
 					fmt.Fprintf(w, "%v:", props.OrigName)
 					if !w.compact {
 						w.Write([]byte{' '})
 					}
-					writeAny(w, av.Elem(j))
+					writeAny(w, av.Index(j))
 					fmt.Fprint(w, "\n")
 				}
 				continue
@@ -145,7 +145,7 @@
 	if !ok {
 		return false
 	}
-	str, ok := m[int32(v.(*reflect.IntValue).Get())]
+	str, ok := m[int32(v.Int())]
 	if !ok {
 		return false
 	}
@@ -158,20 +158,20 @@
 
 	// We don't attempt to serialise every possible value type; only those
 	// that can occur in protocol buffers, plus a few extra that were easy.
-	switch val := v.(type) {
-	case *reflect.SliceValue:
+	switch val := v; val.Kind() {
+	case reflect.Slice:
 		// Should only be a []byte; repeated fields are handled in writeStruct.
 		// TODO: Handle other cases more cleanly.
 		bytes := make([]byte, val.Len())
 		for i := 0; i < val.Len(); i++ {
-			bytes[i] = byte(val.Elem(i).(*reflect.UintValue).Get())
+			bytes[i] = byte(val.Index(i).Uint())
 		}
 		// TODO: Should be strconv.QuoteC, which doesn't exist yet
 		fmt.Fprint(w, strconv.Quote(string(bytes)))
-	case *reflect.StringValue:
+	case reflect.String:
 		// TODO: Should be strconv.QuoteC, which doesn't exist yet
-		fmt.Fprint(w, strconv.Quote(val.Get()))
-	case *reflect.StructValue:
+		fmt.Fprint(w, strconv.Quote(val.String()))
+	case reflect.Struct:
 		// Required/optional group/message.
 		// TODO: groups use { } instead of < >, and no colon.
 		if !w.compact {
@@ -202,7 +202,7 @@
 	// We should normally be passed a struct, or a pointer to a struct,
 	// and we don't want the outer < and > in that case.
 	v = reflect.Indirect(v)
-	if sv, ok := v.(*reflect.StructValue); ok {
+	if sv := v; sv.Kind() == reflect.Struct {
 		writeStruct(aw, sv)
 	} else {
 		writeAny(aw, v)
diff --git a/proto/text_parser.go b/proto/text_parser.go
index cd32bf4..adddb72 100644
--- a/proto/text_parser.go
+++ b/proto/text_parser.go
@@ -228,18 +228,12 @@
 	return &p.cur
 }
 
-type nillable interface {
-	IsNil() bool
-}
-
 // Return an error indicating which required field was not set.
-func (p *textParser) missingRequiredFieldError(sv *reflect.StructValue) *ParseError {
-	st := sv.Type().(*reflect.StructType)
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError {
+	st := sv.Type()
 	sprops := GetProperties(st)
 	for i := 0; i < st.NumField(); i++ {
-		// All protocol buffer fields are nillable, but let's be careful.
-		nfv, ok := sv.Field(i).(nillable)
-		if !ok || !nfv.IsNil() {
+		if !isNil(sv.Field(i)) {
 			continue
 		}
 
@@ -252,7 +246,7 @@
 }
 
 // Returns the index in the struct for the named field, as well as the parsed tag properties.
-func structFieldByName(st *reflect.StructType, name string) (int, *Properties, bool) {
+func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) {
 	sprops := GetProperties(st)
 	i, ok := sprops.origNames[name]
 	if ok {
@@ -261,8 +255,8 @@
 	return -1, nil, false
 }
 
-func (p *textParser) readStruct(sv *reflect.StructValue, terminator string) *ParseError {
-	st := sv.Type().(*reflect.StructType)
+func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError {
+	st := sv.Type()
 	reqCount := GetProperties(st).reqCount
 	// A struct is a sequence of "name: value", terminated by one of
 	// '>' or '}', or the end of the input.
@@ -281,10 +275,8 @@
 		}
 
 		// Check that it's not already set if it's not a repeated field.
-		if !props.Repeated {
-			if nfv, ok := sv.Field(fi).(nillable); ok && !nfv.IsNil() {
-				return p.error("non-repeated field %q was repeated", tok.value)
-			}
+		if !props.Repeated && !isNil(sv.Field(fi)) {
+			return p.error("non-repeated field %q was repeated", tok.value)
 		}
 
 		tok = p.next()
@@ -302,14 +294,14 @@
 				// those three become *T, *string and []T respectively, so we can check for
 				// this field being a pointer to a non-string.
 				typ := st.Field(fi).Type
-				if pt, ok := typ.(*reflect.PtrType); ok {
+				if pt := typ; pt.Kind() == reflect.Ptr {
 					// *T or *string
-					if _, ok := pt.Elem().(*reflect.StringType); ok {
+					if pt.Elem().Kind() == reflect.String {
 						break
 					}
-				} else if st, ok := typ.(*reflect.SliceType); ok {
+				} else if st := typ; st.Kind() == reflect.Slice {
 					// []T or []*T
-					if _, ok := st.Elem().(*reflect.PtrType); !ok {
+					if st.Elem().Kind() != reflect.Ptr {
 						break
 					}
 				}
@@ -352,9 +344,9 @@
 		return p.error("unexpected EOF")
 	}
 
-	switch fv := v.(type) {
-	case *reflect.SliceValue:
-		at := v.Type().(*reflect.SliceType)
+	switch fv := v; fv.Kind() {
+	case reflect.Slice:
+		at := v.Type()
 		if at.Elem().Kind() == reflect.Uint8 {
 			// Special case for []byte
 			if tok.value[0] != '"' {
@@ -364,7 +356,7 @@
 				return p.error("invalid string: %v", tok.value)
 			}
 			bytes := []byte(tok.unquoted)
-			fv.Set(reflect.NewValue(bytes).(*reflect.SliceValue))
+			fv.Set(reflect.NewValue(bytes))
 			return nil
 		}
 		// Repeated field. May already exist.
@@ -378,27 +370,27 @@
 
 		// Read one.
 		p.back()
-		return p.readAny(fv.Elem(flen), nil) // TODO: pass properties?
-	case *reflect.BoolValue:
+		return p.readAny(fv.Index(flen), nil) // TODO: pass properties?
+	case reflect.Bool:
 		// Either "true", "false", 1 or 0.
 		switch tok.value {
 		case "true", "1":
-			fv.Set(true)
+			fv.SetBool(true)
 			return nil
 		case "false", "0":
-			fv.Set(false)
+			fv.SetBool(false)
 			return nil
 		}
-	case *reflect.FloatValue:
+	case reflect.Float32, reflect.Float64:
 		if f, err := strconv.AtofN(tok.value, fv.Type().Bits()); err == nil {
-			fv.Set(f)
+			fv.SetFloat(f)
 			return nil
 		}
-	case *reflect.IntValue:
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		switch fv.Type().Bits() {
 		case 32:
 			if x, err := strconv.Atoi64(tok.value); err == nil && minInt32 <= x && x <= maxInt32 {
-				fv.Set(x)
+				fv.SetInt(x)
 				return nil
 			}
 			if len(props.Enum) == 0 {
@@ -412,25 +404,25 @@
 			if !ok {
 				break
 			}
-			fv.Set(int64(x))
+			fv.SetInt(int64(x))
 			return nil
 		case 64:
 			if x, err := strconv.Atoi64(tok.value); err == nil {
-				fv.Set(x)
+				fv.SetInt(x)
 				return nil
 			}
 		}
-	case *reflect.PtrValue:
+	case reflect.Ptr:
 		// A basic field (indirected through pointer), or a repeated message/group
 		p.back()
-		fv.PointTo(reflect.MakeZero(fv.Type().(*reflect.PtrType).Elem()))
+		fv.Set(reflect.Zero(fv.Type().Elem()).Addr())
 		return p.readAny(fv.Elem(), props)
-	case *reflect.StringValue:
+	case reflect.String:
 		if tok.value[0] == '"' {
-			fv.Set(tok.unquoted)
+			fv.SetString(tok.unquoted)
 			return nil
 		}
-	case *reflect.StructValue:
+	case reflect.Struct:
 		var terminator string
 		switch tok.value {
 		case "{":
@@ -441,16 +433,16 @@
 			return p.error("expected '{' or '<', found %q", tok.value)
 		}
 		return p.readStruct(fv, terminator)
-	case *reflect.UintValue:
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
 		switch fv.Type().Bits() {
 		case 32:
 			if x, err := strconv.Atoui64(tok.value); err == nil && x <= maxUint32 {
-				fv.Set(uint64(x))
+				fv.SetUint(uint64(x))
 				return nil
 			}
 		case 64:
 			if x, err := strconv.Atoui64(tok.value); err == nil {
-				fv.Set(x)
+				fv.SetUint(x)
 				return nil
 			}
 		}
@@ -462,12 +454,13 @@
 
 // UnmarshalText reads a protobuffer in Text format.
 func UnmarshalText(s string, pb interface{}) os.Error {
-	pv, ok := reflect.NewValue(pb).(*reflect.PtrValue)
+	pv := reflect.NewValue(pb)
+	ok := pv.Kind() == reflect.Ptr
 	if !ok {
 		return notPtrStruct
 	}
-	sv, ok := pv.Elem().(*reflect.StructValue)
-	if !ok {
+	sv := pv.Elem()
+	if sv.Kind() != reflect.Struct {
 		return notPtrStruct
 	}
 	if pe := newTextParser(s).readStruct(sv, ""); pe != nil {