all: use typed variant of protoreflect.ValueOf

Change-Id: I7479632b57e7c8efade12a2eb2b855e9c321adb1
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/196037
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/bench_test.go b/encoding/bench_test.go
index d5ae728..d5ac0c3 100644
--- a/encoding/bench_test.go
+++ b/encoding/bench_test.go
@@ -24,14 +24,7 @@
 
 var benchV1 = flag.Bool("v1", false, "benchmark the v1 implementation")
 
-const (
-	boolValue  = true
-	intValue   = 1 << 30
-	floatValue = 3.14159265
-	strValue   = "hello world"
-
-	maxRecurseLevel = 3
-)
+const maxRecurseLevel = 3
 
 func makeProto() *tpb.TestAllTypes {
 	m := &tpb.TestAllTypes{}
@@ -72,34 +65,34 @@
 func scalarField(kind pref.Kind) pref.Value {
 	switch kind {
 	case pref.BoolKind:
-		return pref.ValueOf(boolValue)
+		return pref.ValueOfBool(true)
 
 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
-		return pref.ValueOf(int32(intValue))
+		return pref.ValueOfInt32(1 << 30)
 
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
-		return pref.ValueOf(int64(intValue))
+		return pref.ValueOfInt64(1 << 30)
 
 	case pref.Uint32Kind, pref.Fixed32Kind:
-		return pref.ValueOf(uint32(intValue))
+		return pref.ValueOfUint32(1 << 30)
 
 	case pref.Uint64Kind, pref.Fixed64Kind:
-		return pref.ValueOf(uint64(intValue))
+		return pref.ValueOfUint64(1 << 30)
 
 	case pref.FloatKind:
-		return pref.ValueOf(float32(floatValue))
+		return pref.ValueOfFloat32(3.14159265)
 
 	case pref.DoubleKind:
-		return pref.ValueOf(float64(floatValue))
+		return pref.ValueOfFloat64(3.14159265)
 
 	case pref.BytesKind:
-		return pref.ValueOf([]byte(strValue))
+		return pref.ValueOfBytes([]byte("hello world"))
 
 	case pref.StringKind:
-		return pref.ValueOf(strValue)
+		return pref.ValueOfString("hello world")
 
 	case pref.EnumKind:
-		return pref.ValueOf(pref.EnumNumber(42))
+		return pref.ValueOfEnum(42)
 	}
 
 	panic(fmt.Sprintf("FieldDescriptor.Kind %v is not valid", kind))
diff --git a/encoding/protojson/decode.go b/encoding/protojson/decode.go
index 799dc1d..ec32c48 100644
--- a/encoding/protojson/decode.go
+++ b/encoding/protojson/decode.go
@@ -345,7 +345,7 @@
 		return pref.Value{}, unexpectedJSONError{jval}
 	}
 	b, err := jval.Bool()
-	return pref.ValueOf(b), err
+	return pref.ValueOfBool(b), err
 }
 
 func unmarshalInt(jval json.Value, bitSize int) (pref.Value, error) {
@@ -375,9 +375,9 @@
 		return pref.Value{}, err
 	}
 	if bitSize == 32 {
-		return pref.ValueOf(int32(n)), nil
+		return pref.ValueOfInt32(int32(n)), nil
 	}
-	return pref.ValueOf(n), nil
+	return pref.ValueOfInt64(n), nil
 }
 
 func unmarshalUint(jval json.Value, bitSize int) (pref.Value, error) {
@@ -407,9 +407,9 @@
 		return pref.Value{}, err
 	}
 	if bitSize == 32 {
-		return pref.ValueOf(uint32(n)), nil
+		return pref.ValueOfUint32(uint32(n)), nil
 	}
-	return pref.ValueOf(n), nil
+	return pref.ValueOfUint64(n), nil
 }
 
 func unmarshalFloat(jval json.Value, bitSize int) (pref.Value, error) {
@@ -422,19 +422,19 @@
 		switch s {
 		case "NaN":
 			if bitSize == 32 {
-				return pref.ValueOf(float32(math.NaN())), nil
+				return pref.ValueOfFloat32(float32(math.NaN())), nil
 			}
-			return pref.ValueOf(math.NaN()), nil
+			return pref.ValueOfFloat64(math.NaN()), nil
 		case "Infinity":
 			if bitSize == 32 {
-				return pref.ValueOf(float32(math.Inf(+1))), nil
+				return pref.ValueOfFloat32(float32(math.Inf(+1))), nil
 			}
-			return pref.ValueOf(math.Inf(+1)), nil
+			return pref.ValueOfFloat64(math.Inf(+1)), nil
 		case "-Infinity":
 			if bitSize == 32 {
-				return pref.ValueOf(float32(math.Inf(-1))), nil
+				return pref.ValueOfFloat32(float32(math.Inf(-1))), nil
 			}
-			return pref.ValueOf(math.Inf(-1)), nil
+			return pref.ValueOfFloat64(math.Inf(-1)), nil
 		}
 		// Decode number from string.
 		if len(s) != len(strings.TrimSpace(s)) {
@@ -456,16 +456,16 @@
 		return pref.Value{}, err
 	}
 	if bitSize == 32 {
-		return pref.ValueOf(float32(n)), nil
+		return pref.ValueOfFloat32(float32(n)), nil
 	}
-	return pref.ValueOf(n), nil
+	return pref.ValueOfFloat64(n), nil
 }
 
 func unmarshalString(jval json.Value) (pref.Value, error) {
 	if jval.Type() != json.String {
 		return pref.Value{}, unexpectedJSONError{jval}
 	}
-	return pref.ValueOf(jval.String()), nil
+	return pref.ValueOfString(jval.String()), nil
 }
 
 func unmarshalBytes(jval json.Value) (pref.Value, error) {
@@ -485,7 +485,7 @@
 	if err != nil {
 		return pref.Value{}, err
 	}
-	return pref.ValueOf(b), nil
+	return pref.ValueOfBytes(b), nil
 }
 
 func unmarshalEnum(jval json.Value, fd pref.FieldDescriptor) (pref.Value, error) {
@@ -494,7 +494,7 @@
 		// Lookup EnumNumber based on name.
 		s := jval.String()
 		if enumVal := fd.Enum().Values().ByName(pref.Name(s)); enumVal != nil {
-			return pref.ValueOf(enumVal.Number()), nil
+			return pref.ValueOfEnum(enumVal.Number()), nil
 		}
 		return pref.Value{}, newError("invalid enum value %q", jval)
 
@@ -503,12 +503,12 @@
 		if err != nil {
 			return pref.Value{}, err
 		}
-		return pref.ValueOf(pref.EnumNumber(n)), nil
+		return pref.ValueOfEnum(pref.EnumNumber(n)), nil
 
 	case json.Null:
 		// This is only valid for google.protobuf.NullValue.
 		if isNullValue(fd) {
-			return pref.ValueOf(pref.EnumNumber(0)), nil
+			return pref.ValueOfEnum(0), nil
 		}
 	}
 
