Committing vendored dependencies and generated protos
Change-Id: I349c149b513d9de7d9f60bde2c954a939da2fc54
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/json.go b/vendor/github.com/jhump/protoreflect/dynamic/json.go
new file mode 100644
index 0000000..7dfae09
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/json.go
@@ -0,0 +1,1238 @@
+package dynamic
+
+// JSON marshalling and unmarshalling for dynamic messages
+
+import (
+ "bytes"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/golang/protobuf/jsonpb"
+ "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ // link in the well-known-types that have a special JSON format
+ _ "github.com/golang/protobuf/ptypes/any"
+ _ "github.com/golang/protobuf/ptypes/duration"
+ _ "github.com/golang/protobuf/ptypes/empty"
+ _ "github.com/golang/protobuf/ptypes/struct"
+ _ "github.com/golang/protobuf/ptypes/timestamp"
+ _ "github.com/golang/protobuf/ptypes/wrappers"
+
+ "github.com/jhump/protoreflect/desc"
+)
+
+var wellKnownTypeNames = map[string]struct{}{
+ "google.protobuf.Any": {},
+ "google.protobuf.Empty": {},
+ "google.protobuf.Duration": {},
+ "google.protobuf.Timestamp": {},
+ // struct.proto
+ "google.protobuf.Struct": {},
+ "google.protobuf.Value": {},
+ "google.protobuf.ListValue": {},
+ // wrappers.proto
+ "google.protobuf.DoubleValue": {},
+ "google.protobuf.FloatValue": {},
+ "google.protobuf.Int64Value": {},
+ "google.protobuf.UInt64Value": {},
+ "google.protobuf.Int32Value": {},
+ "google.protobuf.UInt32Value": {},
+ "google.protobuf.BoolValue": {},
+ "google.protobuf.StringValue": {},
+ "google.protobuf.BytesValue": {},
+}
+
+// MarshalJSON serializes this message to bytes in JSON format, returning an
+// error if the operation fails. The resulting bytes will be a valid UTF8
+// string.
+//
+// This method uses a compact form: no newlines, and spaces between fields and
+// between field identifiers and values are elided.
+//
+// This method is convenient shorthand for invoking MarshalJSONPB with a default
+// (zero value) marshaler:
+//
+// m.MarshalJSONPB(&jsonpb.Marshaler{})
+//
+// So enums are serialized using enum value name strings, and values that are
+// not present (including those with default/zero value for messages defined in
+// "proto3" syntax) are omitted.
+func (m *Message) MarshalJSON() ([]byte, error) {
+ return m.MarshalJSONPB(&jsonpb.Marshaler{})
+}
+
+// MarshalJSONIndent serializes this message to bytes in JSON format, returning
+// an error if the operation fails. The resulting bytes will be a valid UTF8
+// string.
+//
+// This method uses a "pretty-printed" form, with each field on its own line and
+// spaces between field identifiers and values. Indentation of two spaces is
+// used.
+//
+// This method is convenient shorthand for invoking MarshalJSONPB with a default
+// (zero value) marshaler:
+//
+// m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "})
+//
+// So enums are serialized using enum value name strings, and values that are
+// not present (including those with default/zero value for messages defined in
+// "proto3" syntax) are omitted.
+func (m *Message) MarshalJSONIndent() ([]byte, error) {
+ return m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "})
+}
+
+// MarshalJSONPB serializes this message to bytes in JSON format, returning an
+// error if the operation fails. The resulting bytes will be a valid UTF8
+// string. The given marshaler is used to convey options used during marshaling.
+//
+// If this message contains nested messages that are generated message types (as
+// opposed to dynamic messages), the given marshaler is used to marshal it.
+//
+// When marshaling any nested messages, any jsonpb.AnyResolver configured in the
+// given marshaler is augmented with knowledge of message types known to this
+// message's descriptor (and its enclosing file and set of transitive
+// dependencies).
+func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error) {
+ var b indentBuffer
+ b.indent = opts.Indent
+ if len(opts.Indent) == 0 {
+ b.indentCount = -1
+ }
+ b.comma = true
+ if err := m.marshalJSON(&b, opts); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+func (m *Message) marshalJSON(b *indentBuffer, opts *jsonpb.Marshaler) error {
+ if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
+ newOpts := *opts
+ newOpts.AnyResolver = r
+ opts = &newOpts
+ }
+
+ if ok, err := marshalWellKnownType(m, b, opts); ok {
+ return err
+ }
+
+ err := b.WriteByte('{')
+ if err != nil {
+ return err
+ }
+ err = b.start()
+ if err != nil {
+ return err
+ }
+
+ var tags []int
+ if opts.EmitDefaults {
+ tags = m.allKnownFieldTags()
+ } else {
+ tags = m.knownFieldTags()
+ }
+
+ first := true
+
+ for _, tag := range tags {
+ itag := int32(tag)
+ fd := m.FindFieldDescriptor(itag)
+
+ v, ok := m.values[itag]
+ if !ok {
+ if fd.GetOneOf() != nil {
+ // don't print defaults for fields in a oneof
+ continue
+ }
+ v = fd.GetDefaultValue()
+ }
+
+ err := b.maybeNext(&first)
+ if err != nil {
+ return err
+ }
+ err = marshalKnownFieldJSON(b, fd, v, opts)
+ if err != nil {
+ return err
+ }
+ }
+
+ err = b.end()
+ if err != nil {
+ return err
+ }
+ err = b.WriteByte('}')
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func marshalWellKnownType(m *Message, b *indentBuffer, opts *jsonpb.Marshaler) (bool, error) {
+ fqn := m.md.GetFullyQualifiedName()
+ if _, ok := wellKnownTypeNames[fqn]; !ok {
+ return false, nil
+ }
+
+ msgType := proto.MessageType(fqn)
+ if msgType == nil {
+ // wtf?
+ panic(fmt.Sprintf("could not find registered message type for %q", fqn))
+ }
+
+ // convert dynamic message to well-known type and let jsonpb marshal it
+ msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
+ if err := m.MergeInto(msg); err != nil {
+ return true, err
+ }
+ return true, opts.Marshal(b, msg)
+}
+
+func marshalKnownFieldJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
+ var jsonName string
+ if opts.OrigName {
+ jsonName = fd.GetName()
+ } else {
+ jsonName = fd.AsFieldDescriptorProto().GetJsonName()
+ if jsonName == "" {
+ jsonName = fd.GetName()
+ }
+ }
+ if fd.IsExtension() {
+ var scope string
+ switch parent := fd.GetParent().(type) {
+ case *desc.FileDescriptor:
+ scope = parent.GetPackage()
+ default:
+ scope = parent.GetFullyQualifiedName()
+ }
+ if scope == "" {
+ jsonName = fmt.Sprintf("[%s]", jsonName)
+ } else {
+ jsonName = fmt.Sprintf("[%s.%s]", scope, jsonName)
+ }
+ }
+ err := writeJsonString(b, jsonName)
+ if err != nil {
+ return err
+ }
+ err = b.sep()
+ if err != nil {
+ return err
+ }
+
+ if isNil(v) {
+ _, err := b.WriteString("null")
+ return err
+ }
+
+ if fd.IsMap() {
+ err = b.WriteByte('{')
+ if err != nil {
+ return err
+ }
+ err = b.start()
+ if err != nil {
+ return err
+ }
+
+ md := fd.GetMessageType()
+ vfd := md.FindFieldByNumber(2)
+
+ mp := v.(map[interface{}]interface{})
+ keys := make([]interface{}, 0, len(mp))
+ for k := range mp {
+ keys = append(keys, k)
+ }
+ sort.Sort(sortable(keys))
+ first := true
+ for _, mk := range keys {
+ mv := mp[mk]
+ err := b.maybeNext(&first)
+ if err != nil {
+ return err
+ }
+
+ err = marshalKnownFieldMapEntryJSON(b, mk, vfd, mv, opts)
+ if err != nil {
+ return err
+ }
+ }
+
+ err = b.end()
+ if err != nil {
+ return err
+ }
+ return b.WriteByte('}')
+
+ } else if fd.IsRepeated() {
+ err = b.WriteByte('[')
+ if err != nil {
+ return err
+ }
+ err = b.start()
+ if err != nil {
+ return err
+ }
+
+ sl := v.([]interface{})
+ first := true
+ for _, slv := range sl {
+ err := b.maybeNext(&first)
+ if err != nil {
+ return err
+ }
+ err = marshalKnownFieldValueJSON(b, fd, slv, opts)
+ if err != nil {
+ return err
+ }
+ }
+
+ err = b.end()
+ if err != nil {
+ return err
+ }
+ return b.WriteByte(']')
+
+ } else {
+ return marshalKnownFieldValueJSON(b, fd, v, opts)
+ }
+}
+
+// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64),
+// bools, or strings.
+type sortable []interface{}
+
+func (s sortable) Len() int {
+ return len(s)
+}
+
+func (s sortable) Less(i, j int) bool {
+ vi := s[i]
+ vj := s[j]
+ switch reflect.TypeOf(vi).Kind() {
+ case reflect.Int32:
+ return vi.(int32) < vj.(int32)
+ case reflect.Int64:
+ return vi.(int64) < vj.(int64)
+ case reflect.Uint32:
+ return vi.(uint32) < vj.(uint32)
+ case reflect.Uint64:
+ return vi.(uint64) < vj.(uint64)
+ case reflect.String:
+ return vi.(string) < vj.(string)
+ case reflect.Bool:
+ return !vi.(bool) && vj.(bool)
+ default:
+ panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi)))
+ }
+}
+
+func (s sortable) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+
+func isNil(v interface{}) bool {
+ if v == nil {
+ return true
+ }
+ rv := reflect.ValueOf(v)
+ return rv.Kind() == reflect.Ptr && rv.IsNil()
+}
+
+func marshalKnownFieldMapEntryJSON(b *indentBuffer, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}, opts *jsonpb.Marshaler) error {
+ rk := reflect.ValueOf(mk)
+ var strkey string
+ switch rk.Kind() {
+ case reflect.Bool:
+ strkey = strconv.FormatBool(rk.Bool())
+ case reflect.Int32, reflect.Int64:
+ strkey = strconv.FormatInt(rk.Int(), 10)
+ case reflect.Uint32, reflect.Uint64:
+ strkey = strconv.FormatUint(rk.Uint(), 10)
+ case reflect.String:
+ strkey = rk.String()
+ default:
+ return fmt.Errorf("invalid map key value: %v (%v)", mk, rk.Type())
+ }
+ err := writeString(b, strkey)
+ if err != nil {
+ return err
+ }
+ err = b.sep()
+ if err != nil {
+ return err
+ }
+ return marshalKnownFieldValueJSON(b, vfd, mv, opts)
+}
+
+func marshalKnownFieldValueJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
+ rv := reflect.ValueOf(v)
+ switch rv.Kind() {
+ case reflect.Int64:
+ return writeJsonString(b, strconv.FormatInt(rv.Int(), 10))
+ case reflect.Int32:
+ ed := fd.GetEnumType()
+ if !opts.EnumsAsInts && ed != nil {
+ n := int32(rv.Int())
+ vd := ed.FindValueByNumber(n)
+ if vd == nil {
+ _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
+ return err
+ } else {
+ return writeJsonString(b, vd.GetName())
+ }
+ } else {
+ _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
+ return err
+ }
+ case reflect.Uint64:
+ return writeJsonString(b, strconv.FormatUint(rv.Uint(), 10))
+ case reflect.Uint32:
+ _, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10))
+ return err
+ case reflect.Float32, reflect.Float64:
+ f := rv.Float()
+ var str string
+ if math.IsNaN(f) {
+ str = `"NaN"`
+ } else if math.IsInf(f, 1) {
+ str = `"Infinity"`
+ } else if math.IsInf(f, -1) {
+ str = `"-Infinity"`
+ } else {
+ var bits int
+ if rv.Kind() == reflect.Float32 {
+ bits = 32
+ } else {
+ bits = 64
+ }
+ str = strconv.FormatFloat(rv.Float(), 'g', -1, bits)
+ }
+ _, err := b.WriteString(str)
+ return err
+ case reflect.Bool:
+ _, err := b.WriteString(strconv.FormatBool(rv.Bool()))
+ return err
+ case reflect.Slice:
+ bstr := base64.StdEncoding.EncodeToString(rv.Bytes())
+ return writeJsonString(b, bstr)
+ case reflect.String:
+ return writeJsonString(b, rv.String())
+ default:
+ // must be a message
+ if dm, ok := v.(*Message); ok {
+ return dm.marshalJSON(b, opts)
+ } else {
+ var err error
+ if b.indentCount <= 0 || len(b.indent) == 0 {
+ err = opts.Marshal(b, v.(proto.Message))
+ } else {
+ str, err := opts.MarshalToString(v.(proto.Message))
+ if err != nil {
+ return err
+ }
+ indent := strings.Repeat(b.indent, b.indentCount)
+ pos := 0
+ // add indention prefix to each line
+ for pos < len(str) {
+ start := pos
+ nextPos := strings.Index(str[pos:], "\n")
+ if nextPos == -1 {
+ nextPos = len(str)
+ } else {
+ nextPos = pos + nextPos + 1 // include newline
+ }
+ line := str[start:nextPos]
+ if pos > 0 {
+ _, err = b.WriteString(indent)
+ if err != nil {
+ return err
+ }
+ }
+ _, err = b.WriteString(line)
+ if err != nil {
+ return err
+ }
+ pos = nextPos
+ }
+ }
+ return err
+ }
+ }
+}
+
+func writeJsonString(b *indentBuffer, s string) error {
+ if sbytes, err := json.Marshal(s); err != nil {
+ return err
+ } else {
+ _, err := b.Write(sbytes)
+ return err
+ }
+}
+
+// UnmarshalJSON de-serializes the message that is present, in JSON format, in
+// the given bytes into this message. It first resets the current message. It
+// returns an error if the given bytes do not contain a valid encoding of this
+// message type in JSON format.
+//
+// This method is shorthand for invoking UnmarshalJSONPB with a default (zero
+// value) unmarshaler:
+//
+// m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
+//
+// So unknown fields will result in an error, and no provided jsonpb.AnyResolver
+// will be used when parsing google.protobuf.Any messages.
+func (m *Message) UnmarshalJSON(js []byte) error {
+ return m.UnmarshalJSONPB(&jsonpb.Unmarshaler{}, js)
+}
+
+// UnmarshalMergeJSON de-serializes the message that is present, in JSON format,
+// in the given bytes into this message. Unlike UnmarshalJSON, it does not first
+// reset the message, instead merging the data in the given bytes into the
+// existing data in this message.
+func (m *Message) UnmarshalMergeJSON(js []byte) error {
+ return m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
+}
+
+// UnmarshalJSONPB de-serializes the message that is present, in JSON format, in
+// the given bytes into this message. The given unmarshaler conveys options used
+// when parsing the JSON. This function first resets the current message. It
+// returns an error if the given bytes do not contain a valid encoding of this
+// message type in JSON format.
+//
+// The decoding is lenient:
+// 1. The JSON can refer to fields either by their JSON name or by their
+// declared name.
+// 2. The JSON can use either numeric values or string names for enum values.
+//
+// When instantiating nested messages, if this message's associated factory
+// returns a generated message type (as opposed to a dynamic message), the given
+// unmarshaler is used to unmarshal it.
+//
+// When unmarshaling any nested messages, any jsonpb.AnyResolver configured in
+// the given unmarshaler is augmented with knowledge of message types known to
+// this message's descriptor (and its enclosing file and set of transitive
+// dependencies).
+func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
+ m.Reset()
+ if err := m.UnmarshalMergeJSONPB(opts, js); err != nil {
+ return err
+ }
+ return m.Validate()
+}
+
+// UnmarshalMergeJSONPB de-serializes the message that is present, in JSON
+// format, in the given bytes into this message. The given unmarshaler conveys
+// options used when parsing the JSON. Unlike UnmarshalJSONPB, it does not first
+// reset the message, instead merging the data in the given bytes into the
+// existing data in this message.
+func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
+ r := newJsReader(js)
+ err := m.unmarshalJson(r, opts)
+ if err != nil {
+ return err
+ }
+ if t, err := r.poll(); err != io.EOF {
+ b, _ := ioutil.ReadAll(r.unread())
+ s := fmt.Sprintf("%v%s", t, string(b))
+ return fmt.Errorf("superfluous data found after JSON object: %q", s)
+ }
+ return nil
+}
+
+func unmarshalWellKnownType(m *Message, r *jsReader, opts *jsonpb.Unmarshaler) (bool, error) {
+ fqn := m.md.GetFullyQualifiedName()
+ if _, ok := wellKnownTypeNames[fqn]; !ok {
+ return false, nil
+ }
+
+ msgType := proto.MessageType(fqn)
+ if msgType == nil {
+ // wtf?
+ panic(fmt.Sprintf("could not find registered message type for %q", fqn))
+ }
+
+ // extract json value from r
+ var js json.RawMessage
+ if err := json.NewDecoder(r.unread()).Decode(&js); err != nil {
+ return true, err
+ }
+ if err := r.skip(); err != nil {
+ return true, err
+ }
+
+ // unmarshal into well-known type and then convert to dynamic message
+ msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
+ if err := opts.Unmarshal(bytes.NewReader(js), msg); err != nil {
+ return true, err
+ }
+ return true, m.MergeFrom(msg)
+}
+
+func (m *Message) unmarshalJson(r *jsReader, opts *jsonpb.Unmarshaler) error {
+ if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
+ newOpts := *opts
+ newOpts.AnyResolver = r
+ opts = &newOpts
+ }
+
+ if ok, err := unmarshalWellKnownType(m, r, opts); ok {
+ return err
+ }
+
+ t, err := r.peek()
+ if err != nil {
+ return err
+ }
+ if t == nil {
+ // if json is simply "null" we do nothing
+ r.poll()
+ return nil
+ }
+
+ if err := r.beginObject(); err != nil {
+ return err
+ }
+
+ for r.hasNext() {
+ f, err := r.nextObjectKey()
+ if err != nil {
+ return err
+ }
+ fd := m.FindFieldDescriptorByJSONName(f)
+ if fd == nil {
+ if opts.AllowUnknownFields {
+ r.skip()
+ continue
+ }
+ return fmt.Errorf("message type %s has no known field named %s", m.md.GetFullyQualifiedName(), f)
+ }
+ v, err := unmarshalJsField(fd, r, m.mf, opts)
+ if err != nil {
+ return err
+ }
+ if v != nil {
+ if err := mergeField(m, fd, v); err != nil {
+ return err
+ }
+ } else if fd.GetOneOf() != nil {
+ // preserve explicit null for oneof fields (this is a little odd but
+ // mimics the behavior of jsonpb with oneofs in generated message types)
+ if fd.GetMessageType() != nil {
+ typ := m.mf.GetKnownTypeRegistry().GetKnownType(fd.GetMessageType().GetFullyQualifiedName())
+ if typ != nil {
+ // typed nil
+ if typ.Kind() != reflect.Ptr {
+ typ = reflect.PtrTo(typ)
+ }
+ v = reflect.Zero(typ).Interface()
+ } else {
+ // can't use nil dynamic message, so we just use empty one instead
+ v = m.mf.NewDynamicMessage(fd.GetMessageType())
+ }
+ if err := m.setField(fd, v); err != nil {
+ return err
+ }
+ } else {
+ // not a message... explicit null makes no sense
+ return fmt.Errorf("message type %s cannot set field %s to null: it is not a message type", m.md.GetFullyQualifiedName(), f)
+ }
+ } else {
+ m.clearField(fd)
+ }
+ }
+
+ if err := r.endObject(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func isWellKnownValue(fd *desc.FieldDescriptor) bool {
+ return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
+ fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value"
+}
+
+func isWellKnownListValue(fd *desc.FieldDescriptor) bool {
+ return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
+ fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue"
+}
+
+func unmarshalJsField(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
+ t, err := r.peek()
+ if err != nil {
+ return nil, err
+ }
+ if t == nil && !isWellKnownValue(fd) {
+ // if value is null, just return nil
+ // (unless field is google.protobuf.Value, in which case
+ // we fall through to parse it as an instance where its
+ // underlying value is set to a NullValue)
+ r.poll()
+ return nil, nil
+ }
+
+ if t == json.Delim('{') && fd.IsMap() {
+ entryType := fd.GetMessageType()
+ keyType := entryType.FindFieldByNumber(1)
+ valueType := entryType.FindFieldByNumber(2)
+ mp := map[interface{}]interface{}{}
+
+ // TODO: if there are just two map keys "key" and "value" and they have the right type of values,
+ // treat this JSON object as a single map entry message. (In keeping with support of map fields as
+ // if they were normal repeated field of entry messages as well as supporting a transition from
+ // optional to repeated...)
+
+ if err := r.beginObject(); err != nil {
+ return nil, err
+ }
+ for r.hasNext() {
+ kk, err := unmarshalJsFieldElement(keyType, r, mf, opts)
+ if err != nil {
+ return nil, err
+ }
+ vv, err := unmarshalJsFieldElement(valueType, r, mf, opts)
+ if err != nil {
+ return nil, err
+ }
+ mp[kk] = vv
+ }
+ if err := r.endObject(); err != nil {
+ return nil, err
+ }
+
+ return mp, nil
+ } else if t == json.Delim('[') && !isWellKnownListValue(fd) {
+ // We support parsing an array, even if field is not repeated, to mimic support in proto
+ // binary wire format that supports changing an optional field to repeated and vice versa.
+ // If the field is not repeated, we only keep the last value in the array.
+
+ if err := r.beginArray(); err != nil {
+ return nil, err
+ }
+ var sl []interface{}
+ var v interface{}
+ for r.hasNext() {
+ var err error
+ v, err = unmarshalJsFieldElement(fd, r, mf, opts)
+ if err != nil {
+ return nil, err
+ }
+ if fd.IsRepeated() && v != nil {
+ sl = append(sl, v)
+ }
+ }
+ if err := r.endArray(); err != nil {
+ return nil, err
+ }
+ if fd.IsMap() {
+ mp := map[interface{}]interface{}{}
+ for _, m := range sl {
+ msg := m.(*Message)
+ kk, err := msg.TryGetFieldByNumber(1)
+ if err != nil {
+ return nil, err
+ }
+ vv, err := msg.TryGetFieldByNumber(2)
+ if err != nil {
+ return nil, err
+ }
+ mp[kk] = vv
+ }
+ return mp, nil
+ } else if fd.IsRepeated() {
+ return sl, nil
+ } else {
+ return v, nil
+ }
+ } else {
+ // We support parsing a singular value, even if field is repeated, to mimic support in proto
+ // binary wire format that supports changing an optional field to repeated and vice versa.
+ // If the field is repeated, we store value as singleton slice of that one value.
+
+ v, err := unmarshalJsFieldElement(fd, r, mf, opts)
+ if err != nil {
+ return nil, err
+ }
+ if v == nil {
+ return nil, nil
+ }
+ if fd.IsRepeated() {
+ return []interface{}{v}, nil
+ } else {
+ return v, nil
+ }
+ }
+}
+
+func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
+ t, err := r.peek()
+ if err != nil {
+ return nil, err
+ }
+
+ switch fd.GetType() {
+ case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
+ descriptor.FieldDescriptorProto_TYPE_GROUP:
+ m := mf.NewMessage(fd.GetMessageType())
+ if dm, ok := m.(*Message); ok {
+ if err := dm.unmarshalJson(r, opts); err != nil {
+ return nil, err
+ }
+ } else {
+ var msg json.RawMessage
+ if err := json.NewDecoder(r.unread()).Decode(&msg); err != nil {
+ return nil, err
+ }
+ if err := r.skip(); err != nil {
+ return nil, err
+ }
+ if err := opts.Unmarshal(bytes.NewReader([]byte(msg)), m); err != nil {
+ return nil, err
+ }
+ }
+ return m, nil
+
+ case descriptor.FieldDescriptorProto_TYPE_ENUM:
+ if e, err := r.nextNumber(); err != nil {
+ return nil, err
+ } else {
+ // value could be string or number
+ if i, err := e.Int64(); err != nil {
+ // number cannot be parsed, so see if it's an enum value name
+ vd := fd.GetEnumType().FindValueByName(string(e))
+ if vd != nil {
+ return vd.GetNumber(), nil
+ } else {
+ return nil, fmt.Errorf("enum %q does not have value named %q", fd.GetEnumType().GetFullyQualifiedName(), e)
+ }
+ } else if i > math.MaxInt32 || i < math.MinInt32 {
+ return nil, NumericOverflowError
+ } else {
+ return int32(i), err
+ }
+ }
+
+ case descriptor.FieldDescriptorProto_TYPE_INT32,
+ descriptor.FieldDescriptorProto_TYPE_SINT32,
+ descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+ if i, err := r.nextInt(); err != nil {
+ return nil, err
+ } else if i > math.MaxInt32 || i < math.MinInt32 {
+ return nil, NumericOverflowError
+ } else {
+ return int32(i), err
+ }
+
+ case descriptor.FieldDescriptorProto_TYPE_INT64,
+ descriptor.FieldDescriptorProto_TYPE_SINT64,
+ descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+ return r.nextInt()
+
+ case descriptor.FieldDescriptorProto_TYPE_UINT32,
+ descriptor.FieldDescriptorProto_TYPE_FIXED32:
+ if i, err := r.nextUint(); err != nil {
+ return nil, err
+ } else if i > math.MaxUint32 {
+ return nil, NumericOverflowError
+ } else {
+ return uint32(i), err
+ }
+
+ case descriptor.FieldDescriptorProto_TYPE_UINT64,
+ descriptor.FieldDescriptorProto_TYPE_FIXED64:
+ return r.nextUint()
+
+ case descriptor.FieldDescriptorProto_TYPE_BOOL:
+ if str, ok := t.(string); ok {
+ if str == "true" {
+ r.poll() // consume token
+ return true, err
+ } else if str == "false" {
+ r.poll() // consume token
+ return false, err
+ }
+ }
+ return r.nextBool()
+
+ case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+ if f, err := r.nextFloat(); err != nil {
+ return nil, err
+ } else {
+ return float32(f), nil
+ }
+
+ case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+ return r.nextFloat()
+
+ case descriptor.FieldDescriptorProto_TYPE_BYTES:
+ return r.nextBytes()
+
+ case descriptor.FieldDescriptorProto_TYPE_STRING:
+ return r.nextString()
+
+ default:
+ return nil, fmt.Errorf("unknown field type: %v", fd.GetType())
+ }
+}
+
+type jsReader struct {
+ reader *bytes.Reader
+ dec *json.Decoder
+ current json.Token
+ peeked bool
+}
+
+func newJsReader(b []byte) *jsReader {
+ reader := bytes.NewReader(b)
+ dec := json.NewDecoder(reader)
+ dec.UseNumber()
+ return &jsReader{reader: reader, dec: dec}
+}
+
+func (r *jsReader) unread() io.Reader {
+ bufs := make([]io.Reader, 3)
+ var peeked []byte
+ if r.peeked {
+ if _, ok := r.current.(json.Delim); ok {
+ peeked = []byte(fmt.Sprintf("%v", r.current))
+ } else {
+ peeked, _ = json.Marshal(r.current)
+ }
+ }
+ readerCopy := *r.reader
+ decCopy := *r.dec
+
+ bufs[0] = bytes.NewReader(peeked)
+ bufs[1] = decCopy.Buffered()
+ bufs[2] = &readerCopy
+ return &concatReader{bufs: bufs}
+}
+
+func (r *jsReader) hasNext() bool {
+ return r.dec.More()
+}
+
+func (r *jsReader) peek() (json.Token, error) {
+ if r.peeked {
+ return r.current, nil
+ }
+ t, err := r.dec.Token()
+ if err != nil {
+ return nil, err
+ }
+ r.peeked = true
+ r.current = t
+ return t, nil
+}
+
+func (r *jsReader) poll() (json.Token, error) {
+ if r.peeked {
+ ret := r.current
+ r.current = nil
+ r.peeked = false
+ return ret, nil
+ }
+ return r.dec.Token()
+}
+
+func (r *jsReader) beginObject() error {
+ _, err := r.expect(func(t json.Token) bool { return t == json.Delim('{') }, nil, "start of JSON object: '{'")
+ return err
+}
+
+func (r *jsReader) endObject() error {
+ _, err := r.expect(func(t json.Token) bool { return t == json.Delim('}') }, nil, "end of JSON object: '}'")
+ return err
+}
+
+func (r *jsReader) beginArray() error {
+ _, err := r.expect(func(t json.Token) bool { return t == json.Delim('[') }, nil, "start of array: '['")
+ return err
+}
+
+func (r *jsReader) endArray() error {
+ _, err := r.expect(func(t json.Token) bool { return t == json.Delim(']') }, nil, "end of array: ']'")
+ return err
+}
+
+func (r *jsReader) nextObjectKey() (string, error) {
+ return r.nextString()
+}
+
+func (r *jsReader) nextString() (string, error) {
+ t, err := r.expect(func(t json.Token) bool { _, ok := t.(string); return ok }, "", "string")
+ if err != nil {
+ return "", err
+ }
+ return t.(string), nil
+}
+
+func (r *jsReader) nextBytes() ([]byte, error) {
+ str, err := r.nextString()
+ if err != nil {
+ return nil, err
+ }
+ return base64.StdEncoding.DecodeString(str)
+}
+
+func (r *jsReader) nextBool() (bool, error) {
+ t, err := r.expect(func(t json.Token) bool { _, ok := t.(bool); return ok }, false, "boolean")
+ if err != nil {
+ return false, err
+ }
+ return t.(bool), nil
+}
+
+func (r *jsReader) nextInt() (int64, error) {
+ n, err := r.nextNumber()
+ if err != nil {
+ return 0, err
+ }
+ return n.Int64()
+}
+
+func (r *jsReader) nextUint() (uint64, error) {
+ n, err := r.nextNumber()
+ if err != nil {
+ return 0, err
+ }
+ return strconv.ParseUint(string(n), 10, 64)
+}
+
+func (r *jsReader) nextFloat() (float64, error) {
+ n, err := r.nextNumber()
+ if err != nil {
+ return 0, err
+ }
+ return n.Float64()
+}
+
+func (r *jsReader) nextNumber() (json.Number, error) {
+ t, err := r.expect(func(t json.Token) bool { return reflect.TypeOf(t).Kind() == reflect.String }, "0", "number")
+ if err != nil {
+ return "", err
+ }
+ switch t := t.(type) {
+ case json.Number:
+ return t, nil
+ case string:
+ return json.Number(t), nil
+ }
+ return "", fmt.Errorf("expecting a number but got %v", t)
+}
+
+func (r *jsReader) skip() error {
+ t, err := r.poll()
+ if err != nil {
+ return err
+ }
+ if t == json.Delim('[') {
+ if err := r.skipArray(); err != nil {
+ return err
+ }
+ } else if t == json.Delim('{') {
+ if err := r.skipObject(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (r *jsReader) skipArray() error {
+ for r.hasNext() {
+ if err := r.skip(); err != nil {
+ return err
+ }
+ }
+ if err := r.endArray(); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (r *jsReader) skipObject() error {
+ for r.hasNext() {
+ // skip object key
+ if err := r.skip(); err != nil {
+ return err
+ }
+ // and value
+ if err := r.skip(); err != nil {
+ return err
+ }
+ }
+ if err := r.endObject(); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (r *jsReader) expect(predicate func(json.Token) bool, ifNil interface{}, expected string) (interface{}, error) {
+ t, err := r.poll()
+ if err != nil {
+ return nil, err
+ }
+ if t == nil && ifNil != nil {
+ return ifNil, nil
+ }
+ if !predicate(t) {
+ return t, fmt.Errorf("bad input: expecting %s ; instead got %v", expected, t)
+ }
+ return t, nil
+}
+
+type concatReader struct {
+ bufs []io.Reader
+ curr int
+}
+
+func (r *concatReader) Read(p []byte) (n int, err error) {
+ for {
+ if r.curr >= len(r.bufs) {
+ err = io.EOF
+ return
+ }
+ var c int
+ c, err = r.bufs[r.curr].Read(p)
+ n += c
+ if err != io.EOF {
+ return
+ }
+ r.curr++
+ p = p[c:]
+ }
+}
+
+// AnyResolver returns a jsonpb.AnyResolver that uses the given file descriptors
+// to resolve message names. It uses the given factory, which may be nil, to
+// instantiate messages. The messages that it returns when resolving a type name
+// may often be dynamic messages.
+func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver {
+ return &anyResolver{mf: mf, files: files}
+}
+
+type anyResolver struct {
+ mf *MessageFactory
+ files []*desc.FileDescriptor
+ ignored map[*desc.FileDescriptor]struct{}
+ other jsonpb.AnyResolver
+}
+
+func wrapResolver(r jsonpb.AnyResolver, mf *MessageFactory, f *desc.FileDescriptor) (jsonpb.AnyResolver, bool) {
+ if r, ok := r.(*anyResolver); ok {
+ if _, ok := r.ignored[f]; ok {
+ // if the current resolver is ignoring this file, it's because another
+ // (upstream) resolver is already handling it, so nothing to do
+ return r, false
+ }
+ for _, file := range r.files {
+ if file == f {
+ // no need to wrap!
+ return r, false
+ }
+ }
+ // ignore files that will be checked by the resolver we're wrapping
+ // (we'll just delegate and let it search those files)
+ ignored := map[*desc.FileDescriptor]struct{}{}
+ for i := range r.ignored {
+ ignored[i] = struct{}{}
+ }
+ ignore(r.files, ignored)
+ return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, ignored: ignored, other: r}, true
+ }
+ return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, other: r}, true
+}
+
+func ignore(files []*desc.FileDescriptor, ignored map[*desc.FileDescriptor]struct{}) {
+ for _, f := range files {
+ if _, ok := ignored[f]; ok {
+ continue
+ }
+ ignored[f] = struct{}{}
+ ignore(f.GetDependencies(), ignored)
+ }
+}
+
+func (r *anyResolver) Resolve(typeUrl string) (proto.Message, error) {
+ mname := typeUrl
+ if slash := strings.LastIndex(mname, "/"); slash >= 0 {
+ mname = mname[slash+1:]
+ }
+
+ // see if the user-specified resolver is able to do the job
+ if r.other != nil {
+ msg, err := r.other.Resolve(typeUrl)
+ if err == nil {
+ return msg, nil
+ }
+ }
+
+ // try to find the message in our known set of files
+ checked := map[*desc.FileDescriptor]struct{}{}
+ for _, f := range r.files {
+ md := r.findMessage(f, mname, checked)
+ if md != nil {
+ return r.mf.NewMessage(md), nil
+ }
+ }
+ // failing that, see if the message factory knows about this type
+ var ktr *KnownTypeRegistry
+ if r.mf != nil {
+ ktr = r.mf.ktr
+ } else {
+ ktr = (*KnownTypeRegistry)(nil)
+ }
+ m := ktr.CreateIfKnown(mname)
+ if m != nil {
+ return m, nil
+ }
+
+ // no other resolver to fallback to? mimic default behavior
+ 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
+}
+
+func (r *anyResolver) findMessage(fd *desc.FileDescriptor, msgName string, checked map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor {
+ // if this is an ignored descriptor, skip
+ if _, ok := r.ignored[fd]; ok {
+ return nil
+ }
+
+ // bail if we've already checked this file
+ if _, ok := checked[fd]; ok {
+ return nil
+ }
+ checked[fd] = struct{}{}
+
+ // see if this file has the message
+ md := fd.FindMessage(msgName)
+ if md != nil {
+ return md
+ }
+
+ // if not, recursively search the file's imports
+ for _, dep := range fd.GetDependencies() {
+ md = r.findMessage(dep, msgName, checked)
+ if md != nil {
+ return md
+ }
+ }
+ return nil
+}
+
+var _ jsonpb.AnyResolver = (*anyResolver)(nil)