encoding/jsonpb: switch MarshalOptions to use new JSON encoder

Delete temporary copy of old JSON encoder/decoder internal/encoding/jsonx.

Change-Id: I8b23d7907370d069d0930c360979a2d8b62adc93
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/165778
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/jsonpb/encode.go b/encoding/jsonpb/encode.go
index e5819f2..4152a74 100644
--- a/encoding/jsonpb/encode.go
+++ b/encoding/jsonpb/encode.go
@@ -6,10 +6,9 @@
 
 import (
 	"encoding/base64"
-	"math"
 	"sort"
 
-	json "github.com/golang/protobuf/v2/internal/encoding/jsonx"
+	"github.com/golang/protobuf/v2/internal/encoding/json"
 	"github.com/golang/protobuf/v2/internal/errors"
 	"github.com/golang/protobuf/v2/internal/pragma"
 	"github.com/golang/protobuf/v2/proto"
@@ -29,36 +28,49 @@
 	Compact bool
 }
 
-// Marshal writes the given proto.Message in JSON format using options in MarshalOptions object.
+// Marshal returns the given proto.Message in JSON format using options in MarshalOptions object.
 func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
-	var nerr errors.NonFatal
-	v, err := o.marshalMessage(m.ProtoReflect())
-	if !nerr.Merge(err) {
-		return nil, err
-	}
-
 	indent := "  "
 	if o.Compact {
 		indent = ""
 	}
 
-	b, err := json.Marshal(v, indent)
+	enc, err := newEncoder(indent)
+	if err != nil {
+		return nil, err
+	}
+
+	var nerr errors.NonFatal
+	err = enc.marshalMessage(m.ProtoReflect())
 	if !nerr.Merge(err) {
 		return nil, err
 	}
-	return b, nerr.E
+	return enc.Bytes(), nerr.E
 }
 
