goprotobuf: Split encoding of repeated int32 and repeated uint32 fields.

This is a follow-on from a previous change where we split the singular int32/uint32.
It was an oversight not to fix the repeated versions at the same time.

Also simplify setEncAndDec for repeated fields while I'm here.
We were doing a lot of unnecessary work: unnecessarily doing two layers of
switches, plus trying to handle a bunch of field types we never generate.

Fixes #52.

LGTM=djd
R=djd
CC=golang-codereviews
https://codereview.appspot.com/123240043
diff --git a/proto/encode.go b/proto/encode.go
index b160372..35e5ad5 100644
--- a/proto/encode.go
+++ b/proto/encode.go
@@ -570,7 +570,7 @@
 	}
 	for i := 0; i < l; i++ {
 		o.buf = append(o.buf, p.tagcode...)
-		x := s.Index(i)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
 		p.valEnc(o, uint64(x))
 	}
 	return nil
@@ -584,7 +584,7 @@
 	}
 	for i := 0; i < l; i++ {
 		n += len(p.tagcode)
-		x := s.Index(i)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
 		n += p.valSize(uint64(x))
 	}
 	return
@@ -600,6 +600,75 @@
 	// TODO: Reuse a Buffer.
 	buf := NewBuffer(nil)
 	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := s.Index(i)
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := s.Index(i)
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
 		p.valEnc(buf, uint64(s.Index(i)))
 	}
 
@@ -609,7 +678,7 @@
 	return nil
 }
 
-func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
 	s := structPointer_Word32Slice(base, p.field)
 	l := s.Len()
 	if l == 0 {
diff --git a/proto/properties.go b/proto/properties.go
index 8513ae7..f2c1e86 100644
--- a/proto/properties.go
+++ b/proto/properties.go
@@ -365,48 +365,50 @@
 			}
 			p.dec = (*Buffer).dec_slice_bool
 			p.packedDec = (*Buffer).dec_slice_packed_bool
-		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 {
-					p.enc = (*Buffer).enc_slice_packed_int32
-					p.size = size_slice_packed_int32
-				} else {
-					p.enc = (*Buffer).enc_slice_int32
-					p.size = size_slice_int32
-				}
-				p.dec = (*Buffer).dec_slice_int32
-				p.packedDec = (*Buffer).dec_slice_packed_int32
-			case 64:
-				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_int64
-					p.size = size_slice_packed_int64
-				} else {
-					p.enc = (*Buffer).enc_slice_int64
-					p.size = size_slice_int64
-				}
-				p.dec = (*Buffer).dec_slice_int64
-				p.packedDec = (*Buffer).dec_slice_packed_int64
-			case 8:
-				if t2.Kind() == reflect.Uint8 {
-					p.enc = (*Buffer).enc_slice_byte
-					p.dec = (*Buffer).dec_slice_byte
-					p.size = size_slice_byte
-				}
-			default:
-				logNoSliceEnc(t1, t2)
-				break
+		case reflect.Int32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int32
+				p.size = size_slice_packed_int32
+			} else {
+				p.enc = (*Buffer).enc_slice_int32
+				p.size = size_slice_int32
 			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Uint32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_uint32
+				p.size = size_slice_packed_uint32
+			} else {
+				p.enc = (*Buffer).enc_slice_uint32
+				p.size = size_slice_uint32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Int64, reflect.Uint64:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int64
+				p.size = size_slice_packed_int64
+			} else {
+				p.enc = (*Buffer).enc_slice_int64
+				p.size = size_slice_int64
+			}
+			p.dec = (*Buffer).dec_slice_int64
+			p.packedDec = (*Buffer).dec_slice_packed_int64
+		case reflect.Uint8:
+			p.enc = (*Buffer).enc_slice_byte
+			p.dec = (*Buffer).dec_slice_byte
+			p.size = size_slice_byte
 		case reflect.Float32, reflect.Float64:
 			switch t2.Bits() {
 			case 32:
 				// can just treat them as bits
 				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_int32
-					p.size = size_slice_packed_int32
+					p.enc = (*Buffer).enc_slice_packed_uint32
+					p.size = size_slice_packed_uint32
 				} else {
-					p.enc = (*Buffer).enc_slice_int32
-					p.size = size_slice_int32
+					p.enc = (*Buffer).enc_slice_uint32
+					p.size = size_slice_uint32
 				}
 				p.dec = (*Buffer).dec_slice_int32
 				p.packedDec = (*Buffer).dec_slice_packed_int32
diff --git a/proto/size_test.go b/proto/size_test.go
index 5aab80b..6cb9de6 100644
--- a/proto/size_test.go
+++ b/proto/size_test.go
@@ -85,7 +85,7 @@
 	{"empty repeated bool", &pb.MoreRepeated{Bools: []bool{}}},
 	{"repeated bool", &pb.MoreRepeated{Bools: []bool{false, true, true, false}}},
 	{"packed repeated bool", &pb.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}},
-	{"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729}}},
+	{"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729, -1}}},
 	{"repeated int32 packed", &pb.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}},
 	{"repeated int64 packed", &pb.MoreRepeated{Int64SPacked: []int64{
 		// Need enough large numbers to verify that the header is counting the number of bytes