encoding/jsonpb: add support for unmarshaling Any

Also added json.Decoder.Clone API for unmarshaling Any to look
ahead remaining bytes for @type field.

Change-Id: I2f803743534dfb64f9092d716805b115faa5975a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170102
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/encoding/json/decode.go b/internal/encoding/json/decode.go
index a9262b8..0ee6c85 100644
--- a/internal/encoding/json/decode.go
+++ b/internal/encoding/json/decode.go
@@ -25,7 +25,8 @@
 
 // Decoder is a token-based JSON decoder.
 type Decoder struct {
-	// lastCall is last method called, eiterh readCall or peekCall.
+	// lastCall is last method called, either readCall or peekCall.
+	// Initial value is readCall.
 	lastCall call
 
 	// value contains the last read value.
@@ -88,7 +89,7 @@
 
 	case Bool, Number:
 		if !d.isValueNext() {
-			return Value{}, d.newSyntaxError("unexpected value %v", value)
+			return Value{}, d.newSyntaxError("unexpected value %v", value.Raw())
 		}
 
 	case String:
@@ -97,7 +98,7 @@
 		}
 		// Check if this is for an object name.
 		if d.value.typ&(StartObject|comma) == 0 {
-			return Value{}, d.newSyntaxError("unexpected value %q", value)
+			return Value{}, d.newSyntaxError("unexpected value %v", value.Raw())
 		}
 		d.in = d.in[n:]
 		d.consume(0)
@@ -109,7 +110,7 @@
 
 	case StartObject, StartArray:
 		if !d.isValueNext() {
-			return Value{}, d.newSyntaxError("unexpected character %v", value)
+			return Value{}, d.newSyntaxError("unexpected character %v", value.Raw())
 		}
 		d.startStack = append(d.startStack, value.typ)
 
@@ -323,6 +324,14 @@
 	}
 }
 
+// Clone returns a copy of the Decoder for use in reading ahead the next JSON
+// object, array or other values without affecting current Decoder.
+func (d *Decoder) Clone() *Decoder {
+	ret := *d
+	ret.startStack = append([]Type(nil), ret.startStack...)
+	return &ret
+}
+
 // Value contains a JSON type and value parsed from calling Decoder.Read.
 // For JSON boolean and string, it holds the converted value in boo and str
 // fields respectively. For JSON number, input field holds a valid number which
@@ -377,6 +386,11 @@
 	return v.str, nil
 }
 
+// Raw returns the read value in string.
+func (v Value) Raw() string {
+	return string(v.input)
+}
+
 // Float returns the floating-point number if token is Number, else it will
 // return an error.
 //
diff --git a/internal/encoding/json/decode_test.go b/internal/encoding/json/decode_test.go
index dc7f25f..b402b0a 100644
--- a/internal/encoding/json/decode_test.go
+++ b/internal/encoding/json/decode_test.go
@@ -1087,3 +1087,37 @@
 		t.Errorf("want#%d: %v got %v, want %v", wantIdx, value, got, want.V)
 	}
 }
+
+func TestClone(t *testing.T) {
+	input := `{"outer":{"str":"hello", "number": 123}}`
+	dec := json.NewDecoder([]byte(input))
+
+	// Clone at the start should produce the same reads as the original.
+	clone := dec.Clone()
+	compareDecoders(t, dec, clone)
+
+	// Advance to inner object, clone and compare again.
+	dec.Read() // Read StartObject.
+	dec.Read() // Read Name.
+	clone = dec.Clone()
+	compareDecoders(t, dec, clone)
+}
+
+func compareDecoders(t *testing.T, d1 *json.Decoder, d2 *json.Decoder) {
+	for {
+		v1, err1 := d1.Read()
+		v2, err2 := d2.Read()
+		if v1.Type() != v2.Type() {
+			t.Errorf("cloned decoder: got Type %v, want %v", v2.Type(), v1.Type())
+		}
+		if v1.Raw() != v2.Raw() {
+			t.Errorf("cloned decoder: got Raw %v, want %v", v2.Raw(), v1.Raw())
+		}
+		if err1 != err2 {
+			t.Errorf("cloned decoder: got error %v, want %v", err2, err1)
+		}
+		if v1.Type() == json.EOF {
+			break
+		}
+	}
+}