@@ -640,14 +640,14 @@
 	kind := fd.Kind()
 	switch kind {
 	case pref.StringKind:
-		return pref.ValueOf(name).MapKey(), nil
+		return pref.ValueOfString(name).MapKey(), nil
 
 	case pref.BoolKind:
 		switch name {
 		case "true":
-			return pref.ValueOf(true).MapKey(), nil
+			return pref.ValueOfBool(true).MapKey(), nil
 		case "false":
-			return pref.ValueOf(false).MapKey(), nil
+			return pref.ValueOfBool(false).MapKey(), nil
 		}
 		return pref.MapKey{}, errors.New("invalid value for boolean key %q", name)
 
@@ -656,28 +656,28 @@
 		if err != nil {
 			return pref.MapKey{}, err
 		}
-		return pref.ValueOf(int32(n)).MapKey(), nil
+		return pref.ValueOfInt32(int32(n)).MapKey(), nil
 
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
 		n, err := strconv.ParseInt(name, base10, b64)
 		if err != nil {
 			return pref.MapKey{}, err
 		}
-		return pref.ValueOf(int64(n)).MapKey(), nil
+		return pref.ValueOfInt64(int64(n)).MapKey(), nil
 
 	case pref.Uint32Kind, pref.Fixed32Kind:
 		n, err := strconv.ParseUint(name, base10, b32)
 		if err != nil {
 			return pref.MapKey{}, err
 		}
-		return pref.ValueOf(uint32(n)).MapKey(), nil
+		return pref.ValueOfUint32(uint32(n)).MapKey(), nil
 
 	case pref.Uint64Kind, pref.Fixed64Kind:
 		n, err := strconv.ParseUint(name, base10, b64)
 		if err != nil {
 			return pref.MapKey{}, err
 		}
-		return pref.ValueOf(uint64(n)).MapKey(), nil
+		return pref.ValueOfUint64(uint64(n)).MapKey(), nil
 	}
 
 	panic(fmt.Sprintf("%s: invalid kind %s for map key", fd.FullName(), kind))
diff --git a/encoding/protojson/well_known_types.go b/encoding/protojson/well_known_types.go
index 98094b5..a30b590 100644
--- a/encoding/protojson/well_known_types.go
+++ b/encoding/protojson/well_known_types.go
@@ -261,8 +261,8 @@
 	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
 	fdValue := fds.ByNumber(fieldnum.Any_Value)
 
-	m.Set(fdType, pref.ValueOf(typeURL))
-	m.Set(fdValue, pref.ValueOf(b))
+	m.Set(fdType, pref.ValueOfString(typeURL))
+	m.Set(fdValue, pref.ValueOfBytes(b))
 	return nil
 }
 
@@ -541,7 +541,7 @@
 	case json.Null:
 		o.decoder.Read()
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_NullValue)
-		m.Set(fd, pref.ValueOf(pref.EnumNumber(0)))
+		m.Set(fd, pref.ValueOfEnum(0))
 
 	case json.Bool:
 		jval, err := o.decoder.Read()
@@ -687,8 +687,8 @@
 	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
 	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)
 
-	m.Set(fdSeconds, pref.ValueOf(secs))
-	m.Set(fdNanos, pref.ValueOf(nanos))
+	m.Set(fdSeconds, pref.ValueOfInt64(secs))
+	m.Set(fdNanos, pref.ValueOfInt32(nanos))
 	return nil
 }
 
@@ -871,8 +871,8 @@
 	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
 	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)
 
-	m.Set(fdSeconds, pref.ValueOf(secs))
-	m.Set(fdNanos, pref.ValueOf(int32(t.Nanosecond())))
+	m.Set(fdSeconds, pref.ValueOfInt64(secs))
+	m.Set(fdNanos, pref.ValueOfInt32(int32(t.Nanosecond())))
 	return nil
 }
 
@@ -921,7 +921,7 @@
 		s = strings.TrimSpace(s)
 		// Convert to snake_case. Unlike encoding, no validation is done because
 		// it is not possible to know the original path names.
-		list.Append(pref.ValueOf(strs.JSONSnakeCase(s)))
+		list.Append(pref.ValueOfString(strs.JSONSnakeCase(s)))
 	}
 	return nil
 }
