gRPC migration
Change-Id: Ib390f6dde0d5a8d6db12ccd7da41135570ad1354
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go
index e545feb..ba971f0 100644
--- a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go
@@ -7,14 +7,17 @@
import (
"encoding/base64"
"fmt"
- "sort"
"google.golang.org/protobuf/internal/encoding/json"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/errors"
+ "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/flags"
+ "google.golang.org/protobuf/internal/genid"
+ "google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
)
@@ -104,6 +107,13 @@
// MarshalOptions. Do not depend on the output being stable. It may change over
// time across different versions of the program.
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
+ return o.marshal(m)
+}
+
+// marshal is a centralized function that all marshal operations go through.
+// For profiling purposes, avoid changing the name of this function or
+// introducing other code paths for marshal that do not go through this.
+func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) {
if o.Multiline && o.Indent == "" {
o.Indent = defaultIndent
}
@@ -123,7 +133,7 @@
}
enc := encoder{internalEnc, o}
- if err := enc.marshalMessage(m.ProtoReflect()); err != nil {
+ if err := enc.marshalMessage(m.ProtoReflect(), ""); err != nil {
return nil, err
}
if o.AllowPartial {
@@ -137,76 +147,94 @@
opts MarshalOptions
}
-// marshalMessage marshals the given protoreflect.Message.
-func (e encoder) marshalMessage(m pref.Message) error {
- if isCustomType(m.Descriptor().FullName()) {
- return e.marshalCustomType(m)
+// typeFieldDesc is a synthetic field descriptor used for the "@type" field.
+var typeFieldDesc = func() protoreflect.FieldDescriptor {
+ var fd filedesc.Field
+ fd.L0.FullName = "@type"
+ fd.L0.Index = -1
+ fd.L1.Cardinality = protoreflect.Optional
+ fd.L1.Kind = protoreflect.StringKind
+ return &fd
+}()
+
+// typeURLFieldRanger wraps a protoreflect.Message and modifies its Range method
+// to additionally iterate over a synthetic field for the type URL.
+type typeURLFieldRanger struct {
+ order.FieldRanger
+ typeURL string
+}
+
+func (m typeURLFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+ if !f(typeFieldDesc, pref.ValueOfString(m.typeURL)) {
+ return
+ }
+ m.FieldRanger.Range(f)
+}
+
+// unpopulatedFieldRanger wraps a protoreflect.Message and modifies its Range
+// method to additionally iterate over unpopulated fields.
+type unpopulatedFieldRanger struct{ pref.Message }
+
+func (m unpopulatedFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
+ fds := m.Descriptor().Fields()
+ for i := 0; i < fds.Len(); i++ {
+ fd := fds.Get(i)
+ if m.Has(fd) || fd.ContainingOneof() != nil {
+ continue // ignore populated fields and fields within a oneofs
+ }
+
+ v := m.Get(fd)
+ isProto2Scalar := fd.Syntax() == pref.Proto2 && fd.Default().IsValid()
+ isSingularMessage := fd.Cardinality() != pref.Repeated && fd.Message() != nil
+ if isProto2Scalar || isSingularMessage {
+ v = pref.Value{} // use invalid value to emit null
+ }
+ if !f(fd, v) {
+ return
+ }
+ }
+ m.Message.Range(f)
+}
+
+// marshalMessage marshals the fields in the given protoreflect.Message.
+// If the typeURL is non-empty, then a synthetic "@type" field is injected
+// containing the URL as the value.
+func (e encoder) marshalMessage(m pref.Message, typeURL string) error {
+ if !flags.ProtoLegacy && messageset.IsMessageSet(m.Descriptor()) {
+ return errors.New("no support for proto1 MessageSets")
+ }
+
+ if marshal := wellKnownTypeMarshaler(m.Descriptor().FullName()); marshal != nil {
+ return marshal(e, m)
}
e.StartObject()
defer e.EndObject()
- if err := e.marshalFields(m); err != nil {
- return err
+
+ var fields order.FieldRanger = m
+ if e.opts.EmitUnpopulated {
+ fields = unpopulatedFieldRanger{m}
+ }
+ if typeURL != "" {
+ fields = typeURLFieldRanger{fields, typeURL}
}
- return nil
-}
-
-// marshalFields marshals the fields in the given protoreflect.Message.
-func (e encoder) marshalFields(m pref.Message) error {
- messageDesc := m.Descriptor()
- if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
- return errors.New("no support for proto1 MessageSets")
- }
-
- // Marshal out known fields.
- fieldDescs := messageDesc.Fields()
- for i := 0; i < fieldDescs.Len(); {
- fd := fieldDescs.Get(i)
- if od := fd.ContainingOneof(); od != nil {
- fd = m.WhichOneof(od)
- i += od.Fields().Len()
- if fd == nil {
- continue // unpopulated oneofs are not affected by EmitUnpopulated
- }
- } else {
- i++
- }
-
- val := m.Get(fd)
- if !m.Has(fd) {
- if !e.opts.EmitUnpopulated {
- continue
- }
- isProto2Scalar := fd.Syntax() == pref.Proto2 && fd.Default().IsValid()
- isSingularMessage := fd.Cardinality() != pref.Repeated && fd.Message() != nil
- if isProto2Scalar || isSingularMessage {
- // Use invalid value to emit null.
- val = pref.Value{}
- }
- }
-
+ var err error
+ order.RangeFields(fields, order.IndexNameFieldOrder, func(fd pref.FieldDescriptor, v pref.Value) bool {
name := fd.JSONName()
if e.opts.UseProtoNames {
- name = string(fd.Name())
- // Use type name for group field name.
- if fd.Kind() == pref.GroupKind {
- name = string(fd.Message().Name())
- }
+ name = fd.TextName()
}
- if err := e.WriteName(name); err != nil {
- return err
- }
- if err := e.marshalValue(val, fd); err != nil {
- return err
- }
- }
- // Marshal out extensions.
- if err := e.marshalExtensions(m); err != nil {
- return err
- }
- return nil
+ if err = e.WriteName(name); err != nil {
+ return false
+ }
+ if err = e.marshalValue(v, fd); err != nil {
+ return false
+ }
+ return true
+ })
+ return err
}
// marshalValue marshals the given protoreflect.Value.
@@ -261,7 +289,7 @@
e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
case pref.EnumKind:
- if fd.Enum().FullName() == "google.protobuf.NullValue" {
+ if fd.Enum().FullName() == genid.NullValue_enum_fullname {
e.WriteNull()
} else {
desc := fd.Enum().Values().ByNumber(val.Enum())
@@ -273,7 +301,7 @@
}
case pref.MessageKind, pref.GroupKind:
- if err := e.marshalMessage(val.Message()); err != nil {
+ if err := e.marshalMessage(val.Message(), ""); err != nil {
return err
}
@@ -297,98 +325,20 @@
return nil
}
-type mapEntry struct {
- key pref.MapKey
- value pref.Value
-}
-
// marshalMap marshals given protoreflect.Map.
func (e encoder) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
e.StartObject()
defer e.EndObject()
- // Get a sorted list based on keyType first.
- entries := make([]mapEntry, 0, mmap.Len())
- mmap.Range(func(key pref.MapKey, val pref.Value) bool {
- entries = append(entries, mapEntry{key: key, value: val})
+ var err error
+ order.RangeEntries(mmap, order.GenericKeyOrder, func(k pref.MapKey, v pref.Value) bool {
+ if err = e.WriteName(k.String()); err != nil {
+ return false
+ }
+ if err = e.marshalSingular(v, fd.MapValue()); err != nil {
+ return false
+ }
return true
})
- sortMap(fd.MapKey().Kind(), entries)
-
- // Write out sorted list.
- for _, entry := range entries {
- if err := e.WriteName(entry.key.String()); err != nil {
- return err
- }
- if err := e.marshalSingular(entry.value, fd.MapValue()); err != nil {
- return err
- }
- }
- return nil
-}
-
-// sortMap orders list based on value of key field for deterministic ordering.
-func sortMap(keyKind pref.Kind, values []mapEntry) {
- sort.Slice(values, func(i, j int) bool {
- switch keyKind {
- case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind,
- pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
- return values[i].key.Int() < values[j].key.Int()
-
- case pref.Uint32Kind, pref.Fixed32Kind,
- pref.Uint64Kind, pref.Fixed64Kind:
- return values[i].key.Uint() < values[j].key.Uint()
- }
- return values[i].key.String() < values[j].key.String()
- })
-}
-
-// marshalExtensions marshals extension fields.
-func (e encoder) marshalExtensions(m pref.Message) error {
- type entry struct {
- key string
- value pref.Value
- desc pref.FieldDescriptor
- }
-
- // Get a sorted list based on field key first.
- var entries []entry
- m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
- if !fd.IsExtension() {
- return true
- }
-
- // For MessageSet extensions, the name used is the parent message.
- name := fd.FullName()
- if messageset.IsMessageSetExtension(fd) {
- name = name.Parent()
- }
-
- // Use [name] format for JSON field name.
- entries = append(entries, entry{
- key: string(name),
- value: v,
- desc: fd,
- })
- return true
- })
-
- // Sort extensions lexicographically.
- sort.Slice(entries, func(i, j int) bool {
- return entries[i].key < entries[j].key
- })
-
- // Write out sorted list.
- for _, entry := range entries {
- // JSON field name is the proto field name enclosed in [], similar to
- // textproto. This is consistent with Go v1 lib. C++ lib v3.7.0 does not
- // marshal out extension fields.
- if err := e.WriteName("[" + entry.key + "]"); err != nil {
- return err
- }
- if err := e.marshalValue(entry.value, entry.desc); err != nil {
- return err
- }
- }
- return nil
+ return err
}