protobuf-go/proto/proto.go

46 lines
1.4 KiB
Go
Raw Normal View History

// 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 (
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/reflect/protoreflect"
)
// Message is the top-level interface that all messages must implement.
// It provides access to a reflective view of a message.
// Any implementation of this interface may be used with all functions in the
// protobuf module that accept a Message, except where otherwise specified.
//
// This is the v2 interface definition for protobuf messages.
// The v1 interface definition is [github.com/golang/protobuf/proto.Message].
//
// - To convert a v1 message to a v2 message,
// use [google.golang.org/protobuf/protoadapt.MessageV2Of].
// - To convert a v2 message to a v1 message,
// use [google.golang.org/protobuf/protoadapt.MessageV1Of].
type Message = protoreflect.ProtoMessage
// Error matches all errors produced by packages in the protobuf module
// according to [errors.Is].
//
// Example usage:
//
// if errors.Is(err, proto.Error) { ... }
var Error error
func init() {
Error = errors.Error
}
proto: add MessageName helper The MessageName returns the full name of a message. It is a shorthand for: var name protoreflect.FullName if m != nil { name = m.ProtoReflect().Descriptor().FullName() } Generally, we avoid the addition of helper functions unless their use is justified. Arguments for this helper: • The legacy proto.MessageName is widely used. For example, inside Google, there are thousands of usages of it. It is commonly used in logging and error construction to report the name of a protobuf message. • The fact that a nil-check may be neccessary means that users either forget the nil-check and risk a nil-panic in production code, or users have to write cumbersome logic to check for it. For example, compare use with the helper: return fmt.Errorf("invalid message type: %v", proto.MessageName(m)) to use without the helper: var messageName protoreflect.FullName if m != nil { messageName = m.ProtoReflect().Descriptor().FullName() } return fmt.Errorf("invalid message type: %v", messageName) A point of consideration is whether this should return a string or a protoreflect.FullName. This CL returns the latter type: • Most uses of it are for logging via log.Printf or error construction via fmt.Errorf where it does not matter what the exact string type is since its formatted the same way. • Another use of it is to check for message type equality by doing something similar to: if proto.MessageName(got) != proto.MessageName(want) { ... } in which case it still does not matter what the exact string type is. • The other major use of proto.MessageName is to call proto APIs that actually do expect a protoreflect.FullName (e.g., protoregistry.GlobalTypes.FindExtensionByNumber) where the user currently type-casts the legacy proto.MessageName to a protoreflect.FullName anyways. As such, there does not seem to be much justified use for MessageName as a string. The rare cases that need a string can trivially type cast it to a string. Change-Id: I840758df828eef72e7e63620569363a496366afa Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/242377 Reviewed-by: Damien Neil <dneil@google.com>
2020-07-13 20:13:26 +00:00
// MessageName returns the full name of m.
// If m is nil, it returns an empty string.
func MessageName(m Message) protoreflect.FullName {
if m == nil {
return ""
}
return m.ProtoReflect().Descriptor().FullName()
}