diff --git a/encoding/prototext/decode.go b/encoding/prototext/decode.go
index 2f2a0e9..27d23d3 100644
--- a/encoding/prototext/decode.go
+++ b/encoding/prototext/decode.go
@@ -256,53 +256,53 @@
 	switch kind := fd.Kind(); kind {
 	case pref.BoolKind:
 		if b, ok := input.Bool(); ok {
-			return pref.ValueOf(bool(b)), nil
+			return pref.ValueOfBool(bool(b)), nil
 		}
 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
 		if n, ok := input.Int(b32); ok {
-			return pref.ValueOf(int32(n)), nil
+			return pref.ValueOfInt32(int32(n)), nil
 		}
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
 		if n, ok := input.Int(b64); ok {
-			return pref.ValueOf(int64(n)), nil
+			return pref.ValueOfInt64(int64(n)), nil
 		}
 	case pref.Uint32Kind, pref.Fixed32Kind:
 		if n, ok := input.Uint(b32); ok {
-			return pref.ValueOf(uint32(n)), nil
+			return pref.ValueOfUint32(uint32(n)), nil
 		}
 	case pref.Uint64Kind, pref.Fixed64Kind:
 		if n, ok := input.Uint(b64); ok {
-			return pref.ValueOf(uint64(n)), nil
+			return pref.ValueOfUint64(uint64(n)), nil
 		}
 	case pref.FloatKind:
 		if n, ok := input.Float(b32); ok {
-			return pref.ValueOf(float32(n)), nil
+			return pref.ValueOfFloat32(float32(n)), nil
 		}
 	case pref.DoubleKind:
 		if n, ok := input.Float(b64); ok {
-			return pref.ValueOf(float64(n)), nil
+			return pref.ValueOfFloat64(float64(n)), nil
 		}
 	case pref.StringKind:
 		if input.Type() == text.String {
 			s := input.String()
 			if utf8.ValidString(s) {
-				return pref.ValueOf(s), nil
+				return pref.ValueOfString(s), nil
 			}
 			return pref.Value{}, errors.InvalidUTF8(string(fd.FullName()))
 		}
 	case pref.BytesKind:
 		if input.Type() == text.String {
-			return pref.ValueOf([]byte(input.String())), nil
+			return pref.ValueOfBytes([]byte(input.String())), nil
 		}
 	case pref.EnumKind:
 		// If input is int32, use directly.
 		if n, ok := input.Int(b32); ok {
-			return pref.ValueOf(pref.EnumNumber(n)), nil
+			return pref.ValueOfEnum(pref.EnumNumber(n)), nil
 		}
 		if name, ok := input.Name(); ok {
 			// Lookup EnumNumber based on name.
 			if enumVal := fd.Enum().Values().ByName(name); enumVal != nil {
-				return pref.ValueOf(enumVal.Number()), nil
+				return pref.ValueOfEnum(enumVal.Number()), nil
 			}
 		}
 	default:
@@ -488,8 +488,8 @@
 	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
 	fdValue := fds.ByNumber(fieldnum.Any_Value)
 
-	m.Set(fdType, pref.ValueOf(typeURL))
-	m.Set(fdValue, pref.ValueOf(b))
+	m.Set(fdType, pref.ValueOfString(typeURL))
+	m.Set(fdValue, pref.ValueOfBytes(b))
 
 	return nil
 }
diff --git a/internal/encoding/defval/default.go b/internal/encoding/defval/default.go
index 7cde945..c1d81a1 100644
--- a/internal/encoding/defval/default.go
+++ b/internal/encoding/defval/default.go
@@ -41,16 +41,16 @@
 		if f == GoTag {
 			switch s {
 			case "1":
-				return pref.ValueOf(true), nil, nil
+				return pref.ValueOfBool(true), nil, nil
 			case "0":
-				return pref.ValueOf(false), nil, nil
+				return pref.ValueOfBool(false), nil, nil
 			}
 		} else {
 			switch s {
 			case "true":
-				return pref.ValueOf(true), nil, nil
+				return pref.ValueOfBool(true), nil, nil
 			case "false":
-				return pref.ValueOf(false), nil, nil
+				return pref.ValueOfBool(false), nil, nil
 			}
 		}
 	case pref.EnumKind:
@@ -58,31 +58,31 @@
 			// Go tags use the numeric form of the enum value.
 			if n, err := strconv.ParseInt(s, 10, 32); err == nil {
 				if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil {
-					return pref.ValueOf(ev.Number()), ev, nil
+					return pref.ValueOfEnum(ev.Number()), ev, nil
 				}
 			}
 		} else {
 			// Descriptor default_value use the enum identifier.
 			ev := evs.ByName(pref.Name(s))
 			if ev != nil {
-				return pref.ValueOf(ev.Number()), ev, nil
+				return pref.ValueOfEnum(ev.Number()), ev, nil
 			}
 		}
 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
 		if v, err := strconv.ParseInt(s, 10, 32); err == nil {
-			return pref.ValueOf(int32(v)), nil, nil
+			return pref.ValueOfInt32(int32(v)), nil, nil
 		}
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
 		if v, err := strconv.ParseInt(s, 10, 64); err == nil {
-			return pref.ValueOf(int64(v)), nil, nil
+			return pref.ValueOfInt64(int64(v)), nil, nil
 		}
 	case pref.Uint32Kind, pref.Fixed32Kind:
 		if v, err := strconv.ParseUint(s, 10, 32); err == nil {
-			return pref.ValueOf(uint32(v)), nil, nil
+			return pref.ValueOfUint32(uint32(v)), nil, nil
 		}
 	case pref.Uint64Kind, pref.Fixed64Kind:
 		if v, err := strconv.ParseUint(s, 10, 64); err == nil {
-			return pref.ValueOf(uint64(v)), nil, nil
+			return pref.ValueOfUint64(uint64(v)), nil, nil
 		}
 	case pref.FloatKind, pref.DoubleKind:
 		var v float64
@@ -99,17 +99,17 @@
 		}
 		if err == nil {
 			if k == pref.FloatKind {
-				return pref.ValueOf(float32(v)), nil, nil
+				return pref.ValueOfFloat32(float32(v)), nil, nil
 			} else {
-				return pref.ValueOf(float64(v)), nil, nil
+				return pref.ValueOfFloat64(float64(v)), nil, nil
 			}
 		}
 	case pref.StringKind:
 		// String values are already unescaped and can be used as is.
-		return pref.ValueOf(s), nil, nil
+		return pref.ValueOfString(s), nil, nil
 	case pref.BytesKind:
 		if b, ok := unmarshalBytes(s); ok {
-			return pref.ValueOf(b), nil, nil
+			return pref.ValueOfBytes(b), nil, nil
 		}
 	}
 	return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s)
diff --git a/internal/filedesc/desc.go b/internal/filedesc/desc.go
index 51ef7c1..72a45e2 100644
--- a/internal/filedesc/desc.go
+++ b/internal/filedesc/desc.go
@@ -533,7 +533,7 @@
 		// If we are unable to resolve the enum dependency, use a placeholder
 		// enum value since we will not be able to parse the default value.
 		if ed.IsPlaceholder() && pref.Name(b).IsValid() {
-			v := pref.ValueOf(pref.EnumNumber(0))
+			v := pref.ValueOfEnum(0)
 			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b)))
 			return DefaultValue(v, ev)
 		}
@@ -561,28 +561,28 @@
 		}
 		switch fd.Kind() {
 		case pref.BoolKind:
-			return pref.ValueOf(false)
+			return pref.ValueOfBool(false)
 		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
-			return pref.ValueOf(int32(0))
+			return pref.ValueOfInt32(0)
 		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
-			return pref.ValueOf(int64(0))
+			return pref.ValueOfInt64(0)
 		case pref.Uint32Kind, pref.Fixed32Kind:
-			return pref.ValueOf(uint32(0))
+			return pref.ValueOfUint32(0)
 		case pref.Uint64Kind, pref.Fixed64Kind:
-			return pref.ValueOf(uint64(0))
+			return pref.ValueOfUint64(0)
 		case pref.FloatKind:
-			return pref.ValueOf(float32(0))
+			return pref.ValueOfFloat32(0)
 		case pref.DoubleKind:
-			return pref.ValueOf(float64(0))
+			return pref.ValueOfFloat64(0)
 		case pref.StringKind:
-			return pref.ValueOf(string(""))
+			return pref.ValueOfString("")
 		case pref.BytesKind:
-			return pref.ValueOf([]byte(nil))
+			return pref.ValueOfBytes(nil)
 		case pref.EnumKind:
 			if evs := fd.Enum().Values(); evs.Len() > 0 {
-				return pref.ValueOf(evs.Get(0).Number())
+				return pref.ValueOfEnum(evs.Get(0).Number())
 			}
-			return pref.ValueOf(pref.EnumNumber(0))
+			return pref.ValueOfEnum(0)
 		}
 	}
 
diff --git a/internal/filedesc/desc_lazy.go b/internal/filedesc/desc_lazy.go
index b989092..86720a0 100644
--- a/internal/filedesc/desc_lazy.go
+++ b/internal/filedesc/desc_lazy.go
@@ -451,7 +451,7 @@
 			case fieldnum.FieldDescriptorProto_JsonName:
 				fd.L1.JSONName = JSONName(sb.MakeString(v))
 			case fieldnum.FieldDescriptorProto_DefaultValue:
-				fd.L1.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveMessages
+				fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
 			case fieldnum.FieldDescriptorProto_TypeName:
 				rawTypeName = v
 			case fieldnum.FieldDescriptorProto_Options:
@@ -544,7 +544,7 @@
 			case fieldnum.FieldDescriptorProto_JsonName:
 				xd.L2.JSONName = JSONName(sb.MakeString(v))
 			case fieldnum.FieldDescriptorProto_DefaultValue:
-				xd.L2.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveExtensions
+				xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
 			case fieldnum.FieldDescriptorProto_TypeName:
 				rawTypeName = v
 			case fieldnum.FieldDescriptorProto_Options:
diff --git a/internal/impl/convert.go b/internal/impl/convert.go
index 67cd7f8..5fdb022 100644
--- a/internal/impl/convert.go
+++ b/internal/impl/convert.go
@@ -76,15 +76,15 @@
 )
 
 var (
-	boolZero    = pref.ValueOf(bool(false))
-	int32Zero   = pref.ValueOf(int32(0))
-	int64Zero   = pref.ValueOf(int64(0))
-	uint32Zero  = pref.ValueOf(uint32(0))
-	uint64Zero  = pref.ValueOf(uint64(0))
-	float32Zero = pref.ValueOf(float32(0))
-	float64Zero = pref.ValueOf(float64(0))
-	stringZero  = pref.ValueOf(string(""))
-	bytesZero   = pref.ValueOf([]byte(nil))
+	boolZero    = pref.ValueOfBool(false)
+	int32Zero   = pref.ValueOfInt32(0)
+	int64Zero   = pref.ValueOfInt64(0)
+	uint32Zero  = pref.ValueOfUint32(0)
+	uint64Zero  = pref.ValueOfUint64(0)
+	float32Zero = pref.ValueOfFloat32(0)
+	float64Zero = pref.ValueOfFloat64(0)
+	stringZero  = pref.ValueOfString("")
+	bytesZero   = pref.ValueOfBytes(nil)
 )
 
 func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
