VOL-3874: DevicePmConfig has to updated to DB in the rw-core only on success response from adapter
- also revert to using github.com/golang/protobuf version 1.3.2
Change-Id: I149c48a61a8858169bd0903e6092376796dae212
diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go
deleted file mode 100644
index 7c6c5a5..0000000
--- a/vendor/github.com/golang/protobuf/jsonpb/decode.go
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jsonpb
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "math"
- "reflect"
- "strconv"
- "strings"
- "time"
-
- "github.com/golang/protobuf/proto"
- "google.golang.org/protobuf/encoding/protojson"
- protoV2 "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/reflect/protoreflect"
- "google.golang.org/protobuf/reflect/protoregistry"
-)
-
-const wrapJSONUnmarshalV2 = false
-
-// UnmarshalNext unmarshals the next JSON object from d into m.
-func UnmarshalNext(d *json.Decoder, m proto.Message) error {
- return new(Unmarshaler).UnmarshalNext(d, m)
-}
-
-// Unmarshal unmarshals a JSON object from r into m.
-func Unmarshal(r io.Reader, m proto.Message) error {
- return new(Unmarshaler).Unmarshal(r, m)
-}
-
-// UnmarshalString unmarshals a JSON object from s into m.
-func UnmarshalString(s string, m proto.Message) error {
- return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
-}
-
-// Unmarshaler is a configurable object for converting from a JSON
-// representation to a protocol buffer object.
-type Unmarshaler struct {
- // AllowUnknownFields specifies whether to allow messages to contain
- // unknown JSON fields, as opposed to failing to unmarshal.
- AllowUnknownFields bool
-
- // AnyResolver is used to resolve the google.protobuf.Any well-known type.
- // If unset, the global registry is used by default.
- AnyResolver AnyResolver
-}
-
-// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
-// they are unmarshaled from JSON. Messages that implement this should also
-// implement JSONPBMarshaler so that the custom format can be produced.
-//
-// The JSON unmarshaling must follow the JSON to proto specification:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// Deprecated: Custom types should implement protobuf reflection instead.
-type JSONPBUnmarshaler interface {
- UnmarshalJSONPB(*Unmarshaler, []byte) error
-}
-
-// Unmarshal unmarshals a JSON object from r into m.
-func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
- return u.UnmarshalNext(json.NewDecoder(r), m)
-}
-
-// UnmarshalNext unmarshals the next JSON object from d into m.
-func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
- if m == nil {
- return errors.New("invalid nil message")
- }
-
- // Parse the next JSON object from the stream.
- raw := json.RawMessage{}
- if err := d.Decode(&raw); err != nil {
- return err
- }
-
- // Check for custom unmarshalers first since they may not properly
- // implement protobuf reflection that the logic below relies on.
- if jsu, ok := m.(JSONPBUnmarshaler); ok {
- return jsu.UnmarshalJSONPB(u, raw)
- }
-
- mr := proto.MessageReflect(m)
-
- // NOTE: For historical reasons, a top-level null is treated as a noop.
- // This is incorrect, but kept for compatibility.
- if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
- return nil
- }
-
- if wrapJSONUnmarshalV2 {
- // NOTE: If input message is non-empty, we need to preserve merge semantics
- // of the old jsonpb implementation. These semantics are not supported by
- // the protobuf JSON specification.
- isEmpty := true
- mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
- isEmpty = false // at least one iteration implies non-empty
- return false
- })
- if !isEmpty {
- // Perform unmarshaling into a newly allocated, empty message.
- mr = mr.New()
-
- // Use a defer to copy all unmarshaled fields into the original message.
- dst := proto.MessageReflect(m)
- defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
- dst.Set(fd, v)
- return true
- })
- }
-
- // Unmarshal using the v2 JSON unmarshaler.
- opts := protojson.UnmarshalOptions{
- DiscardUnknown: u.AllowUnknownFields,
- }
- if u.AnyResolver != nil {
- opts.Resolver = anyResolver{u.AnyResolver}
- }
- return opts.Unmarshal(raw, mr.Interface())
- } else {
- if err := u.unmarshalMessage(mr, raw); err != nil {
- return err
- }
- return protoV2.CheckInitialized(mr.Interface())
- }
-}
-
-func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
- md := m.Descriptor()
- fds := md.Fields()
-
- if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
- return nil
- }
-
- if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
- return jsu.UnmarshalJSONPB(u, in)
- }
-
- switch wellKnownType(md.FullName()) {
- case "Any":
- var jsonObject map[string]json.RawMessage
- if err := json.Unmarshal(in, &jsonObject); err != nil {
- return err
- }
-
- rawTypeURL, ok := jsonObject["@type"]
- if !ok {
- return errors.New("Any JSON doesn't have '@type'")
- }
- typeURL, err := unquoteString(string(rawTypeURL))
- if err != nil {
- return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
- }
- m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))
-
- var m2 protoreflect.Message
- if u.AnyResolver != nil {
- mi, err := u.AnyResolver.Resolve(typeURL)
- if err != nil {
- return err
- }
- m2 = proto.MessageReflect(mi)
- } else {
- mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
- if err != nil {
- if err == protoregistry.NotFound {
- return fmt.Errorf("could not resolve Any message type: %v", typeURL)
- }
- return err
- }
- m2 = mt.New()
- }
-
- if wellKnownType(m2.Descriptor().FullName()) != "" {
- rawValue, ok := jsonObject["value"]
- if !ok {
- return errors.New("Any JSON doesn't have 'value'")
- }
- if err := u.unmarshalMessage(m2, rawValue); err != nil {
- return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
- }
- } else {
- delete(jsonObject, "@type")
- rawJSON, err := json.Marshal(jsonObject)
- if err != nil {
- return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
- }
- if err = u.unmarshalMessage(m2, rawJSON); err != nil {
- return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
- }
- }
-
- rawWire, err := protoV2.Marshal(m2.Interface())
- if err != nil {
- return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
- }
- m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
- return nil
- case "BoolValue", "BytesValue", "StringValue",
- "Int32Value", "UInt32Value", "FloatValue",
- "Int64Value", "UInt64Value", "DoubleValue":
- fd := fds.ByNumber(1)
- v, err := u.unmarshalValue(m.NewField(fd), in, fd)
- if err != nil {
- return err
- }
- m.Set(fd, v)
- return nil
- case "Duration":
- v, err := unquoteString(string(in))
- if err != nil {
- return err
- }
- d, err := time.ParseDuration(v)
- if err != nil {
- return fmt.Errorf("bad Duration: %v", err)
- }
-
- sec := d.Nanoseconds() / 1e9
- nsec := d.Nanoseconds() % 1e9
- m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
- m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
- return nil
- case "Timestamp":
- v, err := unquoteString(string(in))
- if err != nil {
- return err
- }
- t, err := time.Parse(time.RFC3339Nano, v)
- if err != nil {
- return fmt.Errorf("bad Timestamp: %v", err)
- }
-
- sec := t.Unix()
- nsec := t.Nanosecond()
- m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
- m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
- return nil
- case "Value":
- switch {
- case string(in) == "null":
- m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
- case string(in) == "true":
- m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
- case string(in) == "false":
- m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
- case hasPrefixAndSuffix('"', in, '"'):
- s, err := unquoteString(string(in))
- if err != nil {
- return fmt.Errorf("unrecognized type for Value %q", in)
- }
- m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
- case hasPrefixAndSuffix('[', in, ']'):
- v := m.Mutable(fds.ByNumber(6))
- return u.unmarshalMessage(v.Message(), in)
- case hasPrefixAndSuffix('{', in, '}'):
- v := m.Mutable(fds.ByNumber(5))
- return u.unmarshalMessage(v.Message(), in)
- default:
- f, err := strconv.ParseFloat(string(in), 0)
- if err != nil {
- return fmt.Errorf("unrecognized type for Value %q", in)
- }
- m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
- }
- return nil
- case "ListValue":
- var jsonArray []json.RawMessage
- if err := json.Unmarshal(in, &jsonArray); err != nil {
- return fmt.Errorf("bad ListValue: %v", err)
- }
-
- lv := m.Mutable(fds.ByNumber(1)).List()
- for _, raw := range jsonArray {
- ve := lv.NewElement()
- if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
- return err
- }
- lv.Append(ve)
- }
- return nil
- case "Struct":
- var jsonObject map[string]json.RawMessage
- if err := json.Unmarshal(in, &jsonObject); err != nil {
- return fmt.Errorf("bad StructValue: %v", err)
- }
-
- mv := m.Mutable(fds.ByNumber(1)).Map()
- for key, raw := range jsonObject {
- kv := protoreflect.ValueOf(key).MapKey()
- vv := mv.NewValue()
- if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
- return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
- }
- mv.Set(kv, vv)
- }
- return nil
- }
-
- var jsonObject map[string]json.RawMessage
- if err := json.Unmarshal(in, &jsonObject); err != nil {
- return err
- }
-
- // Handle known fields.
- for i := 0; i < fds.Len(); i++ {
- fd := fds.Get(i)
- if fd.IsWeak() && fd.Message().IsPlaceholder() {
- continue // weak reference is not linked in
- }
-
- // Search for any raw JSON value associated with this field.
- var raw json.RawMessage
- name := string(fd.Name())
- if fd.Kind() == protoreflect.GroupKind {
- name = string(fd.Message().Name())
- }
- if v, ok := jsonObject[name]; ok {
- delete(jsonObject, name)
- raw = v
- }
- name = string(fd.JSONName())
- if v, ok := jsonObject[name]; ok {
- delete(jsonObject, name)
- raw = v
- }
-
- // Unmarshal the field value.
- if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
- continue
- }
- v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
- if err != nil {
- return err
- }
- m.Set(fd, v)
- }
-
- // Handle extension fields.
- for name, raw := range jsonObject {
- if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
- continue
- }
-
- // Resolve the extension field by name.
- xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
- xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
- if xt == nil && isMessageSet(md) {
- xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
- }
- if xt == nil {
- continue
- }
- delete(jsonObject, name)
- fd := xt.TypeDescriptor()
- if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
- return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
- }
-
- // Unmarshal the field value.
- if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
- continue
- }
- v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
- if err != nil {
- return err
- }
- m.Set(fd, v)
- }
-
- if !u.AllowUnknownFields && len(jsonObject) > 0 {
- for name := range jsonObject {
- return fmt.Errorf("unknown field %q in %v", name, md.FullName())
- }
- }
- return nil
-}
-
-func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
- if md := fd.Message(); md != nil {
- return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
- }
- return false
-}
-
-func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
- switch {
- case fd.IsList():
- var jsonArray []json.RawMessage
- if err := json.Unmarshal(in, &jsonArray); err != nil {
- return v, err
- }
- lv := v.List()
- for _, raw := range jsonArray {
- ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
- if err != nil {
- return v, err
- }
- lv.Append(ve)
- }
- return v, nil
- case fd.IsMap():
- var jsonObject map[string]json.RawMessage
- if err := json.Unmarshal(in, &jsonObject); err != nil {
- return v, err
- }
- kfd := fd.MapKey()
- vfd := fd.MapValue()
- mv := v.Map()
- for key, raw := range jsonObject {
- var kv protoreflect.MapKey
- if kfd.Kind() == protoreflect.StringKind {
- kv = protoreflect.ValueOf(key).MapKey()
- } else {
- v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
- if err != nil {
- return v, err
- }
- kv = v.MapKey()
- }
-
- vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
- if err != nil {
- return v, err
- }
- mv.Set(kv, vv)
- }
- return v, nil
- default:
- return u.unmarshalSingularValue(v, in, fd)
- }
-}
-
-var nonFinite = map[string]float64{
- `"NaN"`: math.NaN(),
- `"Infinity"`: math.Inf(+1),
- `"-Infinity"`: math.Inf(-1),
-}
-
-func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
- switch fd.Kind() {
- case protoreflect.BoolKind:
- return unmarshalValue(in, new(bool))
- case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
- return unmarshalValue(trimQuote(in), new(int32))
- case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
- return unmarshalValue(trimQuote(in), new(int64))
- case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
- return unmarshalValue(trimQuote(in), new(uint32))
- case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
- return unmarshalValue(trimQuote(in), new(uint64))
- case protoreflect.FloatKind:
- if f, ok := nonFinite[string(in)]; ok {
- return protoreflect.ValueOfFloat32(float32(f)), nil
- }
- return unmarshalValue(trimQuote(in), new(float32))
- case protoreflect.DoubleKind:
- if f, ok := nonFinite[string(in)]; ok {
- return protoreflect.ValueOfFloat64(float64(f)), nil
- }
- return unmarshalValue(trimQuote(in), new(float64))
- case protoreflect.StringKind:
- return unmarshalValue(in, new(string))
- case protoreflect.BytesKind:
- return unmarshalValue(in, new([]byte))
- case protoreflect.EnumKind:
- if hasPrefixAndSuffix('"', in, '"') {
- vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
- if vd == nil {
- return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
- }
- return protoreflect.ValueOfEnum(vd.Number()), nil
- }
- return unmarshalValue(in, new(protoreflect.EnumNumber))
- case protoreflect.MessageKind, protoreflect.GroupKind:
- err := u.unmarshalMessage(v.Message(), in)
- return v, err
- default:
- panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
- }
-}
-
-func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
- err := json.Unmarshal(in, v)
- return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
-}
-
-func unquoteString(in string) (out string, err error) {
- err = json.Unmarshal([]byte(in), &out)
- return out, err
-}
-
-func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
- if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
- return true
- }
- return false
-}
-
-// trimQuote is like unquoteString but simply strips surrounding quotes.
-// This is incorrect, but is behavior done by the legacy implementation.
-func trimQuote(in []byte) []byte {
- if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
- in = in[1 : len(in)-1]
- }
- return in
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go
deleted file mode 100644
index 7633019..0000000
--- a/vendor/github.com/golang/protobuf/jsonpb/encode.go
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jsonpb
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "math"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/golang/protobuf/proto"
- "google.golang.org/protobuf/encoding/protojson"
- protoV2 "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/reflect/protoreflect"
- "google.golang.org/protobuf/reflect/protoregistry"
-)
-
-const wrapJSONMarshalV2 = false
-
-// Marshaler is a configurable object for marshaling protocol buffer messages
-// to the specified JSON representation.
-type Marshaler struct {
- // OrigName specifies whether to use the original protobuf name for fields.
- OrigName bool
-
- // EnumsAsInts specifies whether to render enum values as integers,
- // as opposed to string values.
- EnumsAsInts bool
-
- // EmitDefaults specifies whether to render fields with zero values.
- EmitDefaults bool
-
- // Indent controls whether the output is compact or not.
- // If empty, the output is compact JSON. Otherwise, every JSON object
- // entry and JSON array value will be on its own line.
- // Each line will be preceded by repeated copies of Indent, where the
- // number of copies is the current indentation depth.
- Indent string
-
- // AnyResolver is used to resolve the google.protobuf.Any well-known type.
- // If unset, the global registry is used by default.
- AnyResolver AnyResolver
-}
-
-// JSONPBMarshaler is implemented by protobuf messages that customize the
-// way they are marshaled to JSON. Messages that implement this should also
-// implement JSONPBUnmarshaler so that the custom format can be parsed.
-//
-// The JSON marshaling must follow the proto to JSON specification:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// Deprecated: Custom types should implement protobuf reflection instead.
-type JSONPBMarshaler interface {
- MarshalJSONPB(*Marshaler) ([]byte, error)
-}
-
-// Marshal serializes a protobuf message as JSON into w.
-func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error {
- b, err := jm.marshal(m)
- if len(b) > 0 {
- if _, err := w.Write(b); err != nil {
- return err
- }
- }
- return err
-}
-
-// MarshalToString serializes a protobuf message as JSON in string form.
-func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) {
- b, err := jm.marshal(m)
- if err != nil {
- return "", err
- }
- return string(b), nil
-}
-
-func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) {
- v := reflect.ValueOf(m)
- if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
- return nil, errors.New("Marshal called with nil")
- }
-
- // Check for custom marshalers first since they may not properly
- // implement protobuf reflection that the logic below relies on.
- if jsm, ok := m.(JSONPBMarshaler); ok {
- return jsm.MarshalJSONPB(jm)
- }
-
- if wrapJSONMarshalV2 {
- opts := protojson.MarshalOptions{
- UseProtoNames: jm.OrigName,
- UseEnumNumbers: jm.EnumsAsInts,
- EmitUnpopulated: jm.EmitDefaults,
- Indent: jm.Indent,
- }
- if jm.AnyResolver != nil {
- opts.Resolver = anyResolver{jm.AnyResolver}
- }
- return opts.Marshal(proto.MessageReflect(m).Interface())
- } else {
- // Check for unpopulated required fields first.
- m2 := proto.MessageReflect(m)
- if err := protoV2.CheckInitialized(m2.Interface()); err != nil {
- return nil, err
- }
-
- w := jsonWriter{Marshaler: jm}
- err := w.marshalMessage(m2, "", "")
- return w.buf, err
- }
-}
-
-type jsonWriter struct {
- *Marshaler
- buf []byte
-}
-
-func (w *jsonWriter) write(s string) {
- w.buf = append(w.buf, s...)
-}
-
-func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error {
- if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok {
- b, err := jsm.MarshalJSONPB(w.Marshaler)
- if err != nil {
- return err
- }
- if typeURL != "" {
- // we are marshaling this object to an Any type
- var js map[string]*json.RawMessage
- if err = json.Unmarshal(b, &js); err != nil {
- return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err)
- }
- turl, err := json.Marshal(typeURL)
- if err != nil {
- return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
- }
- js["@type"] = (*json.RawMessage)(&turl)
- if b, err = json.Marshal(js); err != nil {
- return err
- }
- }
- w.write(string(b))
- return nil
- }
-
- md := m.Descriptor()
- fds := md.Fields()
-
- // Handle well-known types.
- const secondInNanos = int64(time.Second / time.Nanosecond)
- switch wellKnownType(md.FullName()) {
- case "Any":
- return w.marshalAny(m, indent)
- case "BoolValue", "BytesValue", "StringValue",
- "Int32Value", "UInt32Value", "FloatValue",
- "Int64Value", "UInt64Value", "DoubleValue":
- fd := fds.ByNumber(1)
- return w.marshalValue(fd, m.Get(fd), indent)
- case "Duration":
- // "Generated output always contains 0, 3, 6, or 9 fractional digits,
- // depending on required precision."
- s := m.Get(fds.ByNumber(1)).Int()
- ns := m.Get(fds.ByNumber(2)).Int()
- if ns <= -secondInNanos || ns >= secondInNanos {
- return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
- }
- if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
- return errors.New("signs of seconds and nanos do not match")
- }
- if s < 0 {
- ns = -ns
- }
- x := fmt.Sprintf("%d.%09d", s, ns)
- x = strings.TrimSuffix(x, "000")
- x = strings.TrimSuffix(x, "000")
- x = strings.TrimSuffix(x, ".000")
- w.write(fmt.Sprintf(`"%vs"`, x))
- return nil
- case "Timestamp":
- // "RFC 3339, where generated output will always be Z-normalized
- // and uses 0, 3, 6 or 9 fractional digits."
- s := m.Get(fds.ByNumber(1)).Int()
- ns := m.Get(fds.ByNumber(2)).Int()
- if ns < 0 || ns >= secondInNanos {
- return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
- }
- t := time.Unix(s, ns).UTC()
- // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
- x := t.Format("2006-01-02T15:04:05.000000000")
- x = strings.TrimSuffix(x, "000")
- x = strings.TrimSuffix(x, "000")
- x = strings.TrimSuffix(x, ".000")
- w.write(fmt.Sprintf(`"%vZ"`, x))
- return nil
- case "Value":
- // JSON value; which is a null, number, string, bool, object, or array.
- od := md.Oneofs().Get(0)
- fd := m.WhichOneof(od)
- if fd == nil {
- return errors.New("nil Value")
- }
- return w.marshalValue(fd, m.Get(fd), indent)
- case "Struct", "ListValue":
- // JSON object or array.
- fd := fds.ByNumber(1)
- return w.marshalValue(fd, m.Get(fd), indent)
- }
-
- w.write("{")
- if w.Indent != "" {
- w.write("\n")
- }
-
- firstField := true
- if typeURL != "" {
- if err := w.marshalTypeURL(indent, typeURL); err != nil {
- return err
- }
- firstField = false
- }
-
- for i := 0; i < fds.Len(); {
- fd := fds.Get(i)
- if od := fd.ContainingOneof(); od != nil {
- fd = m.WhichOneof(od)
- i += od.Fields().Len()
- if fd == nil {
- continue
- }
- } else {
- i++
- }
-
- v := m.Get(fd)
-
- if !m.Has(fd) {
- if !w.EmitDefaults || fd.ContainingOneof() != nil {
- continue
- }
- if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) {
- v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars
- }
- }
-
- if !firstField {
- w.writeComma()
- }
- if err := w.marshalField(fd, v, indent); err != nil {
- return err
- }
- firstField = false
- }
-
- // Handle proto2 extensions.
- if md.ExtensionRanges().Len() > 0 {
- // Collect a sorted list of all extension descriptor and values.
- type ext struct {
- desc protoreflect.FieldDescriptor
- val protoreflect.Value
- }
- var exts []ext
- m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
- if fd.IsExtension() {
- exts = append(exts, ext{fd, v})
- }
- return true
- })
- sort.Slice(exts, func(i, j int) bool {
- return exts[i].desc.Number() < exts[j].desc.Number()
- })
-
- for _, ext := range exts {
- if !firstField {
- w.writeComma()
- }
- if err := w.marshalField(ext.desc, ext.val, indent); err != nil {
- return err
- }
- firstField = false
- }
- }
-
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- }
- w.write("}")
- return nil
-}
-
-func (w *jsonWriter) writeComma() {
- if w.Indent != "" {
- w.write(",\n")
- } else {
- w.write(",")
- }
-}
-
-func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error {
- // "If the Any contains a value that has a special JSON mapping,
- // it will be converted as follows: {"@type": xxx, "value": yyy}.
- // Otherwise, the value will be converted into a JSON object,
- // and the "@type" field will be inserted to indicate the actual data type."
- md := m.Descriptor()
- typeURL := m.Get(md.Fields().ByNumber(1)).String()
- rawVal := m.Get(md.Fields().ByNumber(2)).Bytes()
-
- var m2 protoreflect.Message
- if w.AnyResolver != nil {
- mi, err := w.AnyResolver.Resolve(typeURL)
- if err != nil {
- return err
- }
- m2 = proto.MessageReflect(mi)
- } else {
- mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
- if err != nil {
- return err
- }
- m2 = mt.New()
- }
-
- if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil {
- return err
- }
-
- if wellKnownType(m2.Descriptor().FullName()) == "" {
- return w.marshalMessage(m2, indent, typeURL)
- }
-
- w.write("{")
- if w.Indent != "" {
- w.write("\n")
- }
- if err := w.marshalTypeURL(indent, typeURL); err != nil {
- return err
- }
- w.writeComma()
- if w.Indent != "" {
- w.write(indent)
- w.write(w.Indent)
- w.write(`"value": `)
- } else {
- w.write(`"value":`)
- }
- if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil {
- return err
- }
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- }
- w.write("}")
- return nil
-}
-
-func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error {
- if w.Indent != "" {
- w.write(indent)
- w.write(w.Indent)
- }
- w.write(`"@type":`)
- if w.Indent != "" {
- w.write(" ")
- }
- b, err := json.Marshal(typeURL)
- if err != nil {
- return err
- }
- w.write(string(b))
- return nil
-}
-
-// marshalField writes field description and value to the Writer.
-func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
- if w.Indent != "" {
- w.write(indent)
- w.write(w.Indent)
- }
- w.write(`"`)
- switch {
- case fd.IsExtension():
- // For message set, use the fname of the message as the extension name.
- name := string(fd.FullName())
- if isMessageSet(fd.ContainingMessage()) {
- name = strings.TrimSuffix(name, ".message_set_extension")
- }
-
- w.write("[" + name + "]")
- case w.OrigName:
- name := string(fd.Name())
- if fd.Kind() == protoreflect.GroupKind {
- name = string(fd.Message().Name())
- }
- w.write(name)
- default:
- w.write(string(fd.JSONName()))
- }
- w.write(`":`)
- if w.Indent != "" {
- w.write(" ")
- }
- return w.marshalValue(fd, v, indent)
-}
-
-func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
- switch {
- case fd.IsList():
- w.write("[")
- comma := ""
- lv := v.List()
- for i := 0; i < lv.Len(); i++ {
- w.write(comma)
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- w.write(w.Indent)
- w.write(w.Indent)
- }
- if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil {
- return err
- }
- comma = ","
- }
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- w.write(w.Indent)
- }
- w.write("]")
- return nil
- case fd.IsMap():
- kfd := fd.MapKey()
- vfd := fd.MapValue()
- mv := v.Map()
-
- // Collect a sorted list of all map keys and values.
- type entry struct{ key, val protoreflect.Value }
- var entries []entry
- mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
- entries = append(entries, entry{k.Value(), v})
- return true
- })
- sort.Slice(entries, func(i, j int) bool {
- switch kfd.Kind() {
- case protoreflect.BoolKind:
- return !entries[i].key.Bool() && entries[j].key.Bool()
- case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
- return entries[i].key.Int() < entries[j].key.Int()
- case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
- return entries[i].key.Uint() < entries[j].key.Uint()
- case protoreflect.StringKind:
- return entries[i].key.String() < entries[j].key.String()
- default:
- panic("invalid kind")
- }
- })
-
- w.write(`{`)
- comma := ""
- for _, entry := range entries {
- w.write(comma)
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- w.write(w.Indent)
- w.write(w.Indent)
- }
-
- s := fmt.Sprint(entry.key.Interface())
- b, err := json.Marshal(s)
- if err != nil {
- return err
- }
- w.write(string(b))
-
- w.write(`:`)
- if w.Indent != "" {
- w.write(` `)
- }
-
- if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil {
- return err
- }
- comma = ","
- }
- if w.Indent != "" {
- w.write("\n")
- w.write(indent)
- w.write(w.Indent)
- }
- w.write(`}`)
- return nil
- default:
- return w.marshalSingularValue(fd, v, indent)
- }
-}
-
-func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
- switch {
- case !v.IsValid():
- w.write("null")
- return nil
- case fd.Message() != nil:
- return w.marshalMessage(v.Message(), indent+w.Indent, "")
- case fd.Enum() != nil:
- if fd.Enum().FullName() == "google.protobuf.NullValue" {
- w.write("null")
- return nil
- }
-
- vd := fd.Enum().Values().ByNumber(v.Enum())
- if vd == nil || w.EnumsAsInts {
- w.write(strconv.Itoa(int(v.Enum())))
- } else {
- w.write(`"` + string(vd.Name()) + `"`)
- }
- return nil
- default:
- switch v.Interface().(type) {
- case float32, float64:
- switch {
- case math.IsInf(v.Float(), +1):
- w.write(`"Infinity"`)
- return nil
- case math.IsInf(v.Float(), -1):
- w.write(`"-Infinity"`)
- return nil
- case math.IsNaN(v.Float()):
- w.write(`"NaN"`)
- return nil
- }
- case int64, uint64:
- w.write(fmt.Sprintf(`"%d"`, v.Interface()))
- return nil
- }
-
- b, err := json.Marshal(v.Interface())
- if err != nil {
- return err
- }
- w.write(string(b))
- return nil
- }
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go
deleted file mode 100644
index 480e244..0000000
--- a/vendor/github.com/golang/protobuf/jsonpb/json.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package jsonpb provides functionality to marshal and unmarshal between a
-// protocol buffer message and JSON. It follows the specification at
-// https://developers.google.com/protocol-buffers/docs/proto3#json.
-//
-// Do not rely on the default behavior of the standard encoding/json package
-// when called on generated message types as it does not operate correctly.
-//
-// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson"
-// package instead.
-package jsonpb
-
-import (
- "github.com/golang/protobuf/proto"
- "google.golang.org/protobuf/reflect/protoreflect"
- "google.golang.org/protobuf/reflect/protoregistry"
- "google.golang.org/protobuf/runtime/protoimpl"
-)
-
-// AnyResolver takes a type URL, present in an Any message,
-// and resolves it into an instance of the associated message.
-type AnyResolver interface {
- Resolve(typeURL string) (proto.Message, error)
-}
-
-type anyResolver struct{ AnyResolver }
-
-func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
- return r.FindMessageByURL(string(message))
-}
-
-func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
- m, err := r.Resolve(url)
- if err != nil {
- return nil, err
- }
- return protoimpl.X.MessageTypeOf(m), nil
-}
-
-func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
- return protoregistry.GlobalTypes.FindExtensionByName(field)
-}
-
-func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
- return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
-}
-
-func wellKnownType(s protoreflect.FullName) string {
- if s.Parent() == "google.protobuf" {
- switch s.Name() {
- case "Empty", "Any",
- "BoolValue", "BytesValue", "StringValue",
- "Int32Value", "UInt32Value", "FloatValue",
- "Int64Value", "UInt64Value", "DoubleValue",
- "Duration", "Timestamp",
- "NullValue", "Struct", "Value", "ListValue":
- return string(s.Name())
- }
- }
- return ""
-}
-
-func isMessageSet(md protoreflect.MessageDescriptor) bool {
- ms, ok := md.(interface{ IsMessageSet() bool })
- return ok && ms.IsMessageSet()
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
new file mode 100644
index 0000000..e9cc202
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
@@ -0,0 +1,1284 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2015 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
+It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
+
+This package produces a different output than the standard "encoding/json" package,
+which does not operate correctly on protocol buffers.
+*/
+package jsonpb
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+
+ stpb "github.com/golang/protobuf/ptypes/struct"
+)
+
+const secondInNanos = int64(time.Second / time.Nanosecond)
+const maxSecondsInDuration = 315576000000
+
+// Marshaler is a configurable object for converting between
+// protocol buffer objects and a JSON representation for them.
+type Marshaler struct {
+ // Whether to render enum values as integers, as opposed to string values.
+ EnumsAsInts bool
+
+ // Whether to render fields with zero values.
+ EmitDefaults bool
+
+ // A string to indent each level by. The presence of this field will
+ // also cause a space to appear between the field separator and
+ // value, and for newlines to be appear between fields and array
+ // elements.
+ Indent string
+
+ // Whether to use the original (.proto) name for fields.
+ OrigName bool
+
+ // A custom URL resolver to use when marshaling Any messages to JSON.
+ // If unset, the default resolution strategy is to extract the
+ // fully-qualified type name from the type URL and pass that to
+ // proto.MessageType(string).
+ AnyResolver AnyResolver
+}
+
+// AnyResolver takes a type URL, present in an Any message, and resolves it into
+// an instance of the associated message.
+type AnyResolver interface {
+ Resolve(typeUrl string) (proto.Message, error)
+}
+
+func defaultResolveAny(typeUrl string) (proto.Message, error) {
+ // Only the part of typeUrl after the last slash is relevant.
+ mname := typeUrl
+ if slash := strings.LastIndex(mname, "/"); slash >= 0 {
+ mname = mname[slash+1:]
+ }
+ mt := proto.MessageType(mname)
+ if mt == nil {
+ return nil, fmt.Errorf("unknown message type %q", mname)
+ }
+ return reflect.New(mt.Elem()).Interface().(proto.Message), nil
+}
+
+// JSONPBMarshaler is implemented by protobuf messages that customize the
+// way they are marshaled to JSON. Messages that implement this should
+// also implement JSONPBUnmarshaler so that the custom format can be
+// parsed.
+//
+// The JSON marshaling must follow the proto to JSON specification:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+type JSONPBMarshaler interface {
+ MarshalJSONPB(*Marshaler) ([]byte, error)
+}
+
+// JSONPBUnmarshaler is implemented by protobuf messages that customize
+// the way they are unmarshaled from JSON. Messages that implement this
+// should also implement JSONPBMarshaler so that the custom format can be
+// produced.
+//
+// The JSON unmarshaling must follow the JSON to proto specification:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+type JSONPBUnmarshaler interface {
+ UnmarshalJSONPB(*Unmarshaler, []byte) error
+}
+
+// Marshal marshals a protocol buffer into JSON.
+func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
+ v := reflect.ValueOf(pb)
+ if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
+ return errors.New("Marshal called with nil")
+ }
+ // Check for unset required fields first.
+ if err := checkRequiredFields(pb); err != nil {
+ return err
+ }
+ writer := &errWriter{writer: out}
+ return m.marshalObject(writer, pb, "", "")
+}
+
+// MarshalToString converts a protocol buffer object to JSON string.
+func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
+ var buf bytes.Buffer
+ if err := m.Marshal(&buf, pb); err != nil {
+ return "", err
+ }
+ return buf.String(), nil
+}
+
+type int32Slice []int32
+
+var nonFinite = map[string]float64{
+ `"NaN"`: math.NaN(),
+ `"Infinity"`: math.Inf(1),
+ `"-Infinity"`: math.Inf(-1),
+}
+
+// For sorting extensions ids to ensure stable output.
+func (s int32Slice) Len() int { return len(s) }
+func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
+func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+type wkt interface {
+ XXX_WellKnownType() string
+}
+
+// marshalObject writes a struct to the Writer.
+func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error {
+ if jsm, ok := v.(JSONPBMarshaler); ok {
+ b, err := jsm.MarshalJSONPB(m)
+ if err != nil {
+ return err
+ }
+ if typeURL != "" {
+ // we are marshaling this object to an Any type
+ var js map[string]*json.RawMessage
+ if err = json.Unmarshal(b, &js); err != nil {
+ return fmt.Errorf("type %T produced invalid JSON: %v", v, err)
+ }
+ turl, err := json.Marshal(typeURL)
+ if err != nil {
+ return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
+ }
+ js["@type"] = (*json.RawMessage)(&turl)
+ if m.Indent != "" {
+ b, err = json.MarshalIndent(js, indent, m.Indent)
+ } else {
+ b, err = json.Marshal(js)
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ out.write(string(b))
+ return out.err
+ }
+
+ s := reflect.ValueOf(v).Elem()
+
+ // Handle well-known types.
+ if wkt, ok := v.(wkt); ok {
+ switch wkt.XXX_WellKnownType() {
+ case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
+ "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
+ // "Wrappers use the same representation in JSON
+ // as the wrapped primitive type, ..."
+ sprop := proto.GetProperties(s.Type())
+ return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
+ case "Any":
+ // Any is a bit more involved.
+ return m.marshalAny(out, v, indent)
+ case "Duration":
+ s, ns := s.Field(0).Int(), s.Field(1).Int()
+ if s < -maxSecondsInDuration || s > maxSecondsInDuration {
+ return fmt.Errorf("seconds out of range %v", s)
+ }
+ if ns <= -secondInNanos || ns >= secondInNanos {
+ return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
+ }
+ if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
+ return errors.New("signs of seconds and nanos do not match")
+ }
+ // Generated output always contains 0, 3, 6, or 9 fractional digits,
+ // depending on required precision, followed by the suffix "s".
+ f := "%d.%09d"
+ if ns < 0 {
+ ns = -ns
+ if s == 0 {
+ f = "-%d.%09d"
+ }
+ }
+ x := fmt.Sprintf(f, s, ns)
+ x = strings.TrimSuffix(x, "000")
+ x = strings.TrimSuffix(x, "000")
+ x = strings.TrimSuffix(x, ".000")
+ out.write(`"`)
+ out.write(x)
+ out.write(`s"`)
+ return out.err
+ case "Struct", "ListValue":
+ // Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice.
+ // TODO: pass the correct Properties if needed.
+ return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
+ case "Timestamp":
+ // "RFC 3339, where generated output will always be Z-normalized
+ // and uses 0, 3, 6 or 9 fractional digits."
+ s, ns := s.Field(0).Int(), s.Field(1).Int()
+ if ns < 0 || ns >= secondInNanos {
+ return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
+ }
+ t := time.Unix(s, ns).UTC()
+ // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
+ x := t.Format("2006-01-02T15:04:05.000000000")
+ x = strings.TrimSuffix(x, "000")
+ x = strings.TrimSuffix(x, "000")
+ x = strings.TrimSuffix(x, ".000")
+ out.write(`"`)
+ out.write(x)
+ out.write(`Z"`)
+ return out.err
+ case "Value":
+ // Value has a single oneof.
+ kind := s.Field(0)
+ if kind.IsNil() {
+ // "absence of any variant indicates an error"
+ return errors.New("nil Value")
+ }
+ // oneof -> *T -> T -> T.F
+ x := kind.Elem().Elem().Field(0)
+ // TODO: pass the correct Properties if needed.
+ return m.marshalValue(out, &proto.Properties{}, x, indent)
+ }
+ }
+
+ out.write("{")
+ if m.Indent != "" {
+ out.write("\n")
+ }
+
+ firstField := true
+
+ if typeURL != "" {
+ if err := m.marshalTypeURL(out, indent, typeURL); err != nil {
+ return err
+ }
+ firstField = false
+ }
+
+ for i := 0; i < s.NumField(); i++ {
+ value := s.Field(i)
+ valueField := s.Type().Field(i)
+ if strings.HasPrefix(valueField.Name, "XXX_") {
+ continue
+ }
+
+ // IsNil will panic on most value kinds.
+ switch value.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Interface:
+ if value.IsNil() {
+ continue
+ }
+ }
+
+ if !m.EmitDefaults {
+ switch value.Kind() {
+ case reflect.Bool:
+ if !value.Bool() {
+ continue
+ }
+ case reflect.Int32, reflect.Int64:
+ if value.Int() == 0 {
+ continue
+ }
+ case reflect.Uint32, reflect.Uint64:
+ if value.Uint() == 0 {
+ continue
+ }
+ case reflect.Float32, reflect.Float64:
+ if value.Float() == 0 {
+ continue
+ }
+ case reflect.String:
+ if value.Len() == 0 {
+ continue
+ }
+ case reflect.Map, reflect.Ptr, reflect.Slice:
+ if value.IsNil() {
+ continue
+ }
+ }
+ }
+
+ // Oneof fields need special handling.
+ if valueField.Tag.Get("protobuf_oneof") != "" {
+ // value is an interface containing &T{real_value}.
+ sv := value.Elem().Elem() // interface -> *T -> T
+ value = sv.Field(0)
+ valueField = sv.Type().Field(0)
+ }
+ prop := jsonProperties(valueField, m.OrigName)
+ if !firstField {
+ m.writeSep(out)
+ }
+ if err := m.marshalField(out, prop, value, indent); err != nil {
+ return err
+ }
+ firstField = false
+ }
+
+ // Handle proto2 extensions.
+ if ep, ok := v.(proto.Message); ok {
+ extensions := proto.RegisteredExtensions(v)
+ // Sort extensions for stable output.
+ ids := make([]int32, 0, len(extensions))
+ for id, desc := range extensions {
+ if !proto.HasExtension(ep, desc) {
+ continue
+ }
+ ids = append(ids, id)
+ }
+ sort.Sort(int32Slice(ids))
+ for _, id := range ids {
+ desc := extensions[id]
+ if desc == nil {
+ // unknown extension
+ continue
+ }
+ ext, extErr := proto.GetExtension(ep, desc)
+ if extErr != nil {
+ return extErr
+ }
+ value := reflect.ValueOf(ext)
+ var prop proto.Properties
+ prop.Parse(desc.Tag)
+ prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
+ if !firstField {
+ m.writeSep(out)
+ }
+ if err := m.marshalField(out, &prop, value, indent); err != nil {
+ return err
+ }
+ firstField = false
+ }
+
+ }
+
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ }
+ out.write("}")
+ return out.err
+}
+
+func (m *Marshaler) writeSep(out *errWriter) {
+ if m.Indent != "" {
+ out.write(",\n")
+ } else {
+ out.write(",")
+ }
+}
+
+func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error {
+ // "If the Any contains a value that has a special JSON mapping,
+ // it will be converted as follows: {"@type": xxx, "value": yyy}.
+ // Otherwise, the value will be converted into a JSON object,
+ // and the "@type" field will be inserted to indicate the actual data type."
+ v := reflect.ValueOf(any).Elem()
+ turl := v.Field(0).String()
+ val := v.Field(1).Bytes()
+
+ var msg proto.Message
+ var err error
+ if m.AnyResolver != nil {
+ msg, err = m.AnyResolver.Resolve(turl)
+ } else {
+ msg, err = defaultResolveAny(turl)
+ }
+ if err != nil {
+ return err
+ }
+
+ if err := proto.Unmarshal(val, msg); err != nil {
+ return err
+ }
+
+ if _, ok := msg.(wkt); ok {
+ out.write("{")
+ if m.Indent != "" {
+ out.write("\n")
+ }
+ if err := m.marshalTypeURL(out, indent, turl); err != nil {
+ return err
+ }
+ m.writeSep(out)
+ if m.Indent != "" {
+ out.write(indent)
+ out.write(m.Indent)
+ out.write(`"value": `)
+ } else {
+ out.write(`"value":`)
+ }
+ if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil {
+ return err
+ }
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ }
+ out.write("}")
+ return out.err
+ }
+
+ return m.marshalObject(out, msg, indent, turl)
+}
+
+func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error {
+ if m.Indent != "" {
+ out.write(indent)
+ out.write(m.Indent)
+ }
+ out.write(`"@type":`)
+ if m.Indent != "" {
+ out.write(" ")
+ }
+ b, err := json.Marshal(typeURL)
+ if err != nil {
+ return err
+ }
+ out.write(string(b))
+ return out.err
+}
+
+// marshalField writes field description and value to the Writer.
+func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
+ if m.Indent != "" {
+ out.write(indent)
+ out.write(m.Indent)
+ }
+ out.write(`"`)
+ out.write(prop.JSONName)
+ out.write(`":`)
+ if m.Indent != "" {
+ out.write(" ")
+ }
+ if err := m.marshalValue(out, prop, v, indent); err != nil {
+ return err
+ }
+ return nil
+}
+
+// marshalValue writes the value to the Writer.
+func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
+ var err error
+ v = reflect.Indirect(v)
+
+ // Handle nil pointer
+ if v.Kind() == reflect.Invalid {
+ out.write("null")
+ return out.err
+ }
+
+ // Handle repeated elements.
+ if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
+ out.write("[")
+ comma := ""
+ for i := 0; i < v.Len(); i++ {
+ sliceVal := v.Index(i)
+ out.write(comma)
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ out.write(m.Indent)
+ out.write(m.Indent)
+ }
+ if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil {
+ return err
+ }
+ comma = ","
+ }
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ out.write(m.Indent)
+ }
+ out.write("]")
+ return out.err
+ }
+
+ // Handle well-known types.
+ // Most are handled up in marshalObject (because 99% are messages).
+ if wkt, ok := v.Interface().(wkt); ok {
+ switch wkt.XXX_WellKnownType() {
+ case "NullValue":
+ out.write("null")
+ return out.err
+ }
+ }
+
+ // Handle enumerations.
+ if !m.EnumsAsInts && prop.Enum != "" {
+ // Unknown enum values will are stringified by the proto library as their
+ // value. Such values should _not_ be quoted or they will be interpreted
+ // as an enum string instead of their value.
+ enumStr := v.Interface().(fmt.Stringer).String()
+ var valStr string
+ if v.Kind() == reflect.Ptr {
+ valStr = strconv.Itoa(int(v.Elem().Int()))
+ } else {
+ valStr = strconv.Itoa(int(v.Int()))
+ }
+ isKnownEnum := enumStr != valStr
+ if isKnownEnum {
+ out.write(`"`)
+ }
+ out.write(enumStr)
+ if isKnownEnum {
+ out.write(`"`)
+ }
+ return out.err
+ }
+
+ // Handle nested messages.
+ if v.Kind() == reflect.Struct {
+ return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "")
+ }
+
+ // Handle maps.
+ // Since Go randomizes map iteration, we sort keys for stable output.
+ if v.Kind() == reflect.Map {
+ out.write(`{`)
+ keys := v.MapKeys()
+ sort.Sort(mapKeys(keys))
+ for i, k := range keys {
+ if i > 0 {
+ out.write(`,`)
+ }
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ out.write(m.Indent)
+ out.write(m.Indent)
+ }
+
+ // TODO handle map key prop properly
+ b, err := json.Marshal(k.Interface())
+ if err != nil {
+ return err
+ }
+ s := string(b)
+
+ // If the JSON is not a string value, encode it again to make it one.
+ if !strings.HasPrefix(s, `"`) {
+ b, err := json.Marshal(s)
+ if err != nil {
+ return err
+ }
+ s = string(b)
+ }
+
+ out.write(s)
+ out.write(`:`)
+ if m.Indent != "" {
+ out.write(` `)
+ }
+
+ vprop := prop
+ if prop != nil && prop.MapValProp != nil {
+ vprop = prop.MapValProp
+ }
+ if err := m.marshalValue(out, vprop, v.MapIndex(k), indent+m.Indent); err != nil {
+ return err
+ }
+ }
+ if m.Indent != "" {
+ out.write("\n")
+ out.write(indent)
+ out.write(m.Indent)
+ }
+ out.write(`}`)
+ return out.err
+ }
+
+ // Handle non-finite floats, e.g. NaN, Infinity and -Infinity.
+ if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
+ f := v.Float()
+ var sval string
+ switch {
+ case math.IsInf(f, 1):
+ sval = `"Infinity"`
+ case math.IsInf(f, -1):
+ sval = `"-Infinity"`
+ case math.IsNaN(f):
+ sval = `"NaN"`
+ }
+ if sval != "" {
+ out.write(sval)
+ return out.err
+ }
+ }
+
+ // Default handling defers to the encoding/json library.
+ b, err := json.Marshal(v.Interface())
+ if err != nil {
+ return err
+ }
+ needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
+ if needToQuote {
+ out.write(`"`)
+ }
+ out.write(string(b))
+ if needToQuote {
+ out.write(`"`)
+ }
+ return out.err
+}
+
+// Unmarshaler is a configurable object for converting from a JSON
+// representation to a protocol buffer object.
+type Unmarshaler struct {
+ // Whether to allow messages to contain unknown fields, as opposed to
+ // failing to unmarshal.
+ AllowUnknownFields bool
+
+ // A custom URL resolver to use when unmarshaling Any messages from JSON.
+ // If unset, the default resolution strategy is to extract the
+ // fully-qualified type name from the type URL and pass that to
+ // proto.MessageType(string).
+ AnyResolver AnyResolver
+}
+
+// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
+// This function is lenient and will decode any options permutations of the
+// related Marshaler.
+func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
+ inputValue := json.RawMessage{}
+ if err := dec.Decode(&inputValue); err != nil {
+ return err
+ }
+ if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil {
+ return err
+ }
+ return checkRequiredFields(pb)
+}
+
+// Unmarshal unmarshals a JSON object stream into a protocol
+// buffer. This function is lenient and will decode any options
+// permutations of the related Marshaler.
+func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error {
+ dec := json.NewDecoder(r)
+ return u.UnmarshalNext(dec, pb)
+}
+
+// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
+// This function is lenient and will decode any options permutations of the
+// related Marshaler.
+func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
+ return new(Unmarshaler).UnmarshalNext(dec, pb)
+}
+
+// Unmarshal unmarshals a JSON object stream into a protocol
+// buffer. This function is lenient and will decode any options
+// permutations of the related Marshaler.
+func Unmarshal(r io.Reader, pb proto.Message) error {
+ return new(Unmarshaler).Unmarshal(r, pb)
+}
+
+// UnmarshalString will populate the fields of a protocol buffer based
+// on a JSON string. This function is lenient and will decode any options
+// permutations of the related Marshaler.
+func UnmarshalString(str string, pb proto.Message) error {
+ return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb)
+}
+
+// unmarshalValue converts/copies a value into the target.
+// prop may be nil.
+func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
+ targetType := target.Type()
+
+ // Allocate memory for pointer fields.
+ if targetType.Kind() == reflect.Ptr {
+ // If input value is "null" and target is a pointer type, then the field should be treated as not set
+ // UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue.
+ _, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler)
+ if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler {
+ return nil
+ }
+ target.Set(reflect.New(targetType.Elem()))
+
+ return u.unmarshalValue(target.Elem(), inputValue, prop)
+ }
+
+ if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok {
+ return jsu.UnmarshalJSONPB(u, []byte(inputValue))
+ }
+
+ // Handle well-known types that are not pointers.
+ if w, ok := target.Addr().Interface().(wkt); ok {
+ switch w.XXX_WellKnownType() {
+ case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
+ "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
+ return u.unmarshalValue(target.Field(0), inputValue, prop)
+ case "Any":
+ // Use json.RawMessage pointer type instead of value to support pre-1.8 version.
+ // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see
+ // https://github.com/golang/go/issues/14493
+ var jsonFields map[string]*json.RawMessage
+ if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
+ return err
+ }
+
+ val, ok := jsonFields["@type"]
+ if !ok || val == nil {
+ return errors.New("Any JSON doesn't have '@type'")
+ }
+
+ var turl string
+ if err := json.Unmarshal([]byte(*val), &turl); err != nil {
+ return fmt.Errorf("can't unmarshal Any's '@type': %q", *val)
+ }
+ target.Field(0).SetString(turl)
+
+ var m proto.Message
+ var err error
+ if u.AnyResolver != nil {
+ m, err = u.AnyResolver.Resolve(turl)
+ } else {
+ m, err = defaultResolveAny(turl)
+ }
+ if err != nil {
+ return err
+ }
+
+ if _, ok := m.(wkt); ok {
+ val, ok := jsonFields["value"]
+ if !ok {
+ return errors.New("Any JSON doesn't have 'value'")
+ }
+
+ if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil {
+ return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
+ }
+ } else {
+ delete(jsonFields, "@type")
+ nestedProto, err := json.Marshal(jsonFields)
+ if err != nil {
+ return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
+ }
+
+ if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil {
+ return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
+ }
+ }
+
+ b, err := proto.Marshal(m)
+ if err != nil {
+ return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err)
+ }
+ target.Field(1).SetBytes(b)
+
+ return nil
+ case "Duration":
+ unq, err := unquote(string(inputValue))
+ if err != nil {
+ return err
+ }
+
+ d, err := time.ParseDuration(unq)
+ if err != nil {
+ return fmt.Errorf("bad Duration: %v", err)
+ }
+
+ ns := d.Nanoseconds()
+ s := ns / 1e9
+ ns %= 1e9
+ target.Field(0).SetInt(s)
+ target.Field(1).SetInt(ns)
+ return nil
+ case "Timestamp":
+ unq, err := unquote(string(inputValue))
+ if err != nil {
+ return err
+ }
+
+ t, err := time.Parse(time.RFC3339Nano, unq)
+ if err != nil {
+ return fmt.Errorf("bad Timestamp: %v", err)
+ }
+
+ target.Field(0).SetInt(t.Unix())
+ target.Field(1).SetInt(int64(t.Nanosecond()))
+ return nil
+ case "Struct":
+ var m map[string]json.RawMessage
+ if err := json.Unmarshal(inputValue, &m); err != nil {
+ return fmt.Errorf("bad StructValue: %v", err)
+ }
+
+ target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{}))
+ for k, jv := range m {
+ pv := &stpb.Value{}
+ if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil {
+ return fmt.Errorf("bad value in StructValue for key %q: %v", k, err)
+ }
+ target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv))
+ }
+ return nil
+ case "ListValue":
+ var s []json.RawMessage
+ if err := json.Unmarshal(inputValue, &s); err != nil {
+ return fmt.Errorf("bad ListValue: %v", err)
+ }
+
+ target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s))))
+ for i, sv := range s {
+ if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil {
+ return err
+ }
+ }
+ return nil
+ case "Value":
+ ivStr := string(inputValue)
+ if ivStr == "null" {
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{}))
+ } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil {
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v}))
+ } else if v, err := unquote(ivStr); err == nil {
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v}))
+ } else if v, err := strconv.ParseBool(ivStr); err == nil {
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v}))
+ } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil {
+ lv := &stpb.ListValue{}
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv}))
+ return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop)
+ } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil {
+ sv := &stpb.Struct{}
+ target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv}))
+ return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop)
+ } else {
+ return fmt.Errorf("unrecognized type for Value %q", ivStr)
+ }
+ return nil
+ }
+ }
+
+ // Handle enums, which have an underlying type of int32,
+ // and may appear as strings.
+ // The case of an enum appearing as a number is handled
+ // at the bottom of this function.
+ if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
+ vmap := proto.EnumValueMap(prop.Enum)
+ // Don't need to do unquoting; valid enum names
+ // are from a limited character set.
+ s := inputValue[1 : len(inputValue)-1]
+ n, ok := vmap[string(s)]
+ if !ok {
+ return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
+ }
+ if target.Kind() == reflect.Ptr { // proto2
+ target.Set(reflect.New(targetType.Elem()))
+ target = target.Elem()
+ }
+ if targetType.Kind() != reflect.Int32 {
+ return fmt.Errorf("invalid target %q for enum %s", targetType.Kind(), prop.Enum)
+ }
+ target.SetInt(int64(n))
+ return nil
+ }
+
+ // Handle nested messages.
+ if targetType.Kind() == reflect.Struct {
+ var jsonFields map[string]json.RawMessage
+ if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
+ return err
+ }
+
+ consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
+ // Be liberal in what names we accept; both orig_name and camelName are okay.
+ fieldNames := acceptedJSONFieldNames(prop)
+
+ vOrig, okOrig := jsonFields[fieldNames.orig]
+ vCamel, okCamel := jsonFields[fieldNames.camel]
+ if !okOrig && !okCamel {
+ return nil, false
+ }
+ // If, for some reason, both are present in the data, favour the camelName.
+ var raw json.RawMessage
+ if okOrig {
+ raw = vOrig
+ delete(jsonFields, fieldNames.orig)
+ }
+ if okCamel {
+ raw = vCamel
+ delete(jsonFields, fieldNames.camel)
+ }
+ return raw, true
+ }
+
+ sprops := proto.GetProperties(targetType)
+ for i := 0; i < target.NumField(); i++ {
+ ft := target.Type().Field(i)
+ if strings.HasPrefix(ft.Name, "XXX_") {
+ continue
+ }
+
+ valueForField, ok := consumeField(sprops.Prop[i])
+ if !ok {
+ continue
+ }
+
+ if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
+ return err
+ }
+ }
+ // Check for any oneof fields.
+ if len(jsonFields) > 0 {
+ for _, oop := range sprops.OneofTypes {
+ raw, ok := consumeField(oop.Prop)
+ if !ok {
+ continue
+ }
+ nv := reflect.New(oop.Type.Elem())
+ target.Field(oop.Field).Set(nv)
+ if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
+ return err
+ }
+ }
+ }
+ // Handle proto2 extensions.
+ if len(jsonFields) > 0 {
+ if ep, ok := target.Addr().Interface().(proto.Message); ok {
+ for _, ext := range proto.RegisteredExtensions(ep) {
+ name := fmt.Sprintf("[%s]", ext.Name)
+ raw, ok := jsonFields[name]
+ if !ok {
+ continue
+ }
+ delete(jsonFields, name)
+ nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem())
+ if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil {
+ return err
+ }
+ if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ if !u.AllowUnknownFields && len(jsonFields) > 0 {
+ // Pick any field to be the scapegoat.
+ var f string
+ for fname := range jsonFields {
+ f = fname
+ break
+ }
+ return fmt.Errorf("unknown field %q in %v", f, targetType)
+ }
+ return nil
+ }
+
+ // Handle arrays (which aren't encoded bytes)
+ if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 {
+ var slc []json.RawMessage
+ if err := json.Unmarshal(inputValue, &slc); err != nil {
+ return err
+ }
+ if slc != nil {
+ l := len(slc)
+ target.Set(reflect.MakeSlice(targetType, l, l))
+ for i := 0; i < l; i++ {
+ if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ }
+
+ // Handle maps (whose keys are always strings)
+ if targetType.Kind() == reflect.Map {
+ var mp map[string]json.RawMessage
+ if err := json.Unmarshal(inputValue, &mp); err != nil {
+ return err
+ }
+ if mp != nil {
+ target.Set(reflect.MakeMap(targetType))
+ for ks, raw := range mp {
+ // Unmarshal map key. The core json library already decoded the key into a
+ // string, so we handle that specially. Other types were quoted post-serialization.
+ var k reflect.Value
+ if targetType.Key().Kind() == reflect.String {
+ k = reflect.ValueOf(ks)
+ } else {
+ k = reflect.New(targetType.Key()).Elem()
+ var kprop *proto.Properties
+ if prop != nil && prop.MapKeyProp != nil {
+ kprop = prop.MapKeyProp
+ }
+ if err := u.unmarshalValue(k, json.RawMessage(ks), kprop); err != nil {
+ return err
+ }
+ }
+
+ // Unmarshal map value.
+ v := reflect.New(targetType.Elem()).Elem()
+ var vprop *proto.Properties
+ if prop != nil && prop.MapValProp != nil {
+ vprop = prop.MapValProp
+ }
+ if err := u.unmarshalValue(v, raw, vprop); err != nil {
+ return err
+ }
+ target.SetMapIndex(k, v)
+ }
+ }
+ return nil
+ }
+
+ // Non-finite numbers can be encoded as strings.
+ isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
+ if isFloat {
+ if num, ok := nonFinite[string(inputValue)]; ok {
+ target.SetFloat(num)
+ return nil
+ }
+ }
+
+ // integers & floats can be encoded as strings. In this case we drop
+ // the quotes and proceed as normal.
+ isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 ||
+ targetType.Kind() == reflect.Int32 || targetType.Kind() == reflect.Uint32 ||
+ targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
+ if isNum && strings.HasPrefix(string(inputValue), `"`) {
+ inputValue = inputValue[1 : len(inputValue)-1]
+ }
+
+ // Use the encoding/json for parsing other value types.
+ return json.Unmarshal(inputValue, target.Addr().Interface())
+}
+
+func unquote(s string) (string, error) {
+ var ret string
+ err := json.Unmarshal([]byte(s), &ret)
+ return ret, err
+}
+
+// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
+func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
+ var prop proto.Properties
+ prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
+ if origName || prop.JSONName == "" {
+ prop.JSONName = prop.OrigName
+ }
+ return &prop
+}
+
+type fieldNames struct {
+ orig, camel string
+}
+
+func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
+ opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
+ if prop.JSONName != "" {
+ opts.camel = prop.JSONName
+ }
+ return opts
+}
+
+// Writer wrapper inspired by https://blog.golang.org/errors-are-values
+type errWriter struct {
+ writer io.Writer
+ err error
+}
+
+func (w *errWriter) write(str string) {
+ if w.err != nil {
+ return
+ }
+ _, w.err = w.writer.Write([]byte(str))
+}
+
+// Map fields may have key types of non-float scalars, strings and enums.
+// The easiest way to sort them in some deterministic order is to use fmt.
+// If this turns out to be inefficient we can always consider other options,
+// such as doing a Schwartzian transform.
+//
+// Numeric keys are sorted in numeric order per
+// https://developers.google.com/protocol-buffers/docs/proto#maps.
+type mapKeys []reflect.Value
+
+func (s mapKeys) Len() int { return len(s) }
+func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s mapKeys) Less(i, j int) bool {
+ if k := s[i].Kind(); k == s[j].Kind() {
+ switch k {
+ case reflect.String:
+ return s[i].String() < s[j].String()
+ case reflect.Int32, reflect.Int64:
+ return s[i].Int() < s[j].Int()
+ case reflect.Uint32, reflect.Uint64:
+ return s[i].Uint() < s[j].Uint()
+ }
+ }
+ return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
+}
+
+// checkRequiredFields returns an error if any required field in the given proto message is not set.
+// This function is used by both Marshal and Unmarshal. While required fields only exist in a
+// proto2 message, a proto3 message can contain proto2 message(s).
+func checkRequiredFields(pb proto.Message) error {
+ // Most well-known type messages do not contain required fields. The "Any" type may contain
+ // a message that has required fields.
+ //
+ // When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value
+ // field in order to transform that into JSON, and that should have returned an error if a
+ // required field is not set in the embedded message.
+ //
+ // When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the
+ // embedded message to store the serialized message in Any.Value field, and that should have
+ // returned an error if a required field is not set.
+ if _, ok := pb.(wkt); ok {
+ return nil
+ }
+
+ v := reflect.ValueOf(pb)
+ // Skip message if it is not a struct pointer.
+ if v.Kind() != reflect.Ptr {
+ return nil
+ }
+ v = v.Elem()
+ if v.Kind() != reflect.Struct {
+ return nil
+ }
+
+ for i := 0; i < v.NumField(); i++ {
+ field := v.Field(i)
+ sfield := v.Type().Field(i)
+
+ if sfield.PkgPath != "" {
+ // blank PkgPath means the field is exported; skip if not exported
+ continue
+ }
+
+ if strings.HasPrefix(sfield.Name, "XXX_") {
+ continue
+ }
+
+ // Oneof field is an interface implemented by wrapper structs containing the actual oneof
+ // field, i.e. an interface containing &T{real_value}.
+ if sfield.Tag.Get("protobuf_oneof") != "" {
+ if field.Kind() != reflect.Interface {
+ continue
+ }
+ v := field.Elem()
+ if v.Kind() != reflect.Ptr || v.IsNil() {
+ continue
+ }
+ v = v.Elem()
+ if v.Kind() != reflect.Struct || v.NumField() < 1 {
+ continue
+ }
+ field = v.Field(0)
+ sfield = v.Type().Field(0)
+ }
+
+ protoTag := sfield.Tag.Get("protobuf")
+ if protoTag == "" {
+ continue
+ }
+ var prop proto.Properties
+ prop.Init(sfield.Type, sfield.Name, protoTag, &sfield)
+
+ switch field.Kind() {
+ case reflect.Map:
+ if field.IsNil() {
+ continue
+ }
+ // Check each map value.
+ keys := field.MapKeys()
+ for _, k := range keys {
+ v := field.MapIndex(k)
+ if err := checkRequiredFieldsInValue(v); err != nil {
+ return err
+ }
+ }
+ case reflect.Slice:
+ // Handle non-repeated type, e.g. bytes.
+ if !prop.Repeated {
+ if prop.Required && field.IsNil() {
+ return fmt.Errorf("required field %q is not set", prop.Name)
+ }
+ continue
+ }
+
+ // Handle repeated type.
+ if field.IsNil() {
+ continue
+ }
+ // Check each slice item.
+ for i := 0; i < field.Len(); i++ {
+ v := field.Index(i)
+ if err := checkRequiredFieldsInValue(v); err != nil {
+ return err
+ }
+ }
+ case reflect.Ptr:
+ if field.IsNil() {
+ if prop.Required {
+ return fmt.Errorf("required field %q is not set", prop.Name)
+ }
+ continue
+ }
+ if err := checkRequiredFieldsInValue(field); err != nil {
+ return err
+ }
+ }
+ }
+
+ // Handle proto2 extensions.
+ for _, ext := range proto.RegisteredExtensions(pb) {
+ if !proto.HasExtension(pb, ext) {
+ continue
+ }
+ ep, err := proto.GetExtension(pb, ext)
+ if err != nil {
+ return err
+ }
+ err = checkRequiredFieldsInValue(reflect.ValueOf(ep))
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func checkRequiredFieldsInValue(v reflect.Value) error {
+ if pm, ok := v.Interface().(proto.Message); ok {
+ return checkRequiredFields(pm)
+ }
+ return nil
+}