internal/impl: precompute required bit in validator

Required field validation populates a bitmask of observed required
fields. Store a uint64 containing the bit to set in the validationInfo
rather than the index of the bit. Provides a noticeable speed increase
in validation.

name                             old time/op  new time/op  delta
EmptyMessage/Wire/Unmarshal      40.2ns ± 1%  40.2ns ± 2%    ~     (p=0.860 n=35+37)
EmptyMessage/Wire/Unmarshal-12   7.13ns ± 5%  7.12ns ± 1%    ~     (p=0.112 n=37+37)
RepeatedInt32/Wire/Unmarshal     6.57µs ± 1%  6.46µs ± 1%  -1.56%  (p=0.000 n=39+35)
RepeatedInt32/Wire/Unmarshal-12  1.05µs ± 2%  1.05µs ± 2%    ~     (p=0.659 n=37+33)
Required/Wire/Unmarshal           258ns ± 1%   251ns ± 1%  -2.87%  (p=0.000 n=32+38)
Required/Wire/Unmarshal-12       44.3ns ± 2%  42.4ns ± 1%  -4.36%  (p=0.000 n=36+37)

Change-Id: Ib1cb74d3e348355a6a2f66aecf8fdc4b58cd84d4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216420
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/decode.go b/internal/impl/decode.go
index 4a1d631..4b1bc6d 100644
--- a/internal/impl/decode.go
+++ b/internal/impl/decode.go
@@ -143,9 +143,10 @@
 			var o unmarshalOutput
 			o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, opts)
 			n = o.n
-			if reqi := f.validation.requiredIndex; reqi > 0 && err == nil {
-				requiredMask |= 1 << (reqi - 1)
+			if err != nil {
+				break
 			}
+			requiredMask |= f.validation.requiredBit
 			if f.funcs.isInit != nil && !o.initialized {
 				initialized = false
 			}