@@ -376,7 +376,7 @@
 func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
 	var def pref.Value
 	if fd.Cardinality() == pref.Repeated {
-		def = pref.ValueOf(fd.Enum().Values().Get(0).Number())
+		def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
 	} else {
 		def = fd.Default()
 	}
@@ -387,7 +387,7 @@
 	if v.Type() != c.goType {
 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
 	}
-	return pref.ValueOf(pref.EnumNumber(v.Int()))
+	return pref.ValueOfEnum(pref.EnumNumber(v.Int()))
 }
 
 func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
@@ -424,9 +424,9 @@
 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
 	}
 	if m, ok := v.Interface().(pref.ProtoMessage); ok {
-		return pref.ValueOf(m.ProtoReflect())
+		return pref.ValueOfMessage(m.ProtoReflect())
 	}
-	return pref.ValueOf(legacyWrapMessage(v).ProtoReflect())
+	return pref.ValueOfMessage(legacyWrapMessage(v).ProtoReflect())
 }
 
 func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
diff --git a/internal/impl/convert_list.go b/internal/impl/convert_list.go
index 222f1a4..d17676b 100644
--- a/internal/impl/convert_list.go
+++ b/internal/impl/convert_list.go
@@ -32,7 +32,7 @@
 	}
 	pv := reflect.New(c.goType)
 	pv.Elem().Set(v)
-	return pref.ValueOf(&listReflect{pv, c.c})
+	return pref.ValueOfList(&listReflect{pv, c.c})
 }
 
 func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
@@ -56,11 +56,11 @@
 }
 
 func (c *listConverter) New() pref.Value {
-	return pref.ValueOf(&listReflect{reflect.New(c.goType), c.c})
+	return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
 }
 
 func (c *listConverter) Zero() pref.Value {
-	return pref.ValueOf(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
+	return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
 }
 
 type listPtrConverter struct {
@@ -72,7 +72,7 @@
 	if v.Type() != c.goType {
 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
 	}
-	return pref.ValueOf(&listReflect{v, c.c})
+	return pref.ValueOfList(&listReflect{v, c.c})
 }
 
 func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value {
diff --git a/internal/impl/convert_map.go b/internal/impl/convert_map.go
index 47b5f22..2ddfc78 100644
--- a/internal/impl/convert_map.go
+++ b/internal/impl/convert_map.go
@@ -31,7 +31,7 @@
 	if v.Type() != c.goType {
 		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
 	}
-	return pref.ValueOf(&mapReflect{v, c.keyConv, c.valConv})
+	return pref.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv})
 }
 
 func (c *mapConverter) GoValueOf(v pref.Value) reflect.Value {
diff --git a/internal/impl/legacy_message.go b/internal/impl/legacy_message.go
index 6c52284..de03ee6 100644
--- a/internal/impl/legacy_message.go
+++ b/internal/impl/legacy_message.go
@@ -236,10 +236,10 @@
 		fd.L1.Options = func() pref.ProtoMessage {
 			opts := descopts.Field.ProtoReflect().New()
 			if fd.L1.IsWeak {
-				opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOf(true))
+				opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
 			}
 			if fd.L1.HasPacked {
-				opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOf(fd.L1.IsPacked))
+				opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked))
 			}
 			return opts.Interface()
 		}
@@ -273,7 +273,7 @@
 				md2.L2.IsMapEntry = true
 				md2.L2.Options = func() pref.ProtoMessage {
 					opts := descopts.Message.ProtoReflect().New()
-					opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOf(true))
+					opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
 					return opts.Interface()
 				}
 
diff --git a/internal/impl/message_reflect_field.go b/internal/impl/message_reflect_field.go
index e55b6de..e384aa3 100644
--- a/internal/impl/message_reflect_field.go
+++ b/internal/impl/message_reflect_field.go
@@ -99,7 +99,7 @@
 			}
 			rv = rv.Elem().Elem().Field(0)
 			if rv.IsNil() {
-				rv.Set(conv.GoValueOf(pref.ValueOf(conv.New().Message())))
+				rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message())))
 			}
 			return conv.PBValueOf(rv)
 		},
@@ -324,14 +324,14 @@
 		get: func(p pointer) pref.Value {
 			lazyInit()
 			if p.IsNil() {
-				return pref.ValueOf(messageType.Zero())
+				return pref.ValueOfMessage(messageType.Zero())
 			}
 			fs := p.Apply(weakOffset).WeakFields()
 			m, ok := (*fs)[num]
 			if !ok {
-				return pref.ValueOf(messageType.Zero())
+				return pref.ValueOfMessage(messageType.Zero())
 			}
-			return pref.ValueOf(m.(pref.ProtoMessage).ProtoReflect())
+			return pref.ValueOfMessage(m.(pref.ProtoMessage).ProtoReflect())
 		},
 		set: func(p pointer, v pref.Value) {
 			lazyInit()
@@ -356,7 +356,7 @@
 				m = messageType.New().Interface().(piface.MessageV1)
 				(*fs)[num] = m
 			}
-			return pref.ValueOf(m.(pref.ProtoMessage).ProtoReflect())
+			return pref.ValueOfMessage(m.(pref.ProtoMessage).ProtoReflect())
 		},
 		newMessage: func() pref.Message {
 			lazyInit()
@@ -364,7 +364,7 @@
 		},
 		newField: func() pref.Value {
 			lazyInit()
-			return pref.ValueOf(messageType.New())
+			return pref.ValueOfMessage(messageType.New())
 		},
 	}
 }
