Browse Source
Bumps [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) from 1.24.0 to 1.25.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.24.0...v1.25.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>pull/2827/head
286 changed files with 4548 additions and 16871 deletions
@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes. |
||||
# The master list of authors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/AUTHORS. |
||||
@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors. |
||||
# The master list of contributors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/CONTRIBUTORS. |
||||
@ -1,28 +0,0 @@
|
||||
Copyright 2010 The Go Authors. All rights reserved. |
||||
|
||||
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. |
||||
|
||||
@ -1,530 +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 jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { |
||||
return jsu.UnmarshalJSONPB(u, in) |
||||
} |
||||
|
||||
if string(in) == "null" && md.FullName() != "google.protobuf.Value" { |
||||
return nil |
||||
} |
||||
|
||||
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 |
||||
} |
||||
|
||||
field := m.NewField(fd) |
||||
// Unmarshal the field value.
|
||||
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { |
||||
continue |
||||
} |
||||
v, err := u.unmarshalValue(field, 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()) |
||||
} |
||||
|
||||
field := m.NewField(fd) |
||||
// Unmarshal the field value.
|
||||
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { |
||||
continue |
||||
} |
||||
v, err := u.unmarshalValue(field, 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 fd.Cardinality() == protoreflect.Repeated { |
||||
return false |
||||
} |
||||
if md := fd.Message(); md != nil { |
||||
return md.FullName() == "google.protobuf.Value" |
||||
} |
||||
if ed := fd.Enum(); ed != nil { |
||||
return ed.FullName() == "google.protobuf.NullValue" |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool { |
||||
if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated { |
||||
_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler) |
||||
return ok |
||||
} |
||||
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 |
||||
} |
||||
@ -1,559 +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": |
||||
const maxSecondsInDuration = 315576000000 |
||||
// "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 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") |
||||
} |
||||
var sign string |
||||
if s < 0 || ns < 0 { |
||||
sign, s, ns = "-", -1*s, -1*ns |
||||
} |
||||
x := fmt.Sprintf("%s%d.%09d", sign, 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 |
||||
} |
||||
} |
||||
@ -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() |
||||
} |
||||
@ -1,324 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
|
||||
"google.golang.org/protobuf/encoding/prototext" |
||||
"google.golang.org/protobuf/encoding/protowire" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
const ( |
||||
WireVarint = 0 |
||||
WireFixed32 = 5 |
||||
WireFixed64 = 1 |
||||
WireBytes = 2 |
||||
WireStartGroup = 3 |
||||
WireEndGroup = 4 |
||||
) |
||||
|
||||
// EncodeVarint returns the varint encoded bytes of v.
|
||||
func EncodeVarint(v uint64) []byte { |
||||
return protowire.AppendVarint(nil, v) |
||||
} |
||||
|
||||
// SizeVarint returns the length of the varint encoded bytes of v.
|
||||
// This is equal to len(EncodeVarint(v)).
|
||||
func SizeVarint(v uint64) int { |
||||
return protowire.SizeVarint(v) |
||||
} |
||||
|
||||
// DecodeVarint parses a varint encoded integer from b,
|
||||
// returning the integer value and the length of the varint.
|
||||
// It returns (0, 0) if there is a parse error.
|
||||
func DecodeVarint(b []byte) (uint64, int) { |
||||
v, n := protowire.ConsumeVarint(b) |
||||
if n < 0 { |
||||
return 0, 0 |
||||
} |
||||
return v, n |
||||
} |
||||
|
||||
// Buffer is a buffer for encoding and decoding the protobuf wire format.
|
||||
// It may be reused between invocations to reduce memory usage.
|
||||
type Buffer struct { |
||||
buf []byte |
||||
idx int |
||||
deterministic bool |
||||
} |
||||
|
||||
// NewBuffer allocates a new Buffer initialized with buf,
|
||||
// where the contents of buf are considered the unread portion of the buffer.
|
||||
func NewBuffer(buf []byte) *Buffer { |
||||
return &Buffer{buf: buf} |
||||
} |
||||
|
||||
// SetDeterministic specifies whether to use deterministic serialization.
|
||||
//
|
||||
// Deterministic serialization guarantees that for a given binary, equal
|
||||
// messages will always be serialized to the same bytes. This implies:
|
||||
//
|
||||
// - Repeated serialization of a message will return the same bytes.
|
||||
// - Different processes of the same binary (which may be executing on
|
||||
// different machines) will serialize equal messages to the same bytes.
|
||||
//
|
||||
// Note that the deterministic serialization is NOT canonical across
|
||||
// languages. It is not guaranteed to remain stable over time. It is unstable
|
||||
// across different builds with schema changes due to unknown fields.
|
||||
// Users who need canonical serialization (e.g., persistent storage in a
|
||||
// canonical form, fingerprinting, etc.) should define their own
|
||||
// canonicalization specification and implement their own serializer rather
|
||||
// than relying on this API.
|
||||
//
|
||||
// If deterministic serialization is requested, map entries will be sorted
|
||||
// by keys in lexographical order. This is an implementation detail and
|
||||
// subject to change.
|
||||
func (b *Buffer) SetDeterministic(deterministic bool) { |
||||
b.deterministic = deterministic |
||||
} |
||||
|
||||
// SetBuf sets buf as the internal buffer,
|
||||
// where the contents of buf are considered the unread portion of the buffer.
|
||||
func (b *Buffer) SetBuf(buf []byte) { |
||||
b.buf = buf |
||||
b.idx = 0 |
||||
} |
||||
|
||||
// Reset clears the internal buffer of all written and unread data.
|
||||
func (b *Buffer) Reset() { |
||||
b.buf = b.buf[:0] |
||||
b.idx = 0 |
||||
} |
||||
|
||||
// Bytes returns the internal buffer.
|
||||
func (b *Buffer) Bytes() []byte { |
||||
return b.buf |
||||
} |
||||
|
||||
// Unread returns the unread portion of the buffer.
|
||||
func (b *Buffer) Unread() []byte { |
||||
return b.buf[b.idx:] |
||||
} |
||||
|
||||
// Marshal appends the wire-format encoding of m to the buffer.
|
||||
func (b *Buffer) Marshal(m Message) error { |
||||
var err error |
||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic) |
||||
return err |
||||
} |
||||
|
||||
// Unmarshal parses the wire-format message in the buffer and
|
||||
// places the decoded results in m.
|
||||
// It does not reset m before unmarshaling.
|
||||
func (b *Buffer) Unmarshal(m Message) error { |
||||
err := UnmarshalMerge(b.Unread(), m) |
||||
b.idx = len(b.buf) |
||||
return err |
||||
} |
||||
|
||||
type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields } |
||||
|
||||
func (m *unknownFields) String() string { panic("not implemented") } |
||||
func (m *unknownFields) Reset() { panic("not implemented") } |
||||
func (m *unknownFields) ProtoMessage() { panic("not implemented") } |
||||
|
||||
// DebugPrint dumps the encoded bytes of b with a header and footer including s
|
||||
// to stdout. This is only intended for debugging.
|
||||
func (*Buffer) DebugPrint(s string, b []byte) { |
||||
m := MessageReflect(new(unknownFields)) |
||||
m.SetUnknown(b) |
||||
b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface()) |
||||
fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s) |
||||
} |
||||
|
||||
// EncodeVarint appends an unsigned varint encoding to the buffer.
|
||||
func (b *Buffer) EncodeVarint(v uint64) error { |
||||
b.buf = protowire.AppendVarint(b.buf, v) |
||||
return nil |
||||
} |
||||
|
||||
// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer.
|
||||
func (b *Buffer) EncodeZigzag32(v uint64) error { |
||||
return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) |
||||
} |
||||
|
||||
// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer.
|
||||
func (b *Buffer) EncodeZigzag64(v uint64) error { |
||||
return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63)))) |
||||
} |
||||
|
||||
// EncodeFixed32 appends a 32-bit little-endian integer to the buffer.
|
||||
func (b *Buffer) EncodeFixed32(v uint64) error { |
||||
b.buf = protowire.AppendFixed32(b.buf, uint32(v)) |
||||
return nil |
||||
} |
||||
|
||||
// EncodeFixed64 appends a 64-bit little-endian integer to the buffer.
|
||||
func (b *Buffer) EncodeFixed64(v uint64) error { |
||||
b.buf = protowire.AppendFixed64(b.buf, uint64(v)) |
||||
return nil |
||||
} |
||||
|
||||
// EncodeRawBytes appends a length-prefixed raw bytes to the buffer.
|
||||
func (b *Buffer) EncodeRawBytes(v []byte) error { |
||||
b.buf = protowire.AppendBytes(b.buf, v) |
||||
return nil |
||||
} |
||||
|
||||
// EncodeStringBytes appends a length-prefixed raw bytes to the buffer.
|
||||
// It does not validate whether v contains valid UTF-8.
|
||||
func (b *Buffer) EncodeStringBytes(v string) error { |
||||
b.buf = protowire.AppendString(b.buf, v) |
||||
return nil |
||||
} |
||||
|
||||
// EncodeMessage appends a length-prefixed encoded message to the buffer.
|
||||
func (b *Buffer) EncodeMessage(m Message) error { |
||||
var err error |
||||
b.buf = protowire.AppendVarint(b.buf, uint64(Size(m))) |
||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic) |
||||
return err |
||||
} |
||||
|
||||
// DecodeVarint consumes an encoded unsigned varint from the buffer.
|
||||
func (b *Buffer) DecodeVarint() (uint64, error) { |
||||
v, n := protowire.ConsumeVarint(b.buf[b.idx:]) |
||||
if n < 0 { |
||||
return 0, protowire.ParseError(n) |
||||
} |
||||
b.idx += n |
||||
return uint64(v), nil |
||||
} |
||||
|
||||
// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer.
|
||||
func (b *Buffer) DecodeZigzag32() (uint64, error) { |
||||
v, err := b.DecodeVarint() |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil |
||||
} |
||||
|
||||
// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer.
|
||||
func (b *Buffer) DecodeZigzag64() (uint64, error) { |
||||
v, err := b.DecodeVarint() |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil |
||||
} |
||||
|
||||
// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer.
|
||||
func (b *Buffer) DecodeFixed32() (uint64, error) { |
||||
v, n := protowire.ConsumeFixed32(b.buf[b.idx:]) |
||||
if n < 0 { |
||||
return 0, protowire.ParseError(n) |
||||
} |
||||
b.idx += n |
||||
return uint64(v), nil |
||||
} |
||||
|
||||
// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer.
|
||||
func (b *Buffer) DecodeFixed64() (uint64, error) { |
||||
v, n := protowire.ConsumeFixed64(b.buf[b.idx:]) |
||||
if n < 0 { |
||||
return 0, protowire.ParseError(n) |
||||
} |
||||
b.idx += n |
||||
return uint64(v), nil |
||||
} |
||||
|
||||
// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer.
|
||||
// If alloc is specified, it returns a copy the raw bytes
|
||||
// rather than a sub-slice of the buffer.
|
||||
func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) { |
||||
v, n := protowire.ConsumeBytes(b.buf[b.idx:]) |
||||
if n < 0 { |
||||
return nil, protowire.ParseError(n) |
||||
} |
||||
b.idx += n |
||||
if alloc { |
||||
v = append([]byte(nil), v...) |
||||
} |
||||
return v, nil |
||||
} |
||||
|
||||
// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer.
|
||||
// It does not validate whether the raw bytes contain valid UTF-8.
|
||||
func (b *Buffer) DecodeStringBytes() (string, error) { |
||||
v, n := protowire.ConsumeString(b.buf[b.idx:]) |
||||
if n < 0 { |
||||
return "", protowire.ParseError(n) |
||||
} |
||||
b.idx += n |
||||
return v, nil |
||||
} |
||||
|
||||
// DecodeMessage consumes a length-prefixed message from the buffer.
|
||||
// It does not reset m before unmarshaling.
|
||||
func (b *Buffer) DecodeMessage(m Message) error { |
||||
v, err := b.DecodeRawBytes(false) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return UnmarshalMerge(v, m) |
||||
} |
||||
|
||||
// DecodeGroup consumes a message group from the buffer.
|
||||
// It assumes that the start group marker has already been consumed and
|
||||
// consumes all bytes until (and including the end group marker).
|
||||
// It does not reset m before unmarshaling.
|
||||
func (b *Buffer) DecodeGroup(m Message) error { |
||||
v, n, err := consumeGroup(b.buf[b.idx:]) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
b.idx += n |
||||
return UnmarshalMerge(v, m) |
||||
} |
||||
|
||||
// consumeGroup parses b until it finds an end group marker, returning
|
||||
// the raw bytes of the message (excluding the end group marker) and the
|
||||
// the total length of the message (including the end group marker).
|
||||
func consumeGroup(b []byte) ([]byte, int, error) { |
||||
b0 := b |
||||
depth := 1 // assume this follows a start group marker
|
||||
for { |
||||
_, wtyp, tagLen := protowire.ConsumeTag(b) |
||||
if tagLen < 0 { |
||||
return nil, 0, protowire.ParseError(tagLen) |
||||
} |
||||
b = b[tagLen:] |
||||
|
||||
var valLen int |
||||
switch wtyp { |
||||
case protowire.VarintType: |
||||
_, valLen = protowire.ConsumeVarint(b) |
||||
case protowire.Fixed32Type: |
||||
_, valLen = protowire.ConsumeFixed32(b) |
||||
case protowire.Fixed64Type: |
||||
_, valLen = protowire.ConsumeFixed64(b) |
||||
case protowire.BytesType: |
||||
_, valLen = protowire.ConsumeBytes(b) |
||||
case protowire.StartGroupType: |
||||
depth++ |
||||
case protowire.EndGroupType: |
||||
depth-- |
||||
default: |
||||
return nil, 0, errors.New("proto: cannot parse reserved wire type") |
||||
} |
||||
if valLen < 0 { |
||||
return nil, 0, protowire.ParseError(valLen) |
||||
} |
||||
b = b[valLen:] |
||||
|
||||
if depth == 0 { |
||||
return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil |
||||
} |
||||
} |
||||
} |
||||
@ -1,63 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
import ( |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
) |
||||
|
||||
// SetDefaults sets unpopulated scalar fields to their default values.
|
||||
// Fields within a oneof are not set even if they have a default value.
|
||||
// SetDefaults is recursively called upon any populated message fields.
|
||||
func SetDefaults(m Message) { |
||||
if m != nil { |
||||
setDefaults(MessageReflect(m)) |
||||
} |
||||
} |
||||
|
||||
func setDefaults(m protoreflect.Message) { |
||||
fds := m.Descriptor().Fields() |
||||
for i := 0; i < fds.Len(); i++ { |
||||
fd := fds.Get(i) |
||||
if !m.Has(fd) { |
||||
if fd.HasDefault() && fd.ContainingOneof() == nil { |
||||
v := fd.Default() |
||||
if fd.Kind() == protoreflect.BytesKind { |
||||
v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes
|
||||
} |
||||
m.Set(fd, v) |
||||
} |
||||
continue |
||||
} |
||||
} |
||||
|
||||
m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { |
||||
switch { |
||||
// Handle singular message.
|
||||
case fd.Cardinality() != protoreflect.Repeated: |
||||
if fd.Message() != nil { |
||||
setDefaults(m.Get(fd).Message()) |
||||
} |
||||
// Handle list of messages.
|
||||
case fd.IsList(): |
||||
if fd.Message() != nil { |
||||
ls := m.Get(fd).List() |
||||
for i := 0; i < ls.Len(); i++ { |
||||
setDefaults(ls.Get(i).Message()) |
||||
} |
||||
} |
||||
// Handle map of messages.
|
||||
case fd.IsMap(): |
||||
if fd.MapValue().Message() != nil { |
||||
ms := m.Get(fd).Map() |
||||
ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { |
||||
setDefaults(v.Message()) |
||||
return true |
||||
}) |
||||
} |
||||
} |
||||
return true |
||||
}) |
||||
} |
||||
@ -1,113 +0,0 @@
|
||||
// Copyright 2018 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 proto |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"strconv" |
||||
|
||||
protoV2 "google.golang.org/protobuf/proto" |
||||
) |
||||
|
||||
var ( |
||||
// Deprecated: No longer returned.
|
||||
ErrNil = errors.New("proto: Marshal called with nil") |
||||
|
||||
// Deprecated: No longer returned.
|
||||
ErrTooLarge = errors.New("proto: message encodes to over 2 GB") |
||||
|
||||
// Deprecated: No longer returned.
|
||||
ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") |
||||
) |
||||
|
||||
// Deprecated: Do not use.
|
||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } |
||||
|
||||
// Deprecated: Do not use.
|
||||
func GetStats() Stats { return Stats{} } |
||||
|
||||
// Deprecated: Do not use.
|
||||
func MarshalMessageSet(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func UnmarshalMessageSet([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func UnmarshalMessageSetJSON([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func RegisterMessageSetType(Message, int32, string) {} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func EnumName(m map[int32]string, v int32) string { |
||||
s, ok := m[v] |
||||
if ok { |
||||
return s |
||||
} |
||||
return strconv.Itoa(int(v)) |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { |
||||
if data[0] == '"' { |
||||
// New style: enums are strings.
|
||||
var repr string |
||||
if err := json.Unmarshal(data, &repr); err != nil { |
||||
return -1, err |
||||
} |
||||
val, ok := m[repr] |
||||
if !ok { |
||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) |
||||
} |
||||
return val, nil |
||||
} |
||||
// Old style: enums are ints.
|
||||
var val int32 |
||||
if err := json.Unmarshal(data, &val); err != nil { |
||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) |
||||
} |
||||
return val, nil |
||||
} |
||||
|
||||
// Deprecated: Do not use; this type existed for intenal-use only.
|
||||
type InternalMessageInfo struct{} |
||||
|
||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||
func (*InternalMessageInfo) DiscardUnknown(m Message) { |
||||
DiscardUnknown(m) |
||||
} |
||||
|
||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||
func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) { |
||||
return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m)) |
||||
} |
||||
|
||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||
func (*InternalMessageInfo) Merge(dst, src Message) { |
||||
protoV2.Merge(MessageV2(dst), MessageV2(src)) |
||||
} |
||||
|
||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||
func (*InternalMessageInfo) Size(m Message) int { |
||||
return protoV2.Size(MessageV2(m)) |
||||
} |
||||
|
||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||
func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error { |
||||
return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m)) |
||||
} |
||||
@ -1,58 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
import ( |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
) |
||||
|
||||
// DiscardUnknown recursively discards all unknown fields from this message
|
||||
// and all embedded messages.
|
||||
//
|
||||
// When unmarshaling a message with unrecognized fields, the tags and values
|
||||
// of such fields are preserved in the Message. This allows a later call to
|
||||
// marshal to be able to produce a message that continues to have those
|
||||
// unrecognized fields. To avoid this, DiscardUnknown is used to
|
||||
// explicitly clear the unknown fields after unmarshaling.
|
||||
func DiscardUnknown(m Message) { |
||||
if m != nil { |
||||
discardUnknown(MessageReflect(m)) |
||||
} |
||||
} |
||||
|
||||
func discardUnknown(m protoreflect.Message) { |
||||
m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool { |
||||
switch { |
||||
// Handle singular message.
|
||||
case fd.Cardinality() != protoreflect.Repeated: |
||||
if fd.Message() != nil { |
||||
discardUnknown(m.Get(fd).Message()) |
||||
} |
||||
// Handle list of messages.
|
||||
case fd.IsList(): |
||||
if fd.Message() != nil { |
||||
ls := m.Get(fd).List() |
||||
for i := 0; i < ls.Len(); i++ { |
||||
discardUnknown(ls.Get(i).Message()) |
||||
} |
||||
} |
||||
// Handle map of messages.
|
||||
case fd.IsMap(): |
||||
if fd.MapValue().Message() != nil { |
||||
ms := m.Get(fd).Map() |
||||
ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { |
||||
discardUnknown(v.Message()) |
||||
return true |
||||
}) |
||||
} |
||||
} |
||||
return true |
||||
}) |
||||
|
||||
// Discard unknown fields.
|
||||
if len(m.GetUnknown()) > 0 { |
||||
m.SetUnknown(nil) |
||||
} |
||||
} |
||||
@ -1,356 +0,0 @@
|
||||
// Copyright 2010 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 proto |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"reflect" |
||||
|
||||
"google.golang.org/protobuf/encoding/protowire" |
||||
"google.golang.org/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
"google.golang.org/protobuf/runtime/protoiface" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
type ( |
||||
// ExtensionDesc represents an extension descriptor and
|
||||
// is used to interact with an extension field in a message.
|
||||
//
|
||||
// Variables of this type are generated in code by protoc-gen-go.
|
||||
ExtensionDesc = protoimpl.ExtensionInfo |
||||
|
||||
// ExtensionRange represents a range of message extensions.
|
||||
// Used in code generated by protoc-gen-go.
|
||||
ExtensionRange = protoiface.ExtensionRangeV1 |
||||
|
||||
// Deprecated: Do not use; this is an internal type.
|
||||
Extension = protoimpl.ExtensionFieldV1 |
||||
|
||||
// Deprecated: Do not use; this is an internal type.
|
||||
XXX_InternalExtensions = protoimpl.ExtensionFields |
||||
) |
||||
|
||||
// ErrMissingExtension reports whether the extension was not present.
|
||||
var ErrMissingExtension = errors.New("proto: missing extension") |
||||
|
||||
var errNotExtendable = errors.New("proto: not an extendable proto.Message") |
||||
|
||||
// HasExtension reports whether the extension field is present in m
|
||||
// either as an explicitly populated field or as an unknown field.
|
||||
func HasExtension(m Message, xt *ExtensionDesc) (has bool) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return false |
||||
} |
||||
|
||||
// Check whether any populated known field matches the field number.
|
||||
xtd := xt.TypeDescriptor() |
||||
if isValidExtension(mr.Descriptor(), xtd) { |
||||
has = mr.Has(xtd) |
||||
} else { |
||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { |
||||
has = int32(fd.Number()) == xt.Field |
||||
return !has |
||||
}) |
||||
} |
||||
|
||||
// Check whether any unknown field matches the field number.
|
||||
for b := mr.GetUnknown(); !has && len(b) > 0; { |
||||
num, _, n := protowire.ConsumeField(b) |
||||
has = int32(num) == xt.Field |
||||
b = b[n:] |
||||
} |
||||
return has |
||||
} |
||||
|
||||
// ClearExtension removes the extension field from m
|
||||
// either as an explicitly populated field or as an unknown field.
|
||||
func ClearExtension(m Message, xt *ExtensionDesc) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return |
||||
} |
||||
|
||||
xtd := xt.TypeDescriptor() |
||||
if isValidExtension(mr.Descriptor(), xtd) { |
||||
mr.Clear(xtd) |
||||
} else { |
||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { |
||||
if int32(fd.Number()) == xt.Field { |
||||
mr.Clear(fd) |
||||
return false |
||||
} |
||||
return true |
||||
}) |
||||
} |
||||
clearUnknown(mr, fieldNum(xt.Field)) |
||||
} |
||||
|
||||
// ClearAllExtensions clears all extensions from m.
|
||||
// This includes populated fields and unknown fields in the extension range.
|
||||
func ClearAllExtensions(m Message) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return |
||||
} |
||||
|
||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { |
||||
if fd.IsExtension() { |
||||
mr.Clear(fd) |
||||
} |
||||
return true |
||||
}) |
||||
clearUnknown(mr, mr.Descriptor().ExtensionRanges()) |
||||
} |
||||
|
||||
// GetExtension retrieves a proto2 extended field from m.
|
||||
//
|
||||
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
||||
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
||||
// If the field is not present, then the default value is returned (if one is specified),
|
||||
// otherwise ErrMissingExtension is reported.
|
||||
//
|
||||
// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil),
|
||||
// then GetExtension returns the raw encoded bytes for the extension field.
|
||||
func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { |
||||
return nil, errNotExtendable |
||||
} |
||||
|
||||
// Retrieve the unknown fields for this extension field.
|
||||
var bo protoreflect.RawFields |
||||
for bi := mr.GetUnknown(); len(bi) > 0; { |
||||
num, _, n := protowire.ConsumeField(bi) |
||||
if int32(num) == xt.Field { |
||||
bo = append(bo, bi[:n]...) |
||||
} |
||||
bi = bi[n:] |
||||
} |
||||
|
||||
// For type incomplete descriptors, only retrieve the unknown fields.
|
||||
if xt.ExtensionType == nil { |
||||
return []byte(bo), nil |
||||
} |
||||
|
||||
// If the extension field only exists as unknown fields, unmarshal it.
|
||||
// This is rarely done since proto.Unmarshal eagerly unmarshals extensions.
|
||||
xtd := xt.TypeDescriptor() |
||||
if !isValidExtension(mr.Descriptor(), xtd) { |
||||
return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) |
||||
} |
||||
if !mr.Has(xtd) && len(bo) > 0 { |
||||
m2 := mr.New() |
||||
if err := (proto.UnmarshalOptions{ |
||||
Resolver: extensionResolver{xt}, |
||||
}.Unmarshal(bo, m2.Interface())); err != nil { |
||||
return nil, err |
||||
} |
||||
if m2.Has(xtd) { |
||||
mr.Set(xtd, m2.Get(xtd)) |
||||
clearUnknown(mr, fieldNum(xt.Field)) |
||||
} |
||||
} |
||||
|
||||
// Check whether the message has the extension field set or a default.
|
||||
var pv protoreflect.Value |
||||
switch { |
||||
case mr.Has(xtd): |
||||
pv = mr.Get(xtd) |
||||
case xtd.HasDefault(): |
||||
pv = xtd.Default() |
||||
default: |
||||
return nil, ErrMissingExtension |
||||
} |
||||
|
||||
v := xt.InterfaceOf(pv) |
||||
rv := reflect.ValueOf(v) |
||||
if isScalarKind(rv.Kind()) { |
||||
rv2 := reflect.New(rv.Type()) |
||||
rv2.Elem().Set(rv) |
||||
v = rv2.Interface() |
||||
} |
||||
return v, nil |
||||
} |
||||
|
||||
// extensionResolver is a custom extension resolver that stores a single
|
||||
// extension type that takes precedence over the global registry.
|
||||
type extensionResolver struct{ xt protoreflect.ExtensionType } |
||||
|
||||
func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { |
||||
if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { |
||||
return r.xt, nil |
||||
} |
||||
return protoregistry.GlobalTypes.FindExtensionByName(field) |
||||
} |
||||
|
||||
func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { |
||||
if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field { |
||||
return r.xt, nil |
||||
} |
||||
return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) |
||||
} |
||||
|
||||
// GetExtensions returns a list of the extensions values present in m,
|
||||
// corresponding with the provided list of extension descriptors, xts.
|
||||
// If an extension is missing in m, the corresponding value is nil.
|
||||
func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return nil, errNotExtendable |
||||
} |
||||
|
||||
vs := make([]interface{}, len(xts)) |
||||
for i, xt := range xts { |
||||
v, err := GetExtension(m, xt) |
||||
if err != nil { |
||||
if err == ErrMissingExtension { |
||||
continue |
||||
} |
||||
return vs, err |
||||
} |
||||
vs[i] = v |
||||
} |
||||
return vs, nil |
||||
} |
||||
|
||||
// SetExtension sets an extension field in m to the provided value.
|
||||
func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { |
||||
return errNotExtendable |
||||
} |
||||
|
||||
rv := reflect.ValueOf(v) |
||||
if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) { |
||||
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType) |
||||
} |
||||
if rv.Kind() == reflect.Ptr { |
||||
if rv.IsNil() { |
||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", v) |
||||
} |
||||
if isScalarKind(rv.Elem().Kind()) { |
||||
v = rv.Elem().Interface() |
||||
} |
||||
} |
||||
|
||||
xtd := xt.TypeDescriptor() |
||||
if !isValidExtension(mr.Descriptor(), xtd) { |
||||
return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) |
||||
} |
||||
mr.Set(xtd, xt.ValueOf(v)) |
||||
clearUnknown(mr, fieldNum(xt.Field)) |
||||
return nil |
||||
} |
||||
|
||||
// SetRawExtension inserts b into the unknown fields of m.
|
||||
//
|
||||
// Deprecated: Use Message.ProtoReflect.SetUnknown instead.
|
||||
func SetRawExtension(m Message, fnum int32, b []byte) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return |
||||
} |
||||
|
||||
// Verify that the raw field is valid.
|
||||
for b0 := b; len(b0) > 0; { |
||||
num, _, n := protowire.ConsumeField(b0) |
||||
if int32(num) != fnum { |
||||
panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum)) |
||||
} |
||||
b0 = b0[n:] |
||||
} |
||||
|
||||
ClearExtension(m, &ExtensionDesc{Field: fnum}) |
||||
mr.SetUnknown(append(mr.GetUnknown(), b...)) |
||||
} |
||||
|
||||
// ExtensionDescs returns a list of extension descriptors found in m,
|
||||
// containing descriptors for both populated extension fields in m and
|
||||
// also unknown fields of m that are in the extension range.
|
||||
// For the later case, an type incomplete descriptor is provided where only
|
||||
// the ExtensionDesc.Field field is populated.
|
||||
// The order of the extension descriptors is undefined.
|
||||
func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { |
||||
return nil, errNotExtendable |
||||
} |
||||
|
||||
// Collect a set of known extension descriptors.
|
||||
extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) |
||||
mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { |
||||
if fd.IsExtension() { |
||||
xt := fd.(protoreflect.ExtensionTypeDescriptor) |
||||
if xd, ok := xt.Type().(*ExtensionDesc); ok { |
||||
extDescs[fd.Number()] = xd |
||||
} |
||||
} |
||||
return true |
||||
}) |
||||
|
||||
// Collect a set of unknown extension descriptors.
|
||||
extRanges := mr.Descriptor().ExtensionRanges() |
||||
for b := mr.GetUnknown(); len(b) > 0; { |
||||
num, _, n := protowire.ConsumeField(b) |
||||
if extRanges.Has(num) && extDescs[num] == nil { |
||||
extDescs[num] = nil |
||||
} |
||||
b = b[n:] |
||||
} |
||||
|
||||
// Transpose the set of descriptors into a list.
|
||||
var xts []*ExtensionDesc |
||||
for num, xt := range extDescs { |
||||
if xt == nil { |
||||
xt = &ExtensionDesc{Field: int32(num)} |
||||
} |
||||
xts = append(xts, xt) |
||||
} |
||||
return xts, nil |
||||
} |
||||
|
||||
// isValidExtension reports whether xtd is a valid extension descriptor for md.
|
||||
func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { |
||||
return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number()) |
||||
} |
||||
|
||||
// isScalarKind reports whether k is a protobuf scalar kind (except bytes).
|
||||
// This function exists for historical reasons since the representation of
|
||||
// scalars differs between v1 and v2, where v1 uses *T and v2 uses T.
|
||||
func isScalarKind(k reflect.Kind) bool { |
||||
switch k { |
||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: |
||||
return true |
||||
default: |
||||
return false |
||||
} |
||||
} |
||||
|
||||
// clearUnknown removes unknown fields from m where remover.Has reports true.
|
||||
func clearUnknown(m protoreflect.Message, remover interface { |
||||
Has(protoreflect.FieldNumber) bool |
||||
}) { |
||||
var bo protoreflect.RawFields |
||||
for bi := m.GetUnknown(); len(bi) > 0; { |
||||
num, _, n := protowire.ConsumeField(bi) |
||||
if !remover.Has(num) { |
||||
bo = append(bo, bi[:n]...) |
||||
} |
||||
bi = bi[n:] |
||||
} |
||||
if bi := m.GetUnknown(); len(bi) != len(bo) { |
||||
m.SetUnknown(bo) |
||||
} |
||||
} |
||||
|
||||
type fieldNum protoreflect.FieldNumber |
||||
|
||||
func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool { |
||||
return protoreflect.FieldNumber(n1) == n2 |
||||
} |
||||
@ -1,306 +0,0 @@
|
||||
// Copyright 2010 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 proto |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
"strconv" |
||||
"strings" |
||||
"sync" |
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
// StructProperties represents protocol buffer type information for a
|
||||
// generated protobuf message in the open-struct API.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
type StructProperties struct { |
||||
// Prop are the properties for each field.
|
||||
//
|
||||
// Fields belonging to a oneof are stored in OneofTypes instead, with a
|
||||
// single Properties representing the parent oneof held here.
|
||||
//
|
||||
// The order of Prop matches the order of fields in the Go struct.
|
||||
// Struct fields that are not related to protobufs have a "XXX_" prefix
|
||||
// in the Properties.Name and must be ignored by the user.
|
||||
Prop []*Properties |
||||
|
||||
// OneofTypes contains information about the oneof fields in this message.
|
||||
// It is keyed by the protobuf field name.
|
||||
OneofTypes map[string]*OneofProperties |
||||
} |
||||
|
||||
// Properties represents the type information for a protobuf message field.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
type Properties struct { |
||||
// Name is a placeholder name with little meaningful semantic value.
|
||||
// If the name has an "XXX_" prefix, the entire Properties must be ignored.
|
||||
Name string |
||||
// OrigName is the protobuf field name or oneof name.
|
||||
OrigName string |
||||
// JSONName is the JSON name for the protobuf field.
|
||||
JSONName string |
||||
// Enum is a placeholder name for enums.
|
||||
// For historical reasons, this is neither the Go name for the enum,
|
||||
// nor the protobuf name for the enum.
|
||||
Enum string // Deprecated: Do not use.
|
||||
// Weak contains the full name of the weakly referenced message.
|
||||
Weak string |
||||
// Wire is a string representation of the wire type.
|
||||
Wire string |
||||
// WireType is the protobuf wire type for the field.
|
||||
WireType int |
||||
// Tag is the protobuf field number.
|
||||
Tag int |
||||
// Required reports whether this is a required field.
|
||||
Required bool |
||||
// Optional reports whether this is a optional field.
|
||||
Optional bool |
||||
// Repeated reports whether this is a repeated field.
|
||||
Repeated bool |
||||
// Packed reports whether this is a packed repeated field of scalars.
|
||||
Packed bool |
||||
// Proto3 reports whether this field operates under the proto3 syntax.
|
||||
Proto3 bool |
||||
// Oneof reports whether this field belongs within a oneof.
|
||||
Oneof bool |
||||
|
||||
// Default is the default value in string form.
|
||||
Default string |
||||
// HasDefault reports whether the field has a default value.
|
||||
HasDefault bool |
||||
|
||||
// MapKeyProp is the properties for the key field for a map field.
|
||||
MapKeyProp *Properties |
||||
// MapValProp is the properties for the value field for a map field.
|
||||
MapValProp *Properties |
||||
} |
||||
|
||||
// OneofProperties represents the type information for a protobuf oneof.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
type OneofProperties struct { |
||||
// Type is a pointer to the generated wrapper type for the field value.
|
||||
// This is nil for messages that are not in the open-struct API.
|
||||
Type reflect.Type |
||||
// Field is the index into StructProperties.Prop for the containing oneof.
|
||||
Field int |
||||
// Prop is the properties for the field.
|
||||
Prop *Properties |
||||
} |
||||
|
||||
// String formats the properties in the protobuf struct field tag style.
|
||||
func (p *Properties) String() string { |
||||
s := p.Wire |
||||
s += "," + strconv.Itoa(p.Tag) |
||||
if p.Required { |
||||
s += ",req" |
||||
} |
||||
if p.Optional { |
||||
s += ",opt" |
||||
} |
||||
if p.Repeated { |
||||
s += ",rep" |
||||
} |
||||
if p.Packed { |
||||
s += ",packed" |
||||
} |
||||
s += ",name=" + p.OrigName |
||||
if p.JSONName != "" { |
||||
s += ",json=" + p.JSONName |
||||
} |
||||
if len(p.Enum) > 0 { |
||||
s += ",enum=" + p.Enum |
||||
} |
||||
if len(p.Weak) > 0 { |
||||
s += ",weak=" + p.Weak |
||||
} |
||||
if p.Proto3 { |
||||
s += ",proto3" |
||||
} |
||||
if p.Oneof { |
||||
s += ",oneof" |
||||
} |
||||
if p.HasDefault { |
||||
s += ",def=" + p.Default |
||||
} |
||||
return s |
||||
} |
||||
|
||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||
func (p *Properties) Parse(tag string) { |
||||
// For example: "bytes,49,opt,name=foo,def=hello!"
|
||||
for len(tag) > 0 { |
||||
i := strings.IndexByte(tag, ',') |
||||
if i < 0 { |
||||
i = len(tag) |
||||
} |
||||
switch s := tag[:i]; { |
||||
case strings.HasPrefix(s, "name="): |
||||
p.OrigName = s[len("name="):] |
||||
case strings.HasPrefix(s, "json="): |
||||
p.JSONName = s[len("json="):] |
||||
case strings.HasPrefix(s, "enum="): |
||||
p.Enum = s[len("enum="):] |
||||
case strings.HasPrefix(s, "weak="): |
||||
p.Weak = s[len("weak="):] |
||||
case strings.Trim(s, "0123456789") == "": |
||||
n, _ := strconv.ParseUint(s, 10, 32) |
||||
p.Tag = int(n) |
||||
case s == "opt": |
||||
p.Optional = true |
||||
case s == "req": |
||||
p.Required = true |
||||
case s == "rep": |
||||
p.Repeated = true |
||||
case s == "varint" || s == "zigzag32" || s == "zigzag64": |
||||
p.Wire = s |
||||
p.WireType = WireVarint |
||||
case s == "fixed32": |
||||
p.Wire = s |
||||
p.WireType = WireFixed32 |
||||
case s == "fixed64": |
||||
p.Wire = s |
||||
p.WireType = WireFixed64 |
||||
case s == "bytes": |
||||
p.Wire = s |
||||
p.WireType = WireBytes |
||||
case s == "group": |
||||
p.Wire = s |
||||
p.WireType = WireStartGroup |
||||
case s == "packed": |
||||
p.Packed = true |
||||
case s == "proto3": |
||||
p.Proto3 = true |
||||
case s == "oneof": |
||||
p.Oneof = true |
||||
case strings.HasPrefix(s, "def="): |
||||
// The default tag is special in that everything afterwards is the
|
||||
// default regardless of the presence of commas.
|
||||
p.HasDefault = true |
||||
p.Default, i = tag[len("def="):], len(tag) |
||||
} |
||||
tag = strings.TrimPrefix(tag[i:], ",") |
||||
} |
||||
} |
||||
|
||||
// Init populates the properties from a protocol buffer struct tag.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { |
||||
p.Name = name |
||||
p.OrigName = name |
||||
if tag == "" { |
||||
return |
||||
} |
||||
p.Parse(tag) |
||||
|
||||
if typ != nil && typ.Kind() == reflect.Map { |
||||
p.MapKeyProp = new(Properties) |
||||
p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil) |
||||
p.MapValProp = new(Properties) |
||||
p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil) |
||||
} |
||||
} |
||||
|
||||
var propertiesCache sync.Map // map[reflect.Type]*StructProperties
|
||||
|
||||
// GetProperties returns the list of properties for the type represented by t,
|
||||
// which must be a generated protocol buffer message in the open-struct API,
|
||||
// where protobuf message fields are represented by exported Go struct fields.
|
||||
//
|
||||
// Deprecated: Use protobuf reflection instead.
|
||||
func GetProperties(t reflect.Type) *StructProperties { |
||||
if p, ok := propertiesCache.Load(t); ok { |
||||
return p.(*StructProperties) |
||||
} |
||||
p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) |
||||
return p.(*StructProperties) |
||||
} |
||||
|
||||
func newProperties(t reflect.Type) *StructProperties { |
||||
if t.Kind() != reflect.Struct { |
||||
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) |
||||
} |
||||
|
||||
var hasOneof bool |
||||
prop := new(StructProperties) |
||||
|
||||
// Construct a list of properties for each field in the struct.
|
||||
for i := 0; i < t.NumField(); i++ { |
||||
p := new(Properties) |
||||
f := t.Field(i) |
||||
tagField := f.Tag.Get("protobuf") |
||||
p.Init(f.Type, f.Name, tagField, &f) |
||||
|
||||
tagOneof := f.Tag.Get("protobuf_oneof") |
||||
if tagOneof != "" { |
||||
hasOneof = true |
||||
p.OrigName = tagOneof |
||||
} |
||||
|
||||
// Rename unrelated struct fields with the "XXX_" prefix since so much
|
||||
// user code simply checks for this to exclude special fields.
|
||||
if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") { |
||||
p.Name = "XXX_" + p.Name |
||||
p.OrigName = "XXX_" + p.OrigName |
||||
} else if p.Weak != "" { |
||||
p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field
|
||||
} |
||||
|
||||
prop.Prop = append(prop.Prop, p) |
||||
} |
||||
|
||||
// Construct a mapping of oneof field names to properties.
|
||||
if hasOneof { |
||||
var oneofWrappers []interface{} |
||||
if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok { |
||||
oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{}) |
||||
} |
||||
if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok { |
||||
oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{}) |
||||
} |
||||
if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok { |
||||
if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok { |
||||
oneofWrappers = m.ProtoMessageInfo().OneofWrappers |
||||
} |
||||
} |
||||
|
||||
prop.OneofTypes = make(map[string]*OneofProperties) |
||||
for _, wrapper := range oneofWrappers { |
||||
p := &OneofProperties{ |
||||
Type: reflect.ValueOf(wrapper).Type(), // *T
|
||||
Prop: new(Properties), |
||||
} |
||||
f := p.Type.Elem().Field(0) |
||||
p.Prop.Name = f.Name |
||||
p.Prop.Parse(f.Tag.Get("protobuf")) |
||||
|
||||
// Determine the struct field that contains this oneof.
|
||||
// Each wrapper is assignable to exactly one parent field.
|
||||
var foundOneof bool |
||||
for i := 0; i < t.NumField() && !foundOneof; i++ { |
||||
if p.Type.AssignableTo(t.Field(i).Type) { |
||||
p.Field = i |
||||
foundOneof = true |
||||
} |
||||
} |
||||
if !foundOneof { |
||||
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) |
||||
} |
||||
prop.OneofTypes[p.Prop.OrigName] = p |
||||
} |
||||
} |
||||
|
||||
return prop |
||||
} |
||||
|
||||
func (sp *StructProperties) Len() int { return len(sp.Prop) } |
||||
func (sp *StructProperties) Less(i, j int) bool { return false } |
||||
func (sp *StructProperties) Swap(i, j int) { return } |
||||
@ -1,167 +0,0 @@
|
||||
// Copyright 2019 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 proto provides functionality for handling protocol buffer messages.
|
||||
// In particular, it provides marshaling and unmarshaling between a protobuf
|
||||
// message and the binary wire format.
|
||||
//
|
||||
// See https://developers.google.com/protocol-buffers/docs/gotutorial for
|
||||
// more information.
|
||||
//
|
||||
// Deprecated: Use the "google.golang.org/protobuf/proto" package instead.
|
||||
package proto |
||||
|
||||
import ( |
||||
protoV2 "google.golang.org/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/runtime/protoiface" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
const ( |
||||
ProtoPackageIsVersion1 = true |
||||
ProtoPackageIsVersion2 = true |
||||
ProtoPackageIsVersion3 = true |
||||
ProtoPackageIsVersion4 = true |
||||
) |
||||
|
||||
// GeneratedEnum is any enum type generated by protoc-gen-go
|
||||
// which is a named int32 kind.
|
||||
// This type exists for documentation purposes.
|
||||
type GeneratedEnum interface{} |
||||
|
||||
// GeneratedMessage is any message type generated by protoc-gen-go
|
||||
// which is a pointer to a named struct kind.
|
||||
// This type exists for documentation purposes.
|
||||
type GeneratedMessage interface{} |
||||
|
||||
// Message is a protocol buffer message.
|
||||
//
|
||||
// This is the v1 version of the message interface and is marginally better
|
||||
// than an empty interface as it lacks any method to programatically interact
|
||||
// with the contents of the message.
|
||||
//
|
||||
// A v2 message is declared in "google.golang.org/protobuf/proto".Message and
|
||||
// exposes protobuf reflection as a first-class feature of the interface.
|
||||
//
|
||||
// To convert a v1 message to a v2 message, use the MessageV2 function.
|
||||
// To convert a v2 message to a v1 message, use the MessageV1 function.
|
||||
type Message = protoiface.MessageV1 |
||||
|
||||
// MessageV1 converts either a v1 or v2 message to a v1 message.
|
||||
// It returns nil if m is nil.
|
||||
func MessageV1(m GeneratedMessage) protoiface.MessageV1 { |
||||
return protoimpl.X.ProtoMessageV1Of(m) |
||||
} |
||||
|
||||
// MessageV2 converts either a v1 or v2 message to a v2 message.
|
||||
// It returns nil if m is nil.
|
||||
func MessageV2(m GeneratedMessage) protoV2.Message { |
||||
return protoimpl.X.ProtoMessageV2Of(m) |
||||
} |
||||
|
||||
// MessageReflect returns a reflective view for a message.
|
||||
// It returns nil if m is nil.
|
||||
func MessageReflect(m Message) protoreflect.Message { |
||||
return protoimpl.X.MessageOf(m) |
||||
} |
||||
|
||||
// Marshaler is implemented by messages that can marshal themselves.
|
||||
// This interface is used by the following functions: Size, Marshal,
|
||||
// Buffer.Marshal, and Buffer.EncodeMessage.
|
||||
//
|
||||
// Deprecated: Do not implement.
|
||||
type Marshaler interface { |
||||
// Marshal formats the encoded bytes of the message.
|
||||
// It should be deterministic and emit valid protobuf wire data.
|
||||
// The caller takes ownership of the returned buffer.
|
||||
Marshal() ([]byte, error) |
||||
} |
||||
|
||||
// Unmarshaler is implemented by messages that can unmarshal themselves.
|
||||
// This interface is used by the following functions: Unmarshal, UnmarshalMerge,
|
||||
// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup.
|
||||
//
|
||||
// Deprecated: Do not implement.
|
||||
type Unmarshaler interface { |
||||
// Unmarshal parses the encoded bytes of the protobuf wire input.
|
||||
// The provided buffer is only valid for during method call.
|
||||
// It should not reset the receiver message.
|
||||
Unmarshal([]byte) error |
||||
} |
||||
|
||||
// Merger is implemented by messages that can merge themselves.
|
||||
// This interface is used by the following functions: Clone and Merge.
|
||||
//
|
||||
// Deprecated: Do not implement.
|
||||
type Merger interface { |
||||
// Merge merges the contents of src into the receiver message.
|
||||
// It clones all data structures in src such that it aliases no mutable
|
||||
// memory referenced by src.
|
||||
Merge(src Message) |
||||
} |
||||
|
||||
// RequiredNotSetError is an error type returned when
|
||||
// marshaling or unmarshaling a message with missing required fields.
|
||||
type RequiredNotSetError struct { |
||||
err error |
||||
} |
||||
|
||||
func (e *RequiredNotSetError) Error() string { |
||||
if e.err != nil { |
||||
return e.err.Error() |
||||
} |
||||
return "proto: required field not set" |
||||
} |
||||
func (e *RequiredNotSetError) RequiredNotSet() bool { |
||||
return true |
||||
} |
||||
|
||||
func checkRequiredNotSet(m protoV2.Message) error { |
||||
if err := protoV2.CheckInitialized(m); err != nil { |
||||
return &RequiredNotSetError{err: err} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Clone returns a deep copy of src.
|
||||
func Clone(src Message) Message { |
||||
return MessageV1(protoV2.Clone(MessageV2(src))) |
||||
} |
||||
|
||||
// Merge merges src into dst, which must be messages of the same type.
|
||||
//
|
||||
// Populated scalar fields in src are copied to dst, while populated
|
||||
// singular messages in src are merged into dst by recursively calling Merge.
|
||||
// The elements of every list field in src is appended to the corresponded
|
||||
// list fields in dst. The entries of every map field in src is copied into
|
||||
// the corresponding map field in dst, possibly replacing existing entries.
|
||||
// The unknown fields of src are appended to the unknown fields of dst.
|
||||
func Merge(dst, src Message) { |
||||
protoV2.Merge(MessageV2(dst), MessageV2(src)) |
||||
} |
||||
|
||||
// Equal reports whether two messages are equal.
|
||||
// If two messages marshal to the same bytes under deterministic serialization,
|
||||
// then Equal is guaranteed to report true.
|
||||
//
|
||||
// Two messages are equal if they are the same protobuf message type,
|
||||
// have the same set of populated known and extension field values,
|
||||
// and the same set of unknown fields values.
|
||||
//
|
||||
// Scalar values are compared with the equivalent of the == operator in Go,
|
||||
// except bytes values which are compared using bytes.Equal and
|
||||
// floating point values which specially treat NaNs as equal.
|
||||
// Message values are compared by recursively calling Equal.
|
||||
// Lists are equal if each element value is also equal.
|
||||
// Maps are equal if they have the same set of keys, where the pair of values
|
||||
// for each key is also equal.
|
||||
func Equal(x, y Message) bool { |
||||
return protoV2.Equal(MessageV2(x), MessageV2(y)) |
||||
} |
||||
|
||||
func isMessageSet(md protoreflect.MessageDescriptor) bool { |
||||
ms, ok := md.(interface{ IsMessageSet() bool }) |
||||
return ok && ms.IsMessageSet() |
||||
} |
||||
@ -1,317 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
import ( |
||||
"bytes" |
||||
"compress/gzip" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"reflect" |
||||
"strings" |
||||
"sync" |
||||
|
||||
"google.golang.org/protobuf/reflect/protodesc" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
// filePath is the path to the proto source file.
|
||||
type filePath = string // e.g., "google/protobuf/descriptor.proto"
|
||||
|
||||
// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto.
|
||||
type fileDescGZIP = []byte |
||||
|
||||
var fileCache sync.Map // map[filePath]fileDescGZIP
|
||||
|
||||
// RegisterFile is called from generated code to register the compressed
|
||||
// FileDescriptorProto with the file path for a proto source file.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead.
|
||||
func RegisterFile(s filePath, d fileDescGZIP) { |
||||
// Decompress the descriptor.
|
||||
zr, err := gzip.NewReader(bytes.NewReader(d)) |
||||
if err != nil { |
||||
panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) |
||||
} |
||||
b, err := ioutil.ReadAll(zr) |
||||
if err != nil { |
||||
panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) |
||||
} |
||||
|
||||
// Construct a protoreflect.FileDescriptor from the raw descriptor.
|
||||
// Note that DescBuilder.Build automatically registers the constructed
|
||||
// file descriptor with the v2 registry.
|
||||
protoimpl.DescBuilder{RawDescriptor: b}.Build() |
||||
|
||||
// Locally cache the raw descriptor form for the file.
|
||||
fileCache.Store(s, d) |
||||
} |
||||
|
||||
// FileDescriptor returns the compressed FileDescriptorProto given the file path
|
||||
// for a proto source file. It returns nil if not found.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead.
|
||||
func FileDescriptor(s filePath) fileDescGZIP { |
||||
if v, ok := fileCache.Load(s); ok { |
||||
return v.(fileDescGZIP) |
||||
} |
||||
|
||||
// Find the descriptor in the v2 registry.
|
||||
var b []byte |
||||
if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { |
||||
b, _ = Marshal(protodesc.ToFileDescriptorProto(fd)) |
||||
} |
||||
|
||||
// Locally cache the raw descriptor form for the file.
|
||||
if len(b) > 0 { |
||||
v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b)) |
||||
return v.(fileDescGZIP) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// enumName is the name of an enum. For historical reasons, the enum name is
|
||||
// neither the full Go name nor the full protobuf name of the enum.
|
||||
// The name is the dot-separated combination of just the proto package that the
|
||||
// enum is declared within followed by the Go type name of the generated enum.
|
||||
type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum"
|
||||
|
||||
// enumsByName maps enum values by name to their numeric counterpart.
|
||||
type enumsByName = map[string]int32 |
||||
|
||||
// enumsByNumber maps enum values by number to their name counterpart.
|
||||
type enumsByNumber = map[int32]string |
||||
|
||||
var enumCache sync.Map // map[enumName]enumsByName
|
||||
var numFilesCache sync.Map // map[protoreflect.FullName]int
|
||||
|
||||
// RegisterEnum is called from the generated code to register the mapping of
|
||||
// enum value names to enum numbers for the enum identified by s.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead.
|
||||
func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) { |
||||
if _, ok := enumCache.Load(s); ok { |
||||
panic("proto: duplicate enum registered: " + s) |
||||
} |
||||
enumCache.Store(s, m) |
||||
|
||||
// This does not forward registration to the v2 registry since this API
|
||||
// lacks sufficient information to construct a complete v2 enum descriptor.
|
||||
} |
||||
|
||||
// EnumValueMap returns the mapping from enum value names to enum numbers for
|
||||
// the enum of the given name. It returns nil if not found.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead.
|
||||
func EnumValueMap(s enumName) enumsByName { |
||||
if v, ok := enumCache.Load(s); ok { |
||||
return v.(enumsByName) |
||||
} |
||||
|
||||
// Check whether the cache is stale. If the number of files in the current
|
||||
// package differs, then it means that some enums may have been recently
|
||||
// registered upstream that we do not know about.
|
||||
var protoPkg protoreflect.FullName |
||||
if i := strings.LastIndexByte(s, '.'); i >= 0 { |
||||
protoPkg = protoreflect.FullName(s[:i]) |
||||
} |
||||
v, _ := numFilesCache.Load(protoPkg) |
||||
numFiles, _ := v.(int) |
||||
if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles { |
||||
return nil // cache is up-to-date; was not found earlier
|
||||
} |
||||
|
||||
// Update the enum cache for all enums declared in the given proto package.
|
||||
numFiles = 0 |
||||
protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool { |
||||
walkEnums(fd, func(ed protoreflect.EnumDescriptor) { |
||||
name := protoimpl.X.LegacyEnumName(ed) |
||||
if _, ok := enumCache.Load(name); !ok { |
||||
m := make(enumsByName) |
||||
evs := ed.Values() |
||||
for i := evs.Len() - 1; i >= 0; i-- { |
||||
ev := evs.Get(i) |
||||
m[string(ev.Name())] = int32(ev.Number()) |
||||
} |
||||
enumCache.LoadOrStore(name, m) |
||||
} |
||||
}) |
||||
numFiles++ |
||||
return true |
||||
}) |
||||
numFilesCache.Store(protoPkg, numFiles) |
||||
|
||||
// Check cache again for enum map.
|
||||
if v, ok := enumCache.Load(s); ok { |
||||
return v.(enumsByName) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// walkEnums recursively walks all enums declared in d.
|
||||
func walkEnums(d interface { |
||||
Enums() protoreflect.EnumDescriptors |
||||
Messages() protoreflect.MessageDescriptors |
||||
}, f func(protoreflect.EnumDescriptor)) { |
||||
eds := d.Enums() |
||||
for i := eds.Len() - 1; i >= 0; i-- { |
||||
f(eds.Get(i)) |
||||
} |
||||
mds := d.Messages() |
||||
for i := mds.Len() - 1; i >= 0; i-- { |
||||
walkEnums(mds.Get(i), f) |
||||
} |
||||
} |
||||
|
||||
// messageName is the full name of protobuf message.
|
||||
type messageName = string |
||||
|
||||
var messageTypeCache sync.Map // map[messageName]reflect.Type
|
||||
|
||||
// RegisterType is called from generated code to register the message Go type
|
||||
// for a message of the given name.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead.
|
||||
func RegisterType(m Message, s messageName) { |
||||
mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s)) |
||||
if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil { |
||||
panic(err) |
||||
} |
||||
messageTypeCache.Store(s, reflect.TypeOf(m)) |
||||
} |
||||
|
||||
// RegisterMapType is called from generated code to register the Go map type
|
||||
// for a protobuf message representing a map entry.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
func RegisterMapType(m interface{}, s messageName) { |
||||
t := reflect.TypeOf(m) |
||||
if t.Kind() != reflect.Map { |
||||
panic(fmt.Sprintf("invalid map kind: %v", t)) |
||||
} |
||||
if _, ok := messageTypeCache.Load(s); ok { |
||||
panic(fmt.Errorf("proto: duplicate proto message registered: %s", s)) |
||||
} |
||||
messageTypeCache.Store(s, t) |
||||
} |
||||
|
||||
// MessageType returns the message type for a named message.
|
||||
// It returns nil if not found.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead.
|
||||
func MessageType(s messageName) reflect.Type { |
||||
if v, ok := messageTypeCache.Load(s); ok { |
||||
return v.(reflect.Type) |
||||
} |
||||
|
||||
// Derive the message type from the v2 registry.
|
||||
var t reflect.Type |
||||
if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil { |
||||
t = messageGoType(mt) |
||||
} |
||||
|
||||
// If we could not get a concrete type, it is possible that it is a
|
||||
// pseudo-message for a map entry.
|
||||
if t == nil { |
||||
d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s)) |
||||
if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() { |
||||
kt := goTypeForField(md.Fields().ByNumber(1)) |
||||
vt := goTypeForField(md.Fields().ByNumber(2)) |
||||
t = reflect.MapOf(kt, vt) |
||||
} |
||||
} |
||||
|
||||
// Locally cache the message type for the given name.
|
||||
if t != nil { |
||||
v, _ := messageTypeCache.LoadOrStore(s, t) |
||||
return v.(reflect.Type) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type { |
||||
switch k := fd.Kind(); k { |
||||
case protoreflect.EnumKind: |
||||
if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil { |
||||
return enumGoType(et) |
||||
} |
||||
return reflect.TypeOf(protoreflect.EnumNumber(0)) |
||||
case protoreflect.MessageKind, protoreflect.GroupKind: |
||||
if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil { |
||||
return messageGoType(mt) |
||||
} |
||||
return reflect.TypeOf((*protoreflect.Message)(nil)).Elem() |
||||
default: |
||||
return reflect.TypeOf(fd.Default().Interface()) |
||||
} |
||||
} |
||||
|
||||
func enumGoType(et protoreflect.EnumType) reflect.Type { |
||||
return reflect.TypeOf(et.New(0)) |
||||
} |
||||
|
||||
func messageGoType(mt protoreflect.MessageType) reflect.Type { |
||||
return reflect.TypeOf(MessageV1(mt.Zero().Interface())) |
||||
} |
||||
|
||||
// MessageName returns the full protobuf name for the given message type.
|
||||
//
|
||||
// Deprecated: Use protoreflect.MessageDescriptor.FullName instead.
|
||||
func MessageName(m Message) messageName { |
||||
if m == nil { |
||||
return "" |
||||
} |
||||
if m, ok := m.(interface{ XXX_MessageName() messageName }); ok { |
||||
return m.XXX_MessageName() |
||||
} |
||||
return messageName(protoimpl.X.MessageDescriptorOf(m).FullName()) |
||||
} |
||||
|
||||
// RegisterExtension is called from the generated code to register
|
||||
// the extension descriptor.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead.
|
||||
func RegisterExtension(d *ExtensionDesc) { |
||||
if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil { |
||||
panic(err) |
||||
} |
||||
} |
||||
|
||||
type extensionsByNumber = map[int32]*ExtensionDesc |
||||
|
||||
var extensionCache sync.Map // map[messageName]extensionsByNumber
|
||||
|
||||
// RegisteredExtensions returns a map of the registered extensions for the
|
||||
// provided protobuf message, indexed by the extension field number.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead.
|
||||
func RegisteredExtensions(m Message) extensionsByNumber { |
||||
// Check whether the cache is stale. If the number of extensions for
|
||||
// the given message differs, then it means that some extensions were
|
||||
// recently registered upstream that we do not know about.
|
||||
s := MessageName(m) |
||||
v, _ := extensionCache.Load(s) |
||||
xs, _ := v.(extensionsByNumber) |
||||
if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) { |
||||
return xs // cache is up-to-date
|
||||
} |
||||
|
||||
// Cache is stale, re-compute the extensions map.
|
||||
xs = make(extensionsByNumber) |
||||
protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool { |
||||
if xd, ok := xt.(*ExtensionDesc); ok { |
||||
xs[int32(xt.TypeDescriptor().Number())] = xd |
||||
} else { |
||||
// TODO: This implies that the protoreflect.ExtensionType is a
|
||||
// custom type not generated by protoc-gen-go. We could try and
|
||||
// convert the type to an ExtensionDesc.
|
||||
} |
||||
return true |
||||
}) |
||||
extensionCache.Store(s, xs) |
||||
return xs |
||||
} |
||||
@ -1,801 +0,0 @@
|
||||
// Copyright 2010 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 proto |
||||
|
||||
import ( |
||||
"encoding" |
||||
"errors" |
||||
"fmt" |
||||
"reflect" |
||||
"strconv" |
||||
"strings" |
||||
"unicode/utf8" |
||||
|
||||
"google.golang.org/protobuf/encoding/prototext" |
||||
protoV2 "google.golang.org/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
) |
||||
|
||||
const wrapTextUnmarshalV2 = false |
||||
|
||||
// ParseError is returned by UnmarshalText.
|
||||
type ParseError struct { |
||||
Message string |
||||
|
||||
// Deprecated: Do not use.
|
||||
Line, Offset int |
||||
} |
||||
|
||||
func (e *ParseError) Error() string { |
||||
if wrapTextUnmarshalV2 { |
||||
return e.Message |
||||
} |
||||
if e.Line == 1 { |
||||
return fmt.Sprintf("line 1.%d: %v", e.Offset, e.Message) |
||||
} |
||||
return fmt.Sprintf("line %d: %v", e.Line, e.Message) |
||||
} |
||||
|
||||
// UnmarshalText parses a proto text formatted string into m.
|
||||
func UnmarshalText(s string, m Message) error { |
||||
if u, ok := m.(encoding.TextUnmarshaler); ok { |
||||
return u.UnmarshalText([]byte(s)) |
||||
} |
||||
|
||||
m.Reset() |
||||
mi := MessageV2(m) |
||||
|
||||
if wrapTextUnmarshalV2 { |
||||
err := prototext.UnmarshalOptions{ |
||||
AllowPartial: true, |
||||
}.Unmarshal([]byte(s), mi) |
||||
if err != nil { |
||||
return &ParseError{Message: err.Error()} |
||||
} |
||||
return checkRequiredNotSet(mi) |
||||
} else { |
||||
if err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), ""); err != nil { |
||||
return err |
||||
} |
||||
return checkRequiredNotSet(mi) |
||||
} |
||||
} |
||||
|
||||
type textParser struct { |
||||
s string // remaining input
|
||||
done bool // whether the parsing is finished (success or error)
|
||||
backed bool // whether back() was called
|
||||
offset, line int |
||||
cur token |
||||
} |
||||
|
||||
type token struct { |
||||
value string |
||||
err *ParseError |
||||
line int // line number
|
||||
offset int // byte number from start of input, not start of line
|
||||
unquoted string // the unquoted version of value, if it was a quoted string
|
||||
} |
||||
|
||||
func newTextParser(s string) *textParser { |
||||
p := new(textParser) |
||||
p.s = s |
||||
p.line = 1 |
||||
p.cur.line = 1 |
||||
return p |
||||
} |
||||
|
||||
func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) { |
||||
md := m.Descriptor() |
||||
fds := md.Fields() |
||||
|
||||
// A struct is a sequence of "name: value", terminated by one of
|
||||
// '>' or '}', or the end of the input. A name may also be
|
||||
// "[extension]" or "[type/url]".
|
||||
//
|
||||
// The whole struct can also be an expanded Any message, like:
|
||||
// [type/url] < ... struct contents ... >
|
||||
seen := make(map[protoreflect.FieldNumber]bool) |
||||
for { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
if tok.value == terminator { |
||||
break |
||||
} |
||||
if tok.value == "[" { |
||||
if err := p.unmarshalExtensionOrAny(m, seen); err != nil { |
||||
return err |
||||
} |
||||
continue |
||||
} |
||||
|
||||
// This is a normal, non-extension field.
|
||||
name := protoreflect.Name(tok.value) |
||||
fd := fds.ByName(name) |
||||
switch { |
||||
case fd == nil: |
||||
gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name)))) |
||||
if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name { |
||||
fd = gd |
||||
} |
||||
case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name: |
||||
fd = nil |
||||
case fd.IsWeak() && fd.Message().IsPlaceholder(): |
||||
fd = nil |
||||
} |
||||
if fd == nil { |
||||
typeName := string(md.FullName()) |
||||
if m, ok := m.Interface().(Message); ok { |
||||
t := reflect.TypeOf(m) |
||||
if t.Kind() == reflect.Ptr { |
||||
typeName = t.Elem().String() |
||||
} |
||||
} |
||||
return p.errorf("unknown field name %q in %v", name, typeName) |
||||
} |
||||
if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil { |
||||
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name()) |
||||
} |
||||
if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] { |
||||
return p.errorf("non-repeated field %q was repeated", fd.Name()) |
||||
} |
||||
seen[fd.Number()] = true |
||||
|
||||
// Consume any colon.
|
||||
if err := p.checkForColon(fd); err != nil { |
||||
return err |
||||
} |
||||
|
||||
// Parse into the field.
|
||||
v := m.Get(fd) |
||||
if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { |
||||
v = m.Mutable(fd) |
||||
} |
||||
if v, err = p.unmarshalValue(v, fd); err != nil { |
||||
return err |
||||
} |
||||
m.Set(fd, v) |
||||
|
||||
if err := p.consumeOptionalSeparator(); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error { |
||||
name, err := p.consumeExtensionOrAnyName() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
// If it contains a slash, it's an Any type URL.
|
||||
if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
// consume an optional colon
|
||||
if tok.value == ":" { |
||||
tok = p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
} |
||||
|
||||
var terminator string |
||||
switch tok.value { |
||||
case "<": |
||||
terminator = ">" |
||||
case "{": |
||||
terminator = "}" |
||||
default: |
||||
return p.errorf("expected '{' or '<', found %q", tok.value) |
||||
} |
||||
|
||||
mt, err := protoregistry.GlobalTypes.FindMessageByURL(name) |
||||
if err != nil { |
||||
return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):]) |
||||
} |
||||
m2 := mt.New() |
||||
if err := p.unmarshalMessage(m2, terminator); err != nil { |
||||
return err |
||||
} |
||||
b, err := protoV2.Marshal(m2.Interface()) |
||||
if err != nil { |
||||
return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err) |
||||
} |
||||
|
||||
urlFD := m.Descriptor().Fields().ByName("type_url") |
||||
valFD := m.Descriptor().Fields().ByName("value") |
||||
if seen[urlFD.Number()] { |
||||
return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name()) |
||||
} |
||||
if seen[valFD.Number()] { |
||||
return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name()) |
||||
} |
||||
m.Set(urlFD, protoreflect.ValueOfString(name)) |
||||
m.Set(valFD, protoreflect.ValueOfBytes(b)) |
||||
seen[urlFD.Number()] = true |
||||
seen[valFD.Number()] = true |
||||
return nil |
||||
} |
||||
|
||||
xname := protoreflect.FullName(name) |
||||
xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) |
||||
if xt == nil && isMessageSet(m.Descriptor()) { |
||||
xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) |
||||
} |
||||
if xt == nil { |
||||
return p.errorf("unrecognized extension %q", name) |
||||
} |
||||
fd := xt.TypeDescriptor() |
||||
if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { |
||||
return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName()) |
||||
} |
||||
|
||||
if err := p.checkForColon(fd); err != nil { |
||||
return err |
||||
} |
||||
|
||||
v := m.Get(fd) |
||||
if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { |
||||
v = m.Mutable(fd) |
||||
} |
||||
v, err = p.unmarshalValue(v, fd) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
m.Set(fd, v) |
||||
return p.consumeOptionalSeparator() |
||||
} |
||||
|
||||
func (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return v, tok.err |
||||
} |
||||
if tok.value == "" { |
||||
return v, p.errorf("unexpected EOF") |
||||
} |
||||
|
||||
switch { |
||||
case fd.IsList(): |
||||
lv := v.List() |
||||
var err error |
||||
if tok.value == "[" { |
||||
// Repeated field with list notation, like [1,2,3].
|
||||
for { |
||||
vv := lv.NewElement() |
||||
vv, err = p.unmarshalSingularValue(vv, fd) |
||||
if err != nil { |
||||
return v, err |
||||
} |
||||
lv.Append(vv) |
||||
|
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return v, tok.err |
||||
} |
||||
if tok.value == "]" { |
||||
break |
||||
} |
||||
if tok.value != "," { |
||||
return v, p.errorf("Expected ']' or ',' found %q", tok.value) |
||||
} |
||||
} |
||||
return v, nil |
||||
} |
||||
|
||||
// One value of the repeated field.
|
||||
p.back() |
||||
vv := lv.NewElement() |
||||
vv, err = p.unmarshalSingularValue(vv, fd) |
||||
if err != nil { |
||||
return v, err |
||||
} |
||||
lv.Append(vv) |
||||
return v, nil |
||||
case fd.IsMap(): |
||||
// The map entry should be this sequence of tokens:
|
||||
// < key : KEY value : VALUE >
|
||||
// However, implementations may omit key or value, and technically
|
||||
// we should support them in any order.
|
||||
var terminator string |
||||
switch tok.value { |
||||
case "<": |
||||
terminator = ">" |
||||
case "{": |
||||
terminator = "}" |
||||
default: |
||||
return v, p.errorf("expected '{' or '<', found %q", tok.value) |
||||
} |
||||
|
||||
keyFD := fd.MapKey() |
||||
valFD := fd.MapValue() |
||||
|
||||
mv := v.Map() |
||||
kv := keyFD.Default() |
||||
vv := mv.NewValue() |
||||
for { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return v, tok.err |
||||
} |
||||
if tok.value == terminator { |
||||
break |
||||
} |
||||
var err error |
||||
switch tok.value { |
||||
case "key": |
||||
if err := p.consumeToken(":"); err != nil { |
||||
return v, err |
||||
} |
||||
if kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil { |
||||
return v, err |
||||
} |
||||
if err := p.consumeOptionalSeparator(); err != nil { |
||||
return v, err |
||||
} |
||||
case "value": |
||||
if err := p.checkForColon(valFD); err != nil { |
||||
return v, err |
||||
} |
||||
if vv, err = p.unmarshalSingularValue(vv, valFD); err != nil { |
||||
return v, err |
||||
} |
||||
if err := p.consumeOptionalSeparator(); err != nil { |
||||
return v, err |
||||
} |
||||
default: |
||||
p.back() |
||||
return v, p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) |
||||
} |
||||
} |
||||
mv.Set(kv.MapKey(), vv) |
||||
return v, nil |
||||
default: |
||||
p.back() |
||||
return p.unmarshalSingularValue(v, fd) |
||||
} |
||||
} |
||||
|
||||
func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return v, tok.err |
||||
} |
||||
if tok.value == "" { |
||||
return v, p.errorf("unexpected EOF") |
||||
} |
||||
|
||||
switch fd.Kind() { |
||||
case protoreflect.BoolKind: |
||||
switch tok.value { |
||||
case "true", "1", "t", "True": |
||||
return protoreflect.ValueOfBool(true), nil |
||||
case "false", "0", "f", "False": |
||||
return protoreflect.ValueOfBool(false), nil |
||||
} |
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: |
||||
if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { |
||||
return protoreflect.ValueOfInt32(int32(x)), nil |
||||
} |
||||
|
||||
// The C++ parser accepts large positive hex numbers that uses
|
||||
// two's complement arithmetic to represent negative numbers.
|
||||
// This feature is here for backwards compatibility with C++.
|
||||
if strings.HasPrefix(tok.value, "0x") { |
||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { |
||||
return protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil |
||||
} |
||||
} |
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: |
||||
if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { |
||||
return protoreflect.ValueOfInt64(int64(x)), nil |
||||
} |
||||
|
||||
// The C++ parser accepts large positive hex numbers that uses
|
||||
// two's complement arithmetic to represent negative numbers.
|
||||
// This feature is here for backwards compatibility with C++.
|
||||
if strings.HasPrefix(tok.value, "0x") { |
||||
if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { |
||||
return protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil |
||||
} |
||||
} |
||||
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: |
||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { |
||||
return protoreflect.ValueOfUint32(uint32(x)), nil |
||||
} |
||||
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: |
||||
if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { |
||||
return protoreflect.ValueOfUint64(uint64(x)), nil |
||||
} |
||||
case protoreflect.FloatKind: |
||||
// Ignore 'f' for compatibility with output generated by C++,
|
||||
// but don't remove 'f' when the value is "-inf" or "inf".
|
||||
v := tok.value |
||||
if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { |
||||
v = v[:len(v)-len("f")] |
||||
} |
||||
if x, err := strconv.ParseFloat(v, 32); err == nil { |
||||
return protoreflect.ValueOfFloat32(float32(x)), nil |
||||
} |
||||
case protoreflect.DoubleKind: |
||||
// Ignore 'f' for compatibility with output generated by C++,
|
||||
// but don't remove 'f' when the value is "-inf" or "inf".
|
||||
v := tok.value |
||||
if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { |
||||
v = v[:len(v)-len("f")] |
||||
} |
||||
if x, err := strconv.ParseFloat(v, 64); err == nil { |
||||
return protoreflect.ValueOfFloat64(float64(x)), nil |
||||
} |
||||
case protoreflect.StringKind: |
||||
if isQuote(tok.value[0]) { |
||||
return protoreflect.ValueOfString(tok.unquoted), nil |
||||
} |
||||
case protoreflect.BytesKind: |
||||
if isQuote(tok.value[0]) { |
||||
return protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil |
||||
} |
||||
case protoreflect.EnumKind: |
||||
if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { |
||||
return protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil |
||||
} |
||||
vd := fd.Enum().Values().ByName(protoreflect.Name(tok.value)) |
||||
if vd != nil { |
||||
return protoreflect.ValueOfEnum(vd.Number()), nil |
||||
} |
||||
case protoreflect.MessageKind, protoreflect.GroupKind: |
||||
var terminator string |
||||
switch tok.value { |
||||
case "{": |
||||
terminator = "}" |
||||
case "<": |
||||
terminator = ">" |
||||
default: |
||||
return v, p.errorf("expected '{' or '<', found %q", tok.value) |
||||
} |
||||
err := p.unmarshalMessage(v.Message(), terminator) |
||||
return v, err |
||||
default: |
||||
panic(fmt.Sprintf("invalid kind %v", fd.Kind())) |
||||
} |
||||
return v, p.errorf("invalid %v: %v", fd.Kind(), tok.value) |
||||
} |
||||
|
||||
// Consume a ':' from the input stream (if the next token is a colon),
|
||||
// returning an error if a colon is needed but not present.
|
||||
func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
if tok.value != ":" { |
||||
if fd.Message() == nil { |
||||
return p.errorf("expected ':', found %q", tok.value) |
||||
} |
||||
p.back() |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// consumeExtensionOrAnyName consumes an extension name or an Any type URL and
|
||||
// the following ']'. It returns the name or URL consumed.
|
||||
func (p *textParser) consumeExtensionOrAnyName() (string, error) { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return "", tok.err |
||||
} |
||||
|
||||
// If extension name or type url is quoted, it's a single token.
|
||||
if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { |
||||
name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
return name, p.consumeToken("]") |
||||
} |
||||
|
||||
// Consume everything up to "]"
|
||||
var parts []string |
||||
for tok.value != "]" { |
||||
parts = append(parts, tok.value) |
||||
tok = p.next() |
||||
if tok.err != nil { |
||||
return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) |
||||
} |
||||
if p.done && tok.value != "]" { |
||||
return "", p.errorf("unclosed type_url or extension name") |
||||
} |
||||
} |
||||
return strings.Join(parts, ""), nil |
||||
} |
||||
|
||||
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
||||
// It is used in unmarshalMessage to provide backward compatibility.
|
||||
func (p *textParser) consumeOptionalSeparator() error { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
if tok.value != ";" && tok.value != "," { |
||||
p.back() |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func (p *textParser) errorf(format string, a ...interface{}) *ParseError { |
||||
pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} |
||||
p.cur.err = pe |
||||
p.done = true |
||||
return pe |
||||
} |
||||
|
||||
func (p *textParser) skipWhitespace() { |
||||
i := 0 |
||||
for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { |
||||
if p.s[i] == '#' { |
||||
// comment; skip to end of line or input
|
||||
for i < len(p.s) && p.s[i] != '\n' { |
||||
i++ |
||||
} |
||||
if i == len(p.s) { |
||||
break |
||||
} |
||||
} |
||||
if p.s[i] == '\n' { |
||||
p.line++ |
||||
} |
||||
i++ |
||||
} |
||||
p.offset += i |
||||
p.s = p.s[i:len(p.s)] |
||||
if len(p.s) == 0 { |
||||
p.done = true |
||||
} |
||||
} |
||||
|
||||
func (p *textParser) advance() { |
||||
// Skip whitespace
|
||||
p.skipWhitespace() |
||||
if p.done { |
||||
return |
||||
} |
||||
|
||||
// Start of non-whitespace
|
||||
p.cur.err = nil |
||||
p.cur.offset, p.cur.line = p.offset, p.line |
||||
p.cur.unquoted = "" |
||||
switch p.s[0] { |
||||
case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': |
||||
// Single symbol
|
||||
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] |
||||
case '"', '\'': |
||||
// Quoted string
|
||||
i := 1 |
||||
for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { |
||||
if p.s[i] == '\\' && i+1 < len(p.s) { |
||||
// skip escaped char
|
||||
i++ |
||||
} |
||||
i++ |
||||
} |
||||
if i >= len(p.s) || p.s[i] != p.s[0] { |
||||
p.errorf("unmatched quote") |
||||
return |
||||
} |
||||
unq, err := unquoteC(p.s[1:i], rune(p.s[0])) |
||||
if err != nil { |
||||
p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) |
||||
return |
||||
} |
||||
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] |
||||
p.cur.unquoted = unq |
||||
default: |
||||
i := 0 |
||||
for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { |
||||
i++ |
||||
} |
||||
if i == 0 { |
||||
p.errorf("unexpected byte %#x", p.s[0]) |
||||
return |
||||
} |
||||
p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] |
||||
} |
||||
p.offset += len(p.cur.value) |
||||
} |
||||
|
||||
// Back off the parser by one token. Can only be done between calls to next().
|
||||
// It makes the next advance() a no-op.
|
||||
func (p *textParser) back() { p.backed = true } |
||||
|
||||
// Advances the parser and returns the new current token.
|
||||
func (p *textParser) next() *token { |
||||
if p.backed || p.done { |
||||
p.backed = false |
||||
return &p.cur |
||||
} |
||||
p.advance() |
||||
if p.done { |
||||
p.cur.value = "" |
||||
} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { |
||||
// Look for multiple quoted strings separated by whitespace,
|
||||
// and concatenate them.
|
||||
cat := p.cur |
||||
for { |
||||
p.skipWhitespace() |
||||
if p.done || !isQuote(p.s[0]) { |
||||
break |
||||
} |
||||
p.advance() |
||||
if p.cur.err != nil { |
||||
return &p.cur |
||||
} |
||||
cat.value += " " + p.cur.value |
||||
cat.unquoted += p.cur.unquoted |
||||
} |
||||
p.done = false // parser may have seen EOF, but we want to return cat
|
||||
p.cur = cat |
||||
} |
||||
return &p.cur |
||||
} |
||||
|
||||
func (p *textParser) consumeToken(s string) error { |
||||
tok := p.next() |
||||
if tok.err != nil { |
||||
return tok.err |
||||
} |
||||
if tok.value != s { |
||||
p.back() |
||||
return p.errorf("expected %q, found %q", s, tok.value) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
var errBadUTF8 = errors.New("proto: bad UTF-8") |
||||
|
||||
func unquoteC(s string, quote rune) (string, error) { |
||||
// This is based on C++'s tokenizer.cc.
|
||||
// Despite its name, this is *not* parsing C syntax.
|
||||
// For instance, "\0" is an invalid quoted string.
|
||||
|
||||
// Avoid allocation in trivial cases.
|
||||
simple := true |
||||
for _, r := range s { |
||||
if r == '\\' || r == quote { |
||||
simple = false |
||||
break |
||||
} |
||||
} |
||||
if simple { |
||||
return s, nil |
||||
} |
||||
|
||||
buf := make([]byte, 0, 3*len(s)/2) |
||||
for len(s) > 0 { |
||||
r, n := utf8.DecodeRuneInString(s) |
||||
if r == utf8.RuneError && n == 1 { |
||||
return "", errBadUTF8 |
||||
} |
||||
s = s[n:] |
||||
if r != '\\' { |
||||
if r < utf8.RuneSelf { |
||||
buf = append(buf, byte(r)) |
||||
} else { |
||||
buf = append(buf, string(r)...) |
||||
} |
||||
continue |
||||
} |
||||
|
||||
ch, tail, err := unescape(s) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
buf = append(buf, ch...) |
||||
s = tail |
||||
} |
||||
return string(buf), nil |
||||
} |
||||
|
||||
func unescape(s string) (ch string, tail string, err error) { |
||||
r, n := utf8.DecodeRuneInString(s) |
||||
if r == utf8.RuneError && n == 1 { |
||||
return "", "", errBadUTF8 |
||||
} |
||||
s = s[n:] |
||||
switch r { |
||||
case 'a': |
||||
return "\a", s, nil |
||||
case 'b': |
||||
return "\b", s, nil |
||||
case 'f': |
||||
return "\f", s, nil |
||||
case 'n': |
||||
return "\n", s, nil |
||||
case 'r': |
||||
return "\r", s, nil |
||||
case 't': |
||||
return "\t", s, nil |
||||
case 'v': |
||||
return "\v", s, nil |
||||
case '?': |
||||
return "?", s, nil // trigraph workaround
|
||||
case '\'', '"', '\\': |
||||
return string(r), s, nil |
||||
case '0', '1', '2', '3', '4', '5', '6', '7': |
||||
if len(s) < 2 { |
||||
return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) |
||||
} |
||||
ss := string(r) + s[:2] |
||||
s = s[2:] |
||||
i, err := strconv.ParseUint(ss, 8, 8) |
||||
if err != nil { |
||||
return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) |
||||
} |
||||
return string([]byte{byte(i)}), s, nil |
||||
case 'x', 'X', 'u', 'U': |
||||
var n int |
||||
switch r { |
||||
case 'x', 'X': |
||||
n = 2 |
||||
case 'u': |
||||
n = 4 |
||||
case 'U': |
||||
n = 8 |
||||
} |
||||
if len(s) < n { |
||||
return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) |
||||
} |
||||
ss := s[:n] |
||||
s = s[n:] |
||||
i, err := strconv.ParseUint(ss, 16, 64) |
||||
if err != nil { |
||||
return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) |
||||
} |
||||
if r == 'x' || r == 'X' { |
||||
return string([]byte{byte(i)}), s, nil |
||||
} |
||||
if i > utf8.MaxRune { |
||||
return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) |
||||
} |
||||
return string(rune(i)), s, nil |
||||
} |
||||
return "", "", fmt.Errorf(`unknown escape \%c`, r) |
||||
} |
||||
|
||||
func isIdentOrNumberChar(c byte) bool { |
||||
switch { |
||||
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': |
||||
return true |
||||
case '0' <= c && c <= '9': |
||||
return true |
||||
} |
||||
switch c { |
||||
case '-', '+', '.', '_': |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func isWhitespace(c byte) bool { |
||||
switch c { |
||||
case ' ', '\t', '\n', '\r': |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func isQuote(c byte) bool { |
||||
switch c { |
||||
case '"', '\'': |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
@ -1,560 +0,0 @@
|
||||
// Copyright 2010 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 proto |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding" |
||||
"fmt" |
||||
"io" |
||||
"math" |
||||
"sort" |
||||
"strings" |
||||
|
||||
"google.golang.org/protobuf/encoding/prototext" |
||||
"google.golang.org/protobuf/encoding/protowire" |
||||
"google.golang.org/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
) |
||||
|
||||
const wrapTextMarshalV2 = false |
||||
|
||||
// TextMarshaler is a configurable text format marshaler.
|
||||
type TextMarshaler struct { |
||||
Compact bool // use compact text format (one line)
|
||||
ExpandAny bool // expand google.protobuf.Any messages of known types
|
||||
} |
||||
|
||||
// Marshal writes the proto text format of m to w.
|
||||
func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error { |
||||
b, err := tm.marshal(m) |
||||
if len(b) > 0 { |
||||
if _, err := w.Write(b); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
// Text returns a proto text formatted string of m.
|
||||
func (tm *TextMarshaler) Text(m Message) string { |
||||
b, _ := tm.marshal(m) |
||||
return string(b) |
||||
} |
||||
|
||||
func (tm *TextMarshaler) marshal(m Message) ([]byte, error) { |
||||
mr := MessageReflect(m) |
||||
if mr == nil || !mr.IsValid() { |
||||
return []byte("<nil>"), nil |
||||
} |
||||
|
||||
if wrapTextMarshalV2 { |
||||
if m, ok := m.(encoding.TextMarshaler); ok { |
||||
return m.MarshalText() |
||||
} |
||||
|
||||
opts := prototext.MarshalOptions{ |
||||
AllowPartial: true, |
||||
EmitUnknown: true, |
||||
} |
||||
if !tm.Compact { |
||||
opts.Indent = " " |
||||
} |
||||
if !tm.ExpandAny { |
||||
opts.Resolver = (*protoregistry.Types)(nil) |
||||
} |
||||
return opts.Marshal(mr.Interface()) |
||||
} else { |
||||
w := &textWriter{ |
||||
compact: tm.Compact, |
||||
expandAny: tm.ExpandAny, |
||||
complete: true, |
||||
} |
||||
|
||||
if m, ok := m.(encoding.TextMarshaler); ok { |
||||
b, err := m.MarshalText() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
w.Write(b) |
||||
return w.buf, nil |
||||
} |
||||
|
||||
err := w.writeMessage(mr) |
||||
return w.buf, err |
||||
} |
||||
} |
||||
|
||||
var ( |
||||
defaultTextMarshaler = TextMarshaler{} |
||||
compactTextMarshaler = TextMarshaler{Compact: true} |
||||
) |
||||
|
||||
// MarshalText writes the proto text format of m to w.
|
||||
func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) } |
||||
|
||||
// MarshalTextString returns a proto text formatted string of m.
|
||||
func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) } |
||||
|
||||
// CompactText writes the compact proto text format of m to w.
|
||||
func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) } |
||||
|
||||
// CompactTextString returns a compact proto text formatted string of m.
|
||||
func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) } |
||||
|
||||
var ( |
||||
newline = []byte("\n") |
||||
endBraceNewline = []byte("}\n") |
||||
posInf = []byte("inf") |
||||
negInf = []byte("-inf") |
||||
nan = []byte("nan") |
||||
) |
||||
|
||||
// textWriter is an io.Writer that tracks its indentation level.
|
||||
type textWriter struct { |
||||
compact bool // same as TextMarshaler.Compact
|
||||
expandAny bool // same as TextMarshaler.ExpandAny
|
||||
complete bool // whether the current position is a complete line
|
||||
indent int // indentation level; never negative
|
||||
buf []byte |
||||
} |
||||
|
||||
func (w *textWriter) Write(p []byte) (n int, _ error) { |
||||
newlines := bytes.Count(p, newline) |
||||
if newlines == 0 { |
||||
if !w.compact && w.complete { |
||||
w.writeIndent() |
||||
} |
||||
w.buf = append(w.buf, p...) |
||||
w.complete = false |
||||
return len(p), nil |
||||
} |
||||
|
||||
frags := bytes.SplitN(p, newline, newlines+1) |
||||
if w.compact { |
||||
for i, frag := range frags { |
||||
if i > 0 { |
||||
w.buf = append(w.buf, ' ') |
||||
n++ |
||||
} |
||||
w.buf = append(w.buf, frag...) |
||||
n += len(frag) |
||||
} |
||||
return n, nil |
||||
} |
||||
|
||||
for i, frag := range frags { |
||||
if w.complete { |
||||
w.writeIndent() |
||||
} |
||||
w.buf = append(w.buf, frag...) |
||||
n += len(frag) |
||||
if i+1 < len(frags) { |
||||
w.buf = append(w.buf, '\n') |
||||
n++ |
||||
} |
||||
} |
||||
w.complete = len(frags[len(frags)-1]) == 0 |
||||
return n, nil |
||||
} |
||||
|
||||
func (w *textWriter) WriteByte(c byte) error { |
||||
if w.compact && c == '\n' { |
||||
c = ' ' |
||||
} |
||||
if !w.compact && w.complete { |
||||
w.writeIndent() |
||||
} |
||||
w.buf = append(w.buf, c) |
||||
w.complete = c == '\n' |
||||
return nil |
||||
} |
||||
|
||||
func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) { |
||||
if !w.compact && w.complete { |
||||
w.writeIndent() |
||||
} |
||||
w.complete = false |
||||
|
||||
if fd.Kind() != protoreflect.GroupKind { |
||||
w.buf = append(w.buf, fd.Name()...) |
||||
w.WriteByte(':') |
||||
} else { |
||||
// Use message type name for group field name.
|
||||
w.buf = append(w.buf, fd.Message().Name()...) |
||||
} |
||||
|
||||
if !w.compact { |
||||
w.WriteByte(' ') |
||||
} |
||||
} |
||||
|
||||
func requiresQuotes(u string) bool { |
||||
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
||||
for _, ch := range u { |
||||
switch { |
||||
case ch == '.' || ch == '/' || ch == '_': |
||||
continue |
||||
case '0' <= ch && ch <= '9': |
||||
continue |
||||
case 'A' <= ch && ch <= 'Z': |
||||
continue |
||||
case 'a' <= ch && ch <= 'z': |
||||
continue |
||||
default: |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// writeProto3Any writes an expanded google.protobuf.Any message.
|
||||
//
|
||||
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
||||
// required messages are not linked in).
|
||||
//
|
||||
// It returns (true, error) when sv was written in expanded format or an error
|
||||
// was encountered.
|
||||
func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) { |
||||
md := m.Descriptor() |
||||
fdURL := md.Fields().ByName("type_url") |
||||
fdVal := md.Fields().ByName("value") |
||||
|
||||
url := m.Get(fdURL).String() |
||||
mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) |
||||
if err != nil { |
||||
return false, nil |
||||
} |
||||
|
||||
b := m.Get(fdVal).Bytes() |
||||
m2 := mt.New() |
||||
if err := proto.Unmarshal(b, m2.Interface()); err != nil { |
||||
return false, nil |
||||
} |
||||
w.Write([]byte("[")) |
||||
if requiresQuotes(url) { |
||||
w.writeQuotedString(url) |
||||
} else { |
||||
w.Write([]byte(url)) |
||||
} |
||||
if w.compact { |
||||
w.Write([]byte("]:<")) |
||||
} else { |
||||
w.Write([]byte("]: <\n")) |
||||
w.indent++ |
||||
} |
||||
if err := w.writeMessage(m2); err != nil { |
||||
return true, err |
||||
} |
||||
if w.compact { |
||||
w.Write([]byte("> ")) |
||||
} else { |
||||
w.indent-- |
||||
w.Write([]byte(">\n")) |
||||
} |
||||
return true, nil |
||||
} |
||||
|
||||
func (w *textWriter) writeMessage(m protoreflect.Message) error { |
||||
md := m.Descriptor() |
||||
if w.expandAny && md.FullName() == "google.protobuf.Any" { |
||||
if canExpand, err := w.writeProto3Any(m); canExpand { |
||||
return err |
||||
} |
||||
} |
||||
|
||||
fds := md.Fields() |
||||
for i := 0; i < fds.Len(); { |
||||
fd := fds.Get(i) |
||||
if od := fd.ContainingOneof(); od != nil { |
||||
fd = m.WhichOneof(od) |
||||
i += od.Fields().Len() |
||||
} else { |
||||
i++ |
||||
} |
||||
if fd == nil || !m.Has(fd) { |
||||
continue |
||||
} |
||||
|
||||
switch { |
||||
case fd.IsList(): |
||||
lv := m.Get(fd).List() |
||||
for j := 0; j < lv.Len(); j++ { |
||||
w.writeName(fd) |
||||
v := lv.Get(j) |
||||
if err := w.writeSingularValue(v, fd); err != nil { |
||||
return err |
||||
} |
||||
w.WriteByte('\n') |
||||
} |
||||
case fd.IsMap(): |
||||
kfd := fd.MapKey() |
||||
vfd := fd.MapValue() |
||||
mv := m.Get(fd).Map() |
||||
|
||||
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") |
||||
} |
||||
}) |
||||
for _, entry := range entries { |
||||
w.writeName(fd) |
||||
w.WriteByte('<') |
||||
if !w.compact { |
||||
w.WriteByte('\n') |
||||
} |
||||
w.indent++ |
||||
w.writeName(kfd) |
||||
if err := w.writeSingularValue(entry.key, kfd); err != nil { |
||||
return err |
||||
} |
||||
w.WriteByte('\n') |
||||
w.writeName(vfd) |
||||
if err := w.writeSingularValue(entry.val, vfd); err != nil { |
||||
return err |
||||
} |
||||
w.WriteByte('\n') |
||||
w.indent-- |
||||
w.WriteByte('>') |
||||
w.WriteByte('\n') |
||||
} |
||||
default: |
||||
w.writeName(fd) |
||||
if err := w.writeSingularValue(m.Get(fd), fd); err != nil { |
||||
return err |
||||
} |
||||
w.WriteByte('\n') |
||||
} |
||||
} |
||||
|
||||
if b := m.GetUnknown(); len(b) > 0 { |
||||
w.writeUnknownFields(b) |
||||
} |
||||
return w.writeExtensions(m) |
||||
} |
||||
|
||||
func (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error { |
||||
switch fd.Kind() { |
||||
case protoreflect.FloatKind, protoreflect.DoubleKind: |
||||
switch vf := v.Float(); { |
||||
case math.IsInf(vf, +1): |
||||
w.Write(posInf) |
||||
case math.IsInf(vf, -1): |
||||
w.Write(negInf) |
||||
case math.IsNaN(vf): |
||||
w.Write(nan) |
||||
default: |
||||
fmt.Fprint(w, v.Interface()) |
||||
} |
||||
case protoreflect.StringKind: |
||||
// NOTE: This does not validate UTF-8 for historical reasons.
|
||||
w.writeQuotedString(string(v.String())) |
||||
case protoreflect.BytesKind: |
||||
w.writeQuotedString(string(v.Bytes())) |
||||
case protoreflect.MessageKind, protoreflect.GroupKind: |
||||
var bra, ket byte = '<', '>' |
||||
if fd.Kind() == protoreflect.GroupKind { |
||||
bra, ket = '{', '}' |
||||
} |
||||
w.WriteByte(bra) |
||||
if !w.compact { |
||||
w.WriteByte('\n') |
||||
} |
||||
w.indent++ |
||||
m := v.Message() |
||||
if m2, ok := m.Interface().(encoding.TextMarshaler); ok { |
||||
b, err := m2.MarshalText() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
w.Write(b) |
||||
} else { |
||||
w.writeMessage(m) |
||||
} |
||||
w.indent-- |
||||
w.WriteByte(ket) |
||||
case protoreflect.EnumKind: |
||||
if ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil { |
||||
fmt.Fprint(w, ev.Name()) |
||||
} else { |
||||
fmt.Fprint(w, v.Enum()) |
||||
} |
||||
default: |
||||
fmt.Fprint(w, v.Interface()) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// writeQuotedString writes a quoted string in the protocol buffer text format.
|
||||
func (w *textWriter) writeQuotedString(s string) { |
||||
w.WriteByte('"') |
||||
for i := 0; i < len(s); i++ { |
||||
switch c := s[i]; c { |
||||
case '\n': |
||||
w.buf = append(w.buf, `\n`...) |
||||
case '\r': |
||||
w.buf = append(w.buf, `\r`...) |
||||
case '\t': |
||||
w.buf = append(w.buf, `\t`...) |
||||
case '"': |
||||
w.buf = append(w.buf, `\"`...) |
||||
case '\\': |
||||
w.buf = append(w.buf, `\\`...) |
||||
default: |
||||
if isPrint := c >= 0x20 && c < 0x7f; isPrint { |
||||
w.buf = append(w.buf, c) |
||||
} else { |
||||
w.buf = append(w.buf, fmt.Sprintf(`\%03o`, c)...) |
||||
} |
||||
} |
||||
} |
||||
w.WriteByte('"') |
||||
} |
||||
|
||||
func (w *textWriter) writeUnknownFields(b []byte) { |
||||
if !w.compact { |
||||
fmt.Fprintf(w, "/* %d unknown bytes */\n", len(b)) |
||||
} |
||||
|
||||
for len(b) > 0 { |
||||
num, wtyp, n := protowire.ConsumeTag(b) |
||||
if n < 0 { |
||||
return |
||||
} |
||||
b = b[n:] |
||||
|
||||
if wtyp == protowire.EndGroupType { |
||||
w.indent-- |
||||
w.Write(endBraceNewline) |
||||
continue |
||||
} |
||||
fmt.Fprint(w, num) |
||||
if wtyp != protowire.StartGroupType { |
||||
w.WriteByte(':') |
||||
} |
||||
if !w.compact || wtyp == protowire.StartGroupType { |
||||
w.WriteByte(' ') |
||||
} |
||||
switch wtyp { |
||||
case protowire.VarintType: |
||||
v, n := protowire.ConsumeVarint(b) |
||||
if n < 0 { |
||||
return |
||||
} |
||||
b = b[n:] |
||||
fmt.Fprint(w, v) |
||||
case protowire.Fixed32Type: |
||||
v, n := protowire.ConsumeFixed32(b) |
||||
if n < 0 { |
||||
return |
||||
} |
||||
b = b[n:] |
||||
fmt.Fprint(w, v) |
||||
case protowire.Fixed64Type: |
||||
v, n := protowire.ConsumeFixed64(b) |
||||
if n < 0 { |
||||
return |
||||
} |
||||
b = b[n:] |
||||
fmt.Fprint(w, v) |
||||
case protowire.BytesType: |
||||
v, n := protowire.ConsumeBytes(b) |
||||
if n < 0 { |
||||
return |
||||
} |
||||
b = b[n:] |
||||
fmt.Fprintf(w, "%q", v) |
||||
case protowire.StartGroupType: |
||||
w.WriteByte('{') |
||||
w.indent++ |
||||
default: |
||||
fmt.Fprintf(w, "/* unknown wire type %d */", wtyp) |
||||
} |
||||
w.WriteByte('\n') |
||||
} |
||||
} |
||||
|
||||
// writeExtensions writes all the extensions in m.
|
||||
func (w *textWriter) writeExtensions(m protoreflect.Message) error { |
||||
md := m.Descriptor() |
||||
if md.ExtensionRanges().Len() == 0 { |
||||
return nil |
||||
} |
||||
|
||||
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 { |
||||
// For message set, use the name of the message as the extension name.
|
||||
name := string(ext.desc.FullName()) |
||||
if isMessageSet(ext.desc.ContainingMessage()) { |
||||
name = strings.TrimSuffix(name, ".message_set_extension") |
||||
} |
||||
|
||||
if !ext.desc.IsList() { |
||||
if err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil { |
||||
return err |
||||
} |
||||
} else { |
||||
lv := ext.val.List() |
||||
for i := 0; i < lv.Len(); i++ { |
||||
if err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error { |
||||
fmt.Fprintf(w, "[%s]:", name) |
||||
if !w.compact { |
||||
w.WriteByte(' ') |
||||
} |
||||
if err := w.writeSingularValue(v, fd); err != nil { |
||||
return err |
||||
} |
||||
w.WriteByte('\n') |
||||
return nil |
||||
} |
||||
|
||||
func (w *textWriter) writeIndent() { |
||||
if !w.complete { |
||||
return |
||||
} |
||||
for i := 0; i < w.indent*2; i++ { |
||||
w.buf = append(w.buf, ' ') |
||||
} |
||||
w.complete = false |
||||
} |
||||
@ -1,78 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
import ( |
||||
protoV2 "google.golang.org/protobuf/proto" |
||||
"google.golang.org/protobuf/runtime/protoiface" |
||||
) |
||||
|
||||
// Size returns the size in bytes of the wire-format encoding of m.
|
||||
func Size(m Message) int { |
||||
if m == nil { |
||||
return 0 |
||||
} |
||||
mi := MessageV2(m) |
||||
return protoV2.Size(mi) |
||||
} |
||||
|
||||
// Marshal returns the wire-format encoding of m.
|
||||
func Marshal(m Message) ([]byte, error) { |
||||
b, err := marshalAppend(nil, m, false) |
||||
if b == nil { |
||||
b = zeroBytes |
||||
} |
||||
return b, err |
||||
} |
||||
|
||||
var zeroBytes = make([]byte, 0, 0) |
||||
|
||||
func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) { |
||||
if m == nil { |
||||
return nil, ErrNil |
||||
} |
||||
mi := MessageV2(m) |
||||
nbuf, err := protoV2.MarshalOptions{ |
||||
Deterministic: deterministic, |
||||
AllowPartial: true, |
||||
}.MarshalAppend(buf, mi) |
||||
if err != nil { |
||||
return buf, err |
||||
} |
||||
if len(buf) == len(nbuf) { |
||||
if !mi.ProtoReflect().IsValid() { |
||||
return buf, ErrNil |
||||
} |
||||
} |
||||
return nbuf, checkRequiredNotSet(mi) |
||||
} |
||||
|
||||
// Unmarshal parses a wire-format message in b and places the decoded results in m.
|
||||
//
|
||||
// Unmarshal resets m before starting to unmarshal, so any existing data in m is always
|
||||
// removed. Use UnmarshalMerge to preserve and append to existing data.
|
||||
func Unmarshal(b []byte, m Message) error { |
||||
m.Reset() |
||||
return UnmarshalMerge(b, m) |
||||
} |
||||
|
||||
// UnmarshalMerge parses a wire-format message in b and places the decoded results in m.
|
||||
func UnmarshalMerge(b []byte, m Message) error { |
||||
mi := MessageV2(m) |
||||
out, err := protoV2.UnmarshalOptions{ |
||||
AllowPartial: true, |
||||
Merge: true, |
||||
}.UnmarshalState(protoiface.UnmarshalInput{ |
||||
Buf: b, |
||||
Message: mi.ProtoReflect(), |
||||
}) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if out.Flags&protoiface.UnmarshalInitialized > 0 { |
||||
return nil |
||||
} |
||||
return checkRequiredNotSet(mi) |
||||
} |
||||
@ -1,34 +0,0 @@
|
||||
// Copyright 2019 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 proto |
||||
|
||||
// Bool stores v in a new bool value and returns a pointer to it.
|
||||
func Bool(v bool) *bool { return &v } |
||||
|
||||
// Int stores v in a new int32 value and returns a pointer to it.
|
||||
//
|
||||
// Deprecated: Use Int32 instead.
|
||||
func Int(v int) *int32 { return Int32(int32(v)) } |
||||
|
||||
// Int32 stores v in a new int32 value and returns a pointer to it.
|
||||
func Int32(v int32) *int32 { return &v } |
||||
|
||||
// Int64 stores v in a new int64 value and returns a pointer to it.
|
||||
func Int64(v int64) *int64 { return &v } |
||||
|
||||
// Uint32 stores v in a new uint32 value and returns a pointer to it.
|
||||
func Uint32(v uint32) *uint32 { return &v } |
||||
|
||||
// Uint64 stores v in a new uint64 value and returns a pointer to it.
|
||||
func Uint64(v uint64) *uint64 { return &v } |
||||
|
||||
// Float32 stores v in a new float32 value and returns a pointer to it.
|
||||
func Float32(v float32) *float32 { return &v } |
||||
|
||||
// Float64 stores v in a new float64 value and returns a pointer to it.
|
||||
func Float64(v float64) *float64 { return &v } |
||||
|
||||
// String stores v in a new string value and returns a pointer to it.
|
||||
func String(v string) *string { return &v } |
||||
@ -1,179 +0,0 @@
|
||||
// Copyright 2016 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 ptypes |
||||
|
||||
import ( |
||||
"fmt" |
||||
"strings" |
||||
|
||||
"github.com/golang/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
|
||||
anypb "github.com/golang/protobuf/ptypes/any" |
||||
) |
||||
|
||||
const urlPrefix = "type.googleapis.com/" |
||||
|
||||
// AnyMessageName returns the message name contained in an anypb.Any message.
|
||||
// Most type assertions should use the Is function instead.
|
||||
//
|
||||
// Deprecated: Call the any.MessageName method instead.
|
||||
func AnyMessageName(any *anypb.Any) (string, error) { |
||||
name, err := anyMessageName(any) |
||||
return string(name), err |
||||
} |
||||
func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { |
||||
if any == nil { |
||||
return "", fmt.Errorf("message is nil") |
||||
} |
||||
name := protoreflect.FullName(any.TypeUrl) |
||||
if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { |
||||
name = name[i+len("/"):] |
||||
} |
||||
if !name.IsValid() { |
||||
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) |
||||
} |
||||
return name, nil |
||||
} |
||||
|
||||
// MarshalAny marshals the given message m into an anypb.Any message.
|
||||
//
|
||||
// Deprecated: Call the anypb.New function instead.
|
||||
func MarshalAny(m proto.Message) (*anypb.Any, error) { |
||||
switch dm := m.(type) { |
||||
case DynamicAny: |
||||
m = dm.Message |
||||
case *DynamicAny: |
||||
if dm == nil { |
||||
return nil, proto.ErrNil |
||||
} |
||||
m = dm.Message |
||||
} |
||||
b, err := proto.Marshal(m) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil |
||||
} |
||||
|
||||
// Empty returns a new message of the type specified in an anypb.Any message.
|
||||
// It returns protoregistry.NotFound if the corresponding message type could not
|
||||
// be resolved in the global registry.
|
||||
//
|
||||
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead
|
||||
// to resolve the message name and create a new instance of it.
|
||||
func Empty(any *anypb.Any) (proto.Message, error) { |
||||
name, err := anyMessageName(any) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(name) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return proto.MessageV1(mt.New().Interface()), nil |
||||
} |
||||
|
||||
// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message
|
||||
// into the provided message m. It returns an error if the target message
|
||||
// does not match the type in the Any message or if an unmarshal error occurs.
|
||||
//
|
||||
// The target message m may be a *DynamicAny message. If the underlying message
|
||||
// type could not be resolved, then this returns protoregistry.NotFound.
|
||||
//
|
||||
// Deprecated: Call the any.UnmarshalTo method instead.
|
||||
func UnmarshalAny(any *anypb.Any, m proto.Message) error { |
||||
if dm, ok := m.(*DynamicAny); ok { |
||||
if dm.Message == nil { |
||||
var err error |
||||
dm.Message, err = Empty(any) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
} |
||||
m = dm.Message |
||||
} |
||||
|
||||
anyName, err := AnyMessageName(any) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
msgName := proto.MessageName(m) |
||||
if anyName != msgName { |
||||
return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) |
||||
} |
||||
return proto.Unmarshal(any.Value, m) |
||||
} |
||||
|
||||
// Is reports whether the Any message contains a message of the specified type.
|
||||
//
|
||||
// Deprecated: Call the any.MessageIs method instead.
|
||||
func Is(any *anypb.Any, m proto.Message) bool { |
||||
if any == nil || m == nil { |
||||
return false |
||||
} |
||||
name := proto.MessageName(m) |
||||
if !strings.HasSuffix(any.TypeUrl, name) { |
||||
return false |
||||
} |
||||
return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' |
||||
} |
||||
|
||||
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
|
||||
// allocate a proto.Message for the type specified in an anypb.Any message.
|
||||
// The allocated message is stored in the embedded proto.Message.
|
||||
//
|
||||
// Example:
|
||||
// var x ptypes.DynamicAny
|
||||
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
|
||||
// fmt.Printf("unmarshaled message: %v", x.Message)
|
||||
//
|
||||
// Deprecated: Use the any.UnmarshalNew method instead to unmarshal
|
||||
// the any message contents into a new instance of the underlying message.
|
||||
type DynamicAny struct{ proto.Message } |
||||
|
||||
func (m DynamicAny) String() string { |
||||
if m.Message == nil { |
||||
return "<nil>" |
||||
} |
||||
return m.Message.String() |
||||
} |
||||
func (m DynamicAny) Reset() { |
||||
if m.Message == nil { |
||||
return |
||||
} |
||||
m.Message.Reset() |
||||
} |
||||
func (m DynamicAny) ProtoMessage() { |
||||
return |
||||
} |
||||
func (m DynamicAny) ProtoReflect() protoreflect.Message { |
||||
if m.Message == nil { |
||||
return nil |
||||
} |
||||
return dynamicAny{proto.MessageReflect(m.Message)} |
||||
} |
||||
|
||||
type dynamicAny struct{ protoreflect.Message } |
||||
|
||||
func (m dynamicAny) Type() protoreflect.MessageType { |
||||
return dynamicAnyType{m.Message.Type()} |
||||
} |
||||
func (m dynamicAny) New() protoreflect.Message { |
||||
return dynamicAnyType{m.Message.Type()}.New() |
||||
} |
||||
func (m dynamicAny) Interface() protoreflect.ProtoMessage { |
||||
return DynamicAny{proto.MessageV1(m.Message.Interface())} |
||||
} |
||||
|
||||
type dynamicAnyType struct{ protoreflect.MessageType } |
||||
|
||||
func (t dynamicAnyType) New() protoreflect.Message { |
||||
return dynamicAny{t.MessageType.New()} |
||||
} |
||||
func (t dynamicAnyType) Zero() protoreflect.Message { |
||||
return dynamicAny{t.MessageType.Zero()} |
||||
} |
||||
@ -1,62 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/any/any.proto
|
||||
|
||||
package any |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
anypb "google.golang.org/protobuf/types/known/anypb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/any.proto.
|
||||
|
||||
type Any = anypb.Any |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ |
||||
0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, |
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, |
||||
0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, |
||||
0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, |
||||
0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, |
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, |
||||
0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, |
||||
0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, |
||||
0x74, 0x6f, 0x33, |
||||
} |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} |
||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ |
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
} |
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } |
||||
func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { |
||||
if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { |
||||
return |
||||
} |
||||
type x struct{} |
||||
out := protoimpl.TypeBuilder{ |
||||
File: protoimpl.DescBuilder{ |
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), |
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, |
||||
NumEnums: 0, |
||||
NumMessages: 0, |
||||
NumExtensions: 0, |
||||
NumServices: 0, |
||||
}, |
||||
GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, |
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, |
||||
}.Build() |
||||
File_github_com_golang_protobuf_ptypes_any_any_proto = out.File |
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil |
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil |
||||
file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil |
||||
} |
||||
@ -1,10 +0,0 @@
|
||||
// Copyright 2016 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 ptypes provides functionality for interacting with well-known types.
|
||||
//
|
||||
// Deprecated: Well-known types have specialized functionality directly
|
||||
// injected into the generated packages for each message type.
|
||||
// See the deprecation notice for each function for the suggested alternative.
|
||||
package ptypes |
||||
@ -1,76 +0,0 @@
|
||||
// Copyright 2016 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 ptypes |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"time" |
||||
|
||||
durationpb "github.com/golang/protobuf/ptypes/duration" |
||||
) |
||||
|
||||
// Range of google.protobuf.Duration as specified in duration.proto.
|
||||
// This is about 10,000 years in seconds.
|
||||
const ( |
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) |
||||
minSeconds = -maxSeconds |
||||
) |
||||
|
||||
// Duration converts a durationpb.Duration to a time.Duration.
|
||||
// Duration returns an error if dur is invalid or overflows a time.Duration.
|
||||
//
|
||||
// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead.
|
||||
func Duration(dur *durationpb.Duration) (time.Duration, error) { |
||||
if err := validateDuration(dur); err != nil { |
||||
return 0, err |
||||
} |
||||
d := time.Duration(dur.Seconds) * time.Second |
||||
if int64(d/time.Second) != dur.Seconds { |
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) |
||||
} |
||||
if dur.Nanos != 0 { |
||||
d += time.Duration(dur.Nanos) * time.Nanosecond |
||||
if (d < 0) != (dur.Nanos < 0) { |
||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) |
||||
} |
||||
} |
||||
return d, nil |
||||
} |
||||
|
||||
// DurationProto converts a time.Duration to a durationpb.Duration.
|
||||
//
|
||||
// Deprecated: Call the durationpb.New function instead.
|
||||
func DurationProto(d time.Duration) *durationpb.Duration { |
||||
nanos := d.Nanoseconds() |
||||
secs := nanos / 1e9 |
||||
nanos -= secs * 1e9 |
||||
return &durationpb.Duration{ |
||||
Seconds: int64(secs), |
||||
Nanos: int32(nanos), |
||||
} |
||||
} |
||||
|
||||
// validateDuration determines whether the durationpb.Duration is valid
|
||||
// according to the definition in google/protobuf/duration.proto.
|
||||
// A valid durpb.Duration may still be too large to fit into a time.Duration
|
||||
// Note that the range of durationpb.Duration is about 10,000 years,
|
||||
// while the range of time.Duration is about 290 years.
|
||||
func validateDuration(dur *durationpb.Duration) error { |
||||
if dur == nil { |
||||
return errors.New("duration: nil Duration") |
||||
} |
||||
if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { |
||||
return fmt.Errorf("duration: %v: seconds out of range", dur) |
||||
} |
||||
if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { |
||||
return fmt.Errorf("duration: %v: nanos out of range", dur) |
||||
} |
||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
|
||||
if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { |
||||
return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) |
||||
} |
||||
return nil |
||||
} |
||||
@ -1,63 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/duration/duration.proto
|
||||
|
||||
package duration |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
durationpb "google.golang.org/protobuf/types/known/durationpb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/duration.proto.
|
||||
|
||||
type Duration = durationpb.Duration |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ |
||||
0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, |
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, |
||||
0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, |
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, |
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, |
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, |
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, |
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, |
||||
0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, |
||||
0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, |
||||
} |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} |
||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ |
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
} |
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } |
||||
func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { |
||||
if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { |
||||
return |
||||
} |
||||
type x struct{} |
||||
out := protoimpl.TypeBuilder{ |
||||
File: protoimpl.DescBuilder{ |
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), |
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, |
||||
NumEnums: 0, |
||||
NumMessages: 0, |
||||
NumExtensions: 0, |
||||
NumServices: 0, |
||||
}, |
||||
GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, |
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, |
||||
}.Build() |
||||
File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File |
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil |
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil |
||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil |
||||
} |
||||
@ -1,112 +0,0 @@
|
||||
// Copyright 2016 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 ptypes |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"time" |
||||
|
||||
timestamppb "github.com/golang/protobuf/ptypes/timestamp" |
||||
) |
||||
|
||||
// Range of google.protobuf.Duration as specified in timestamp.proto.
|
||||
const ( |
||||
// Seconds field of the earliest valid Timestamp.
|
||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
minValidSeconds = -62135596800 |
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800 |
||||
) |
||||
|
||||
// Timestamp converts a timestamppb.Timestamp to a time.Time.
|
||||
// It returns an error if the argument is invalid.
|
||||
//
|
||||
// Unlike most Go functions, if Timestamp returns an error, the first return
|
||||
// value is not the zero time.Time. Instead, it is the value obtained from the
|
||||
// time.Unix function when passed the contents of the Timestamp, in the UTC
|
||||
// locale. This may or may not be a meaningful time; many invalid Timestamps
|
||||
// do map to valid time.Times.
|
||||
//
|
||||
// A nil Timestamp returns an error. The first return value in that case is
|
||||
// undefined.
|
||||
//
|
||||
// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead.
|
||||
func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { |
||||
// Don't return the zero value on error, because corresponds to a valid
|
||||
// timestamp. Instead return whatever time.Unix gives us.
|
||||
var t time.Time |
||||
if ts == nil { |
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else { |
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() |
||||
} |
||||
return t, validateTimestamp(ts) |
||||
} |
||||
|
||||
// TimestampNow returns a google.protobuf.Timestamp for the current time.
|
||||
//
|
||||
// Deprecated: Call the timestamppb.Now function instead.
|
||||
func TimestampNow() *timestamppb.Timestamp { |
||||
ts, err := TimestampProto(time.Now()) |
||||
if err != nil { |
||||
panic("ptypes: time.Now() out of Timestamp range") |
||||
} |
||||
return ts |
||||
} |
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
//
|
||||
// Deprecated: Call the timestamppb.New function instead.
|
||||
func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { |
||||
ts := ×tamppb.Timestamp{ |
||||
Seconds: t.Unix(), |
||||
Nanos: int32(t.Nanosecond()), |
||||
} |
||||
if err := validateTimestamp(ts); err != nil { |
||||
return nil, err |
||||
} |
||||
return ts, nil |
||||
} |
||||
|
||||
// TimestampString returns the RFC 3339 string for valid Timestamps.
|
||||
// For invalid Timestamps, it returns an error message in parentheses.
|
||||
//
|
||||
// Deprecated: Call the ts.AsTime method instead,
|
||||
// followed by a call to the Format method on the time.Time value.
|
||||
func TimestampString(ts *timestamppb.Timestamp) string { |
||||
t, err := Timestamp(ts) |
||||
if err != nil { |
||||
return fmt.Sprintf("(%v)", err) |
||||
} |
||||
return t.Format(time.RFC3339Nano) |
||||
} |
||||
|
||||
// validateTimestamp determines whether a Timestamp is valid.
|
||||
// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01)
|
||||
// and has a Nanos field in the range [0, 1e9).
|
||||
//
|
||||
// If the Timestamp is valid, validateTimestamp returns nil.
|
||||
// Otherwise, it returns an error that describes the problem.
|
||||
//
|
||||
// Every valid Timestamp can be represented by a time.Time,
|
||||
// but the converse is not true.
|
||||
func validateTimestamp(ts *timestamppb.Timestamp) error { |
||||
if ts == nil { |
||||
return errors.New("timestamp: nil Timestamp") |
||||
} |
||||
if ts.Seconds < minValidSeconds { |
||||
return fmt.Errorf("timestamp: %v before 0001-01-01", ts) |
||||
} |
||||
if ts.Seconds >= maxValidSeconds { |
||||
return fmt.Errorf("timestamp: %v after 10000-01-01", ts) |
||||
} |
||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 { |
||||
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) |
||||
} |
||||
return nil |
||||
} |
||||
@ -1,64 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
|
||||
|
||||
package timestamp |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/timestamp.proto.
|
||||
|
||||
type Timestamp = timestamppb.Timestamp |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ |
||||
0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, |
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, |
||||
0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, |
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, |
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, |
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, |
||||
0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, |
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, |
||||
0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, |
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, |
||||
0x33, |
||||
} |
||||
|
||||
var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} |
||||
var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ |
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
} |
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } |
||||
func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { |
||||
if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { |
||||
return |
||||
} |
||||
type x struct{} |
||||
out := protoimpl.TypeBuilder{ |
||||
File: protoimpl.DescBuilder{ |
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), |
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, |
||||
NumEnums: 0, |
||||
NumMessages: 0, |
||||
NumExtensions: 0, |
||||
NumServices: 0, |
||||
}, |
||||
GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, |
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, |
||||
}.Build() |
||||
File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File |
||||
file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil |
||||
file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil |
||||
file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil |
||||
} |
||||
@ -0,0 +1,3 @@
|
||||
# Attribute |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/attribute) |
||||
@ -1,16 +1,5 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package attribute provides key and value attributes.
|
||||
package attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
# Baggage |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/baggage) |
||||
@ -0,0 +1,3 @@
|
||||
# Codes |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/codes) |
||||
@ -0,0 +1,3 @@
|
||||
# OTLP Trace Exporter |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace) |
||||
@ -0,0 +1,3 @@
|
||||
# OTLP Trace gRPC Exporter |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc) |
||||
@ -1,20 +1,9 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
|
||||
// Version is the current release version of the OpenTelemetry OTLP trace exporter in use.
|
||||
func Version() string { |
||||
return "1.24.0" |
||||
return "1.25.0" |
||||
} |
||||
|
||||
@ -0,0 +1,3 @@
|
||||
# Metric API |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/metric) |
||||
@ -0,0 +1,3 @@
|
||||
# Metric Embedded |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/metric/embedded) |
||||
@ -0,0 +1,3 @@
|
||||
# Metric Noop |
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/metric/noop) |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue