goprotobuf: Optimize tag lookups and stype handling.

R=r, adg
CC=golang-dev
http://codereview.appspot.com/6453158
diff --git a/proto/decode.go b/proto/decode.go
index 1929747..6c7f53a 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -333,7 +333,7 @@
 		return err
 	}
 
-	err = p.unmarshalType(typ, GetProperties(typ.Elem()), false, base)
+	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
 
 	if collectStats {
 		stats.Decode++
@@ -343,8 +343,7 @@
 }
 
 // unmarshalType does the work of unmarshaling a structure.
-func (o *Buffer) unmarshalType(t reflect.Type, prop *StructProperties, is_group bool, base uintptr) error {
-	st := t.Elem()
+func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base uintptr) error {
 	required, reqFields := prop.reqCount, uint64(0)
 
 	var err error
@@ -366,7 +365,7 @@
 		if tag <= 0 {
 			return fmt.Errorf("proto: illegal tag %d", tag)
 		}
-		fieldnum, ok := prop.tags[tag]
+		fieldnum, ok := prop.tags.get(tag)
 		if !ok {
 			// Maybe it's an extension?
 			iv := reflect.NewAt(st, unsafe.Pointer(base)).Interface()
@@ -384,7 +383,7 @@
 		p := prop.Prop[fieldnum]
 
 		if p.dec == nil {
-			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", t, st.Field(fieldnum).Name)
+			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
 			continue
 		}
 		dec := p.dec
@@ -650,8 +649,7 @@
 // Decode a group.
 func (o *Buffer) dec_struct_group(p *Properties, base uintptr) error {
 	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
-	typ := p.stype.Elem()
-	bas := reflect.New(typ).Pointer()
+	bas := reflect.New(p.stype).Pointer()
 	structv := unsafe.Pointer(bas)
 	*ptr = (*struct{})(structv)
 
@@ -668,14 +666,13 @@
 	}
 
 	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
-	typ := p.stype.Elem()
-	bas := reflect.New(typ).Pointer()
+	bas := reflect.New(p.stype).Pointer()
 	structp := unsafe.Pointer(bas)
 	*ptr = (*struct{})(structp)
 
 	// If the object can unmarshal itself, let it.
 	if p.isMarshaler {
-		iv := reflect.NewAt(p.stype.Elem(), structp).Interface()
+		iv := reflect.NewAt(p.stype, structp).Interface()
 		return iv.(Unmarshaler).Unmarshal(raw)
 	}
 
@@ -707,8 +704,7 @@
 	v := (*[]*struct{})(unsafe.Pointer(base + p.offset))
 	y := *v
 
-	typ := p.stype.Elem()
-	bas := reflect.New(typ).Pointer()
+	bas := reflect.New(p.stype).Pointer()
 	structp := unsafe.Pointer(bas)
 	y = append(y, (*struct{})(structp))
 	*v = y
@@ -725,7 +721,7 @@
 
 	// If the object can unmarshal itself, let it.
 	if p.isUnmarshaler {
-		iv := reflect.NewAt(typ, structp).Interface()
+		iv := reflect.NewAt(p.stype, structp).Interface()
 		return iv.(Unmarshaler).Unmarshal(raw)
 	}