diff --git a/proto/merge.go b/proto/merge.go
index 8c31b3c..45bfc9b 100644
--- a/proto/merge.go
+++ b/proto/merge.go
@@ -74,5 +74,5 @@
 }
 
 func cloneBytes(v protoreflect.Value) protoreflect.Value {
-	return protoreflect.ValueOf(append([]byte{}, v.Bytes()...))
+	return protoreflect.ValueOfBytes(append([]byte{}, v.Bytes()...))
 }
diff --git a/reflect/protodesc/desc_resolve.go b/reflect/protodesc/desc_resolve.go
index 83f0ba0..1bf4799 100644
--- a/reflect/protodesc/desc_resolve.go
+++ b/reflect/protodesc/desc_resolve.go
@@ -268,9 +268,9 @@
 	}
 	v, ev, err := defval.Unmarshal(s, fd.Kind(), evs, defval.Descriptor)
 	if err != nil && allowUnresolvable && evs != nil && protoreflect.Name(s).IsValid() {
-		v = protoreflect.ValueOf(protoreflect.EnumNumber(0))
+		v = protoreflect.ValueOfEnum(0)
 		if evs.Len() > 0 {
-			v = protoreflect.ValueOf(evs.Get(0).Number())
+			v = protoreflect.ValueOfEnum(evs.Get(0).Number())
 		}
 		ev = filedesc.PlaceholderEnumValue(fd.Enum().FullName().Parent().Append(protoreflect.Name(s)))
 	} else if err != nil {
diff --git a/testing/prototest/prototest.go b/testing/prototest/prototest.go
index 0aad3f0..437c216 100644
--- a/testing/prototest/prototest.go
+++ b/testing/prototest/prototest.go
@@ -188,9 +188,9 @@
 	m.Clear(fd)
 
 	// Set to the wrong type.
-	v := pref.ValueOf("")
+	v := pref.ValueOfString("")
 	if fd.Kind() == pref.StringKind {
-		v = pref.ValueOf(int32(0))
+		v = pref.ValueOfInt32(0)
 	}
 	if !panics(func() {
 		m.Set(fd, v)
@@ -226,7 +226,7 @@
 		v := newMapValue(fd, mapv, n, nil)
 		mapv.Set(k, v)
 		want.Set(k, v)
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfMap(want); !valueEqual(got, want) {
 			t.Errorf("after inserting %d elements to %q:\nMessage.Get(%v) = %v, want %v", i, name, num, formatValue(got), formatValue(want))
 		}
 	}
@@ -236,7 +236,7 @@
 		nv := newMapValue(fd, mapv, 10, nil)
 		mapv.Set(k, nv)
 		want.Set(k, nv)
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfMap(want); !valueEqual(got, want) {
 			t.Errorf("after setting element %v of %q:\nMessage.Get(%v) = %v, want %v", formatValue(k.Value()), name, num, formatValue(got), formatValue(want))
 		}
 		return true
@@ -249,7 +249,7 @@
 		if got, want := m.Has(fd), want.Len() > 0; got != want {
 			t.Errorf("after clearing elements of %q:\nMessage.Has(%v) = %v, want %v", name, num, got, want)
 		}
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfMap(want); !valueEqual(got, want) {
 			t.Errorf("after clearing elements of %q:\nMessage.Get(%v) = %v, want %v", name, num, formatValue(got), formatValue(want))
 		}
 		return true
@@ -307,7 +307,7 @@
 		want.Append(v)
 		list.Append(v)
 
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfList(want); !valueEqual(got, want) {
 			t.Errorf("after appending %d elements to %q:\nMessage.Get(%v) = %v, want %v", i+1, name, num, formatValue(got), formatValue(want))
 		}
 	}
@@ -317,7 +317,7 @@
 		v := newListElement(fd, list, seed(i+10), nil)
 		want.Set(i, v)
 		list.Set(i, v)
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfList(want); !valueEqual(got, want) {
 			t.Errorf("after setting element %d of %q:\nMessage.Get(%v) = %v, want %v", i, name, num, formatValue(got), formatValue(want))
 		}
 	}
@@ -330,7 +330,7 @@
 		if got, want := m.Has(fd), want.Len() > 0 || fd.IsExtension(); got != want {
 			t.Errorf("after truncating %q to %d:\nMessage.Has(%v) = %v, want %v", name, n, num, got, want)
 		}
-		if got, want := m.Get(fd), pref.ValueOf(want); !valueEqual(got, want) {
+		if got, want := m.Get(fd), pref.ValueOfList(want); !valueEqual(got, want) {
 			t.Errorf("after truncating %q to %d:\nMessage.Get(%v) = %v, want %v", name, n, num, formatValue(got), formatValue(want))
 		}
 	}