-// marshalMessage converts a protoreflect.Message to a json.Value.
-func (o MarshalOptions) marshalMessage(m pref.Message) (json.Value, error) {
-	var nerr errors.NonFatal
-	var msgFields [][2]json.Value
+// encoder encodes protoreflect values into JSON.
+type encoder struct {
+	*json.Encoder
+}
 
-	msgType := m.Type()
-	fieldDescs := msgType.Fields()
+func newEncoder(indent string) (encoder, error) {
+	enc, err := json.NewEncoder(indent)
+	if err != nil {
+		return encoder{}, errors.New("error in constructing an encoder: %v", err)
+	}
+	return encoder{enc}, nil
+}
+
+// marshalMessage marshals the given protoreflect.Message.
+func (e encoder) marshalMessage(m pref.Message) error {
+	e.StartObject()
+	defer e.EndObject()
+
+	var nerr errors.NonFatal
+	fieldDescs := m.Type().Fields()
 	knownFields := m.KnownFields()
-	size := fieldDescs.Len()
-	for i := 0; i < size; i++ {
+
+	for i := 0; i < fieldDescs.Len(); i++ {
 		fd := fieldDescs.Get(i)
 		num := fd.Number()
 
@@ -70,111 +82,116 @@
 			continue
 		}
 
-		name := json.ValueOf(fd.JSONName())
-		pval := knownFields.Get(num)
-		var err error
-		msgFields, err = o.appendField(msgFields, name, pval, fd)
-		if !nerr.Merge(err) {
-			return json.Value{}, err
+		name := fd.JSONName()
+		if err := e.WriteName(name); !nerr.Merge(err) {
+			return err
+		}
+
+		val := knownFields.Get(num)
+		if err := e.marshalValue(val, fd); !nerr.Merge(err) {
+			return err
 		}
 	}
-
-	return json.ValueOf(msgFields), nerr.E
+	return nerr.E
 }
 
-// appendField marshals a protoreflect.Value and appends it to the given
-// [][2]json.Value.
-func (o MarshalOptions) appendField(msgFields [][2]json.Value, name json.Value, pval pref.Value, fd pref.FieldDescriptor) ([][2]json.Value, error) {
+// marshalValue marshals the given protoreflect.Value.
+func (e encoder) marshalValue(val pref.Value, fd pref.FieldDescriptor) error {
 	var nerr errors.NonFatal
-	var jval json.Value
-	var err error
-
 	if fd.Cardinality() == pref.Repeated {
 		// Map or repeated fields.
 		if fd.IsMap() {
-			jval, err = o.marshalMap(pval.Map(), fd)
-			if !nerr.Merge(err) {
-				return msgFields, err
+			if err := e.marshalMap(val.Map(), fd); !nerr.Merge(err) {
+				return err
 			}
 		} else {
-			jval, err = o.marshalList(pval.List(), fd)
-			if !nerr.Merge(err) {
-				return msgFields, err
+			if err := e.marshalList(val.List(), fd); !nerr.Merge(err) {
+				return err
 			}
 		}
 	} else {
 		// Required or optional fields.
-		jval, err = o.marshalSingular(pval, fd)
-		if !nerr.Merge(err) {
-			return msgFields, err
+		if err := e.marshalSingular(val, fd); !nerr.Merge(err) {
+			return err
 		}
 	}
-
-	msgFields = append(msgFields, [2]json.Value{name, jval})
-	return msgFields, nerr.E
+	return nerr.E
 }
 
-// marshalSingular converts a non-repeated field value to json.Value.
-// This includes all scalar types, enums, messages, and groups.
-func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor) (json.Value, error) {
-	kind := fd.Kind()
-	switch kind {
-	case pref.BoolKind, pref.StringKind,
-		pref.Int32Kind, pref.Sint32Kind, pref.Uint32Kind,
-		pref.Sfixed32Kind, pref.Fixed32Kind:
-		return json.ValueOf(val.Interface()), nil
+// marshalSingular marshals the given non-repeated field value. This includes
+// all scalar types, enums, messages, and groups.
+func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
+	var nerr errors.NonFatal
+	switch kind := fd.Kind(); kind {
+	case pref.BoolKind:
+		e.WriteBool(val.Bool())
+
+	case pref.StringKind:
+		if err := e.WriteString(val.String()); !nerr.Merge(err) {
+			return err
+		}
+
+	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+		e.WriteInt(val.Int())
+
+	case pref.Uint32Kind, pref.Fixed32Kind:
+		e.WriteUint(val.Uint())
 
 	case pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind,
 		pref.Sfixed64Kind, pref.Fixed64Kind:
-		return json.ValueOf(val.String()), nil
+		// 64-bit integers are written out as JSON string.
+		e.WriteString(val.String())
 
-	case pref.FloatKind, pref.DoubleKind:
-		n := val.Float()
-		switch {
-		case math.IsNaN(n):
-			return json.ValueOf("NaN"), nil
-		case math.IsInf(n, +1):
-			return json.ValueOf("Infinity"), nil
-		case math.IsInf(n, -1):
-			return json.ValueOf("-Infinity"), nil
-		default:
-			return json.ValueOf(n), nil
-		}
+	case pref.FloatKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 32)
+
+	case pref.DoubleKind:
+		// Encoder.WriteFloat handles the special numbers NaN and infinites.
+		e.WriteFloat(val.Float(), 64)
 
 	case pref.BytesKind:
-		return json.ValueOf(base64.StdEncoding.EncodeToString(val.Bytes())), nil
+		err := e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
+		if !nerr.Merge(err) {
+			return err
+		}
 
 	case pref.EnumKind:
 		num := val.Enum()
 		if desc := fd.EnumType().Values().ByNumber(num); desc != nil {
-			return json.ValueOf(string(desc.Name())), nil
+			err := e.WriteString(string(desc.Name()))
+			if !nerr.Merge(err) {
+				return err
+			}
+		} else {
+			// Use numeric value if there is no enum value descriptor.
+			e.WriteInt(int64(num))
 		}
-		// Use numeric value if there is no enum value descriptor.
-		return json.ValueOf(int32(num)), nil
 
 	case pref.MessageKind, pref.GroupKind:
-		return o.marshalMessage(val.Message())
-	}
+		if err := e.marshalMessage(val.Message()); !nerr.Merge(err) {
+			return err
+		}
 
-	return json.Value{}, errors.New("%v has unknown kind: %v", fd.FullName(), kind)
+	default:
+		return errors.New("%v has unknown kind: %v", fd.FullName(), kind)
+	}
+	return nerr.E
 }
 
-// marshalList converts a protoreflect.List to json.Value.
-func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) (json.Value, error) {
+// marshalList marshals the given protoreflect.List.
+func (e encoder) marshalList(list pref.List, fd pref.FieldDescriptor) error {
+	e.StartArray()
+	defer e.EndArray()
+
 	var nerr errors.NonFatal
-	size := list.Len()
-	values := make([]json.Value, 0, size)
-
-	for i := 0; i < size; i++ {
+	for i := 0; i < list.Len(); i++ {
 		item := list.Get(i)
-		val, err := o.marshalSingular(item, fd)
-		if !nerr.Merge(err) {
-			return json.Value{}, err
+		if err := e.marshalSingular(item, fd); !nerr.Merge(err) {
+			return err
 		}
-		values = append(values, val)
 	}
-
-	return json.ValueOf(values), nerr.E
+	return nerr.E
 }
 
 type mapEntry struct {
@@ -182,8 +199,11 @@
 	value pref.Value
 }
 
-// marshalMap converts a protoreflect.Map to json.Value.
-func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) (json.Value, error) {
+// marshalMap marshals given protoreflect.Map.
+func (e encoder) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
+	e.StartObject()
+	defer e.EndObject()
+
 	msgFields := fd.MessageType().Fields()
 	keyType := msgFields.ByNumber(1)
 	valType := msgFields.ByNumber(2)
@@ -196,18 +216,18 @@
 	})
 	sortMap(keyType.Kind(), entries)
 
-	// Convert to list of [2]json.Value.
+	// Write out sorted list.
 	var nerr errors.NonFatal
-	values := make([][2]json.Value, 0, len(entries))
 	for _, entry := range entries {
-		jkey := json.ValueOf(entry.key.String())
-		jval, err := o.marshalSingular(entry.value, valType)
-		if !nerr.Merge(err) {
-			return json.Value{}, err
+		if err := e.WriteName(entry.key.String()); !nerr.Merge(err) {
+			return err
 		}
-		values = append(values, [2]json.Value{jkey, jval})
+
+		if err := e.marshalSingular(entry.value, valType); !nerr.Merge(err) {
+			return err
+		}
 	}
-	return json.ValueOf(values), nerr.E
+	return nerr.E
 }
 
 // sortMap orders list based on value of key field for deterministic output.