all: fix tests for 32-bit architectures

Fix the tests to work on GOARCH=386.
Also add another test suite that tests on GOARCH=386.

Change-Id: I41290998053dc059347adb8af70012dc5cc31811
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/241537
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/integration_test.go b/integration_test.go
index 54ad30f..d24d70f 100644
--- a/integration_test.go
+++ b/integration_test.go
@@ -101,7 +101,7 @@
 	for i := range golangVersions {
 		goVersion := golangVersions[i]
 		goLabel := "Go" + goVersion
-		runGo := func(label, workDir string, args ...string) {
+		runGo := func(label string, cmd command, args ...string) {
 			wg.Add(1)
 			sema <- true
 			go func() {
@@ -109,19 +109,25 @@
 				defer func() { <-sema }()
 				t.Run(goLabel+"/"+label, func(t *testing.T) {
 					args[0] += goVersion
-					command{Dir: workDir}.mustRun(t, args...)
+					cmd.mustRun(t, args...)
 				})
 			}()
 		}
 
 		workDir := filepath.Join(goPath, "src", modulePath)
-		runGo("Normal", workDir, "go", "test", "-race", "./...")
-		runGo("PureGo", workDir, "go", "test", "-race", "-tags", "purego", "./...")
-		runGo("Reflect", workDir, "go", "test", "-race", "-tags", "protoreflect", "./...")
+		runGo("Normal", command{Dir: workDir}, "go", "test", "-race", "./...")
+		runGo("PureGo", command{Dir: workDir}, "go", "test", "-race", "-tags", "purego", "./...")
+		runGo("Reflect", command{Dir: workDir}, "go", "test", "-race", "-tags", "protoreflect", "./...")
 		if goVersion == golangLatest {
-			runGo("ProtoLegacy", workDir, "go", "test", "-race", "-tags", "protolegacy", "./...")
-			runGo("ProtocGenGo", "cmd/protoc-gen-go/testdata", "go", "test")
-			runGo("Conformance", "internal/conformance", "go", "test", "-execute")
+			runGo("ProtoLegacy", command{Dir: workDir}, "go", "test", "-race", "-tags", "protolegacy", "./...")
+			runGo("ProtocGenGo", command{Dir: "cmd/protoc-gen-go/testdata"}, "go", "test")
+			runGo("Conformance", command{Dir: "internal/conformance"}, "go", "test", "-execute")
+
+			// Only run the 32-bit compatability tests for Linux;
+			// avoid Darwin since 10.15 dropped support i386 code execution.
+			if runtime.GOOS == "linux" {
+				runGo("Arch32Bit", command{Dir: workDir, Env: append(os.Environ(), "GOARCH=386")}, "go", "test", "./...")
+			}
 		}
 	}
 	wg.Wait()
diff --git a/internal/encoding/text/decode_test.go b/internal/encoding/text/decode_test.go
index 3f8047f..9e38cb3 100644
--- a/internal/encoding/text/decode_test.go
+++ b/internal/encoding/text/decode_test.go
@@ -1021,10 +1021,10 @@
 			in: `nums: [` +
 				fmt.Sprintf("%d", uint64(math.MaxUint64)) + `,` +
 				fmt.Sprintf("%d", uint32(math.MaxUint32)) + `,` +
-				fmt.Sprintf("%d", math.MaxInt64) + `,` +
-				fmt.Sprintf("%d", math.MinInt64) + `,` +
-				fmt.Sprintf("%d", math.MaxInt32) + `,` +
-				fmt.Sprintf("%d", math.MinInt32) +
+				fmt.Sprintf("%d", int64(math.MaxInt64)) + `,` +
+				fmt.Sprintf("%d", int64(math.MinInt64)) + `,` +
+				fmt.Sprintf("%d", int32(math.MaxInt32)) + `,` +
+				fmt.Sprintf("%d", int32(math.MinInt32)) +
 				`]`,
 			want: []R{
 				{K: text.Name},
diff --git a/internal/protobuild/build.go b/internal/protobuild/build.go
index cb2f4a5..46ab5c5 100644
--- a/internal/protobuild/build.go
+++ b/internal/protobuild/build.go
@@ -106,20 +106,20 @@
 	case int:
 		switch fd.Kind() {
 		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
-			if min, max := math.MinInt32, math.MaxInt32; o < min || o > max {
-				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, min, max))
+			if o < math.MinInt32 || math.MaxInt32 < o {
+				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, int32(math.MinInt32), int32(math.MaxInt32)))
 			}
 			v = int32(o)
 		case pref.Uint32Kind, pref.Fixed32Kind:
-			if min, max := 0, math.MaxUint32; o < min || o > max {
-				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, min, max))
+			if o < 0 || math.MaxUint32 < 0 {
+				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, uint32(0), uint32(math.MaxUint32)))
 			}
 			v = uint32(o)
 		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
 			v = int64(o)
 		case pref.Uint64Kind, pref.Fixed64Kind:
 			if o < 0 {
-				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, 0, uint64(math.MaxUint64)))
+				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, uint64(0), uint64(math.MaxUint64)))
 			}
 			v = uint64(o)
 		case pref.FloatKind:
diff --git a/proto/encode_test.go b/proto/encode_test.go
index 852aa57..3915c9d 100644
--- a/proto/encode_test.go
+++ b/proto/encode_test.go
@@ -227,7 +227,7 @@
 func TestEncodeLarge(t *testing.T) {
 	// Encode/decode a message large enough to overflow a 32-bit size cache.
 	t.Skip("too slow and memory-hungry to run all the time")
-	size := math.MaxUint32 + 1
+	size := int64(math.MaxUint32 + 1)
 	m := &testpb.TestAllTypes_NestedMessage{
 		Corecursive: &testpb.TestAllTypes{
 			OptionalBytes: make([]byte, size),
@@ -243,7 +243,7 @@
 	if err := proto.Unmarshal(b, m); err != nil {
 		t.Fatalf("Unmarshal: %v", err)
 	}
-	if got, want := len(m.Corecursive.OptionalBytes), size; got != want {
+	if got, want := int64(len(m.Corecursive.OptionalBytes)), size; got != want {
 		t.Errorf("after round-trip marshal, got len(m.OptionalBytes) = %v, want %v", got, want)
 	}
 }