@@ -355,9 +355,9 @@
 	for _, v := range []float64{math.Inf(-1), math.Inf(1), math.NaN(), math.Copysign(0, -1)} {
 		var val pref.Value
 		if fd.Kind() == pref.FloatKind {
-			val = pref.ValueOf(float32(v))
+			val = pref.ValueOfFloat32(float32(v))
 		} else {
-			val = pref.ValueOf(v)
+			val = pref.ValueOfFloat64(float64(v))
 		}
 		m.Set(fd, val)
 		// Note that Has is true for -0.
@@ -543,7 +543,7 @@
 		list.Append(newListElement(fd, list, minVal, stack))
 		list.Append(newListElement(fd, list, maxVal, stack))
 		list.Append(newListElement(fd, list, n, stack))
-		return pref.ValueOf(list)
+		return pref.ValueOfList(list)
 	case fd.IsMap():
 		if n == 0 {
 			return m.New().Get(fd)
@@ -553,7 +553,7 @@
 		mapv.Set(newMapKey(fd, minVal), newMapValue(fd, mapv, minVal, stack))
 		mapv.Set(newMapKey(fd, maxVal), newMapValue(fd, mapv, maxVal, stack))
 		mapv.Set(newMapKey(fd, n), newMapValue(fd, mapv, newSeed(n, 0), stack))
-		return pref.ValueOf(mapv)
+		return pref.ValueOfMap(mapv)
 	case fd.Message() != nil:
 		//if n == 0 {
 		//	return m.New().Get(fd)
@@ -587,7 +587,7 @@
 func newScalarValue(fd pref.FieldDescriptor, n seed) pref.Value {
 	switch fd.Kind() {
 	case pref.BoolKind:
-		return pref.ValueOf(n != 0)
+		return pref.ValueOfBool(n != 0)
 	case pref.EnumKind:
 		vals := fd.Enum().Values()
 		var i int
@@ -599,85 +599,85 @@
 		default:
 			i = int(n) % vals.Len()
 		}
-		return pref.ValueOf(vals.Get(i).Number())
+		return pref.ValueOfEnum(vals.Get(i).Number())
 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
 		switch n {
 		case minVal:
-			return pref.ValueOf(int32(math.MinInt32))
+			return pref.ValueOfInt32(math.MinInt32)
 		case maxVal:
-			return pref.ValueOf(int32(math.MaxInt32))
+			return pref.ValueOfInt32(math.MaxInt32)
 		default:
-			return pref.ValueOf(int32(n))
+			return pref.ValueOfInt32(int32(n))
 		}
 	case pref.Uint32Kind, pref.Fixed32Kind:
 		switch n {
 		case minVal:
 			// Only use 0 for the zero value.
-			return pref.ValueOf(uint32(1))
+			return pref.ValueOfUint32(1)
 		case maxVal:
-			return pref.ValueOf(uint32(math.MaxInt32))
+			return pref.ValueOfUint32(math.MaxInt32)
 		default:
-			return pref.ValueOf(uint32(n))
+			return pref.ValueOfUint32(uint32(n))
 		}
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
 		switch n {
 		case minVal:
-			return pref.ValueOf(int64(math.MinInt64))
+			return pref.ValueOfInt64(math.MinInt64)
 		case maxVal:
-			return pref.ValueOf(int64(math.MaxInt64))
+			return pref.ValueOfInt64(math.MaxInt64)
 		default:
-			return pref.ValueOf(int64(n))
+			return pref.ValueOfInt64(int64(n))
 		}
 	case pref.Uint64Kind, pref.Fixed64Kind:
 		switch n {
 		case minVal:
 			// Only use 0 for the zero value.
-			return pref.ValueOf(uint64(1))
+			return pref.ValueOfUint64(1)
 		case maxVal:
-			return pref.ValueOf(uint64(math.MaxInt64))
+			return pref.ValueOfUint64(math.MaxInt64)
 		default:
-			return pref.ValueOf(uint64(n))
+			return pref.ValueOfUint64(uint64(n))
 		}
 	case pref.FloatKind:
 		switch n {
 		case minVal:
-			return pref.ValueOf(float32(math.SmallestNonzeroFloat32))
+			return pref.ValueOfFloat32(math.SmallestNonzeroFloat32)
 		case maxVal:
-			return pref.ValueOf(float32(math.MaxFloat32))
+			return pref.ValueOfFloat32(math.MaxFloat32)
 		default:
-			return pref.ValueOf(1.5 * float32(n))
+			return pref.ValueOfFloat32(1.5 * float32(n))
 		}
 	case pref.DoubleKind:
 		switch n {
 		case minVal:
-			return pref.ValueOf(float64(math.SmallestNonzeroFloat64))
+			return pref.ValueOfFloat64(math.SmallestNonzeroFloat64)
 		case maxVal:
-			return pref.ValueOf(float64(math.MaxFloat64))
+			return pref.ValueOfFloat64(math.MaxFloat64)
 		default:
-			return pref.ValueOf(1.5 * float64(n))
+			return pref.ValueOfFloat64(1.5 * float64(n))
 		}
 	case pref.StringKind:
 		if n == 0 {
-			return pref.ValueOf("")
+			return pref.ValueOfString("")
 		}
-		return pref.ValueOf(fmt.Sprintf("%d", n))
+		return pref.ValueOfString(fmt.Sprintf("%d", n))
 	case pref.BytesKind:
 		if n == 0 {
-			return pref.ValueOf([]byte(nil))
+			return pref.ValueOfBytes(nil)
 		}
-		return pref.ValueOf([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)})
+		return pref.ValueOfBytes([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)})
 	}
 	panic("unhandled kind")
 }
 
 func populateMessage(m pref.Message, n seed, stack []pref.MessageDescriptor) pref.Value {
 	if n == 0 {
-		return pref.ValueOf(m)
+		return pref.ValueOfMessage(m)
 	}
 	md := m.Descriptor()
 	for _, x := range stack {
 		if md == x {
-			return pref.ValueOf(m)
+			return pref.ValueOfMessage(m)
 		}
 	}
 	stack = append(stack, md)
@@ -688,7 +688,7 @@
 		}
 		m.Set(fd, newValue(m, fd, newSeed(n, i), stack))
 	}
-	return pref.ValueOf(m)
+	return pref.ValueOfMessage(m)
 }
 
 func panics(f func()) (didPanic bool) {
diff --git a/types/dynamicpb/dynamic.go b/types/dynamicpb/dynamic.go
index 4327879..48d1830 100644
--- a/types/dynamicpb/dynamic.go
+++ b/types/dynamicpb/dynamic.go
@@ -133,13 +133,13 @@
 	}
 	switch {
 	case fd.IsMap():
-		return pref.ValueOf(&dynamicMap{desc: fd})
+		return pref.ValueOfMap(&dynamicMap{desc: fd})
 	case fd.IsList():
-		return pref.ValueOf(emptyList{desc: fd})
+		return pref.ValueOfList(emptyList{desc: fd})
 	case fd.Message() != nil:
-		return pref.ValueOf(&Message{typ: messageType{fd.Message()}})
+		return pref.ValueOfMessage(&Message{typ: messageType{fd.Message()}})
 	case fd.Kind() == pref.BytesKind:
-		return pref.ValueOf(append([]byte(nil), fd.Default().Bytes()...))
+		return pref.ValueOfBytes(append([]byte(nil), fd.Default().Bytes()...))
 	default:
 		return fd.Default()
 	}
@@ -214,14 +214,14 @@
 	case fd.IsExtension():
 		return fd.(pref.ExtensionTypeDescriptor).Type().New()
 	case fd.IsMap():
-		return pref.ValueOf(&dynamicMap{
+		return pref.ValueOfMap(&dynamicMap{
 			desc: fd,
 			mapv: make(map[interface{}]pref.Value),
 		})
 	case fd.IsList():
-		return pref.ValueOf(&dynamicList{desc: fd})
+		return pref.ValueOfList(&dynamicList{desc: fd})
 	case fd.Message() != nil:
-		return pref.ValueOf(NewMessage(fd.Message()).ProtoReflect())
+		return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
 	default:
 		return fd.Default()
 	}
@@ -352,7 +352,7 @@
 func (x *dynamicMap) Len() int               { return len(x.mapv) }
 func (x *dynamicMap) NewValue() pref.Value {
 	if md := x.desc.MapValue().Message(); md != nil {
-		return pref.ValueOf(NewMessage(md).ProtoReflect())
+		return pref.ValueOfMessage(NewMessage(md).ProtoReflect())
 	}
 	return x.desc.MapValue().Default()
 }
@@ -474,27 +474,27 @@
 func newListEntry(fd pref.FieldDescriptor) pref.Value {
 	switch fd.Kind() {
 	case pref.BoolKind:
-		return pref.ValueOf(false)
+		return pref.ValueOfBool(false)
 	case pref.EnumKind:
-		return pref.ValueOf(fd.Enum().Values().Get(0).Number())
+		return pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
-		return pref.ValueOf(int32(0))
+		return pref.ValueOfInt32(0)
 	case pref.Uint32Kind, pref.Fixed32Kind:
-		return pref.ValueOf(uint32(0))
+		return pref.ValueOfUint32(0)
 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
-		return pref.ValueOf(int64(0))
+		return pref.ValueOfInt64(0)
 	case pref.Uint64Kind, pref.Fixed64Kind:
-		return pref.ValueOf(uint64(0))
+		return pref.ValueOfUint64(0)
 	case pref.FloatKind:
-		return pref.ValueOf(float32(0))
+		return pref.ValueOfFloat32(0)
 	case pref.DoubleKind:
-		return pref.ValueOf(float64(0))
+		return pref.ValueOfFloat64(0)
 	case pref.StringKind:
-		return pref.ValueOf("")
+		return pref.ValueOfString("")
 	case pref.BytesKind:
-		return pref.ValueOf(([]byte)(nil))
+		return pref.ValueOfBytes(nil)
 	case pref.MessageKind, pref.GroupKind:
-		return pref.ValueOf(NewMessage(fd.Message()).ProtoReflect())
+		return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
 	}
 	panic(errors.New("%v: unknown kind %v", fd.FullName(), fd.Kind()))
 }
@@ -533,14 +533,14 @@
 func (xt extensionType) New() pref.Value {
 	switch {
 	case xt.desc.IsMap():
-		return pref.ValueOf(&dynamicMap{
+		return pref.ValueOfMap(&dynamicMap{
 			desc: xt.desc,
 			mapv: make(map[interface{}]pref.Value),
 		})
 	case xt.desc.IsList():
-		return pref.ValueOf(&dynamicList{desc: xt.desc})
+		return pref.ValueOfList(&dynamicList{desc: xt.desc})
 	case xt.desc.Message() != nil:
-		return pref.ValueOf(NewMessage(xt.desc.Message()))
+		return pref.ValueOfMessage(NewMessage(xt.desc.Message()))
 	default:
 		return xt.desc.Default()
 	}
@@ -549,11 +549,11 @@
 func (xt extensionType) Zero() pref.Value {
 	switch {
 	case xt.desc.IsMap():
-		return pref.ValueOf(&dynamicMap{desc: xt.desc})
+		return pref.ValueOfMap(&dynamicMap{desc: xt.desc})
 	case xt.desc.Cardinality() == pref.Repeated:
-		return pref.ValueOf(emptyList{desc: xt.desc})
+		return pref.ValueOfList(emptyList{desc: xt.desc})
 	case xt.desc.Message() != nil:
-		return pref.ValueOf(&Message{typ: messageType{xt.desc.Message()}})
+		return pref.ValueOfMessage(&Message{typ: messageType{xt.desc.Message()}})
 	default:
 		return xt.desc.Default()
 	}