0
0
Fork 0
mirror of https://github.com/crazy-max/diun.git synced 2025-03-18 05:02:53 +00:00

Merge pull request from crazy-max/dependabot/go_modules/google.golang.org/protobuf-1.35.2

chore(deps): bump google.golang.org/protobuf from 1.33.0 to 1.35.2
This commit is contained in:
CrazyMax 2024-12-15 01:32:18 +01:00 committed by GitHub
commit 1b456e14db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
95 changed files with 2426 additions and 2625 deletions
go.modgo.sum
pb
vendor
google.golang.org/protobuf
modules.txt

2
go.mod
View file

@ -45,7 +45,7 @@ require (
golang.org/x/sys v0.25.0
google.golang.org/grpc v1.64.1
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
google.golang.org/protobuf v1.33.0
google.golang.org/protobuf v1.35.2
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.29.3
k8s.io/apimachinery v0.29.3

4
go.sum
View file

@ -449,8 +449,8 @@ google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.33.0
// protoc-gen-go v1.35.2
// protoc v3.17.3
// source: image.proto
@ -37,11 +37,9 @@ type Manifest struct {
func (x *Manifest) Reset() {
*x = Manifest{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Manifest) String() string {
@ -52,7 +50,7 @@ func (*Manifest) ProtoMessage() {}
func (x *Manifest) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -124,11 +122,9 @@ type ImageListRequest struct {
func (x *ImageListRequest) Reset() {
*x = ImageListRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageListRequest) String() string {
@ -139,7 +135,7 @@ func (*ImageListRequest) ProtoMessage() {}
func (x *ImageListRequest) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -164,11 +160,9 @@ type ImageListResponse struct {
func (x *ImageListResponse) Reset() {
*x = ImageListResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageListResponse) String() string {
@ -179,7 +173,7 @@ func (*ImageListResponse) ProtoMessage() {}
func (x *ImageListResponse) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -211,11 +205,9 @@ type ImageInspectRequest struct {
func (x *ImageInspectRequest) Reset() {
*x = ImageInspectRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageInspectRequest) String() string {
@ -226,7 +218,7 @@ func (*ImageInspectRequest) ProtoMessage() {}
func (x *ImageInspectRequest) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -258,11 +250,9 @@ type ImageInspectResponse struct {
func (x *ImageInspectResponse) Reset() {
*x = ImageInspectResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageInspectResponse) String() string {
@ -273,7 +263,7 @@ func (*ImageInspectResponse) ProtoMessage() {}
func (x *ImageInspectResponse) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -305,11 +295,9 @@ type ImageRemoveRequest struct {
func (x *ImageRemoveRequest) Reset() {
*x = ImageRemoveRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageRemoveRequest) String() string {
@ -320,7 +308,7 @@ func (*ImageRemoveRequest) ProtoMessage() {}
func (x *ImageRemoveRequest) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -352,11 +340,9 @@ type ImageRemoveResponse struct {
func (x *ImageRemoveResponse) Reset() {
*x = ImageRemoveResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageRemoveResponse) String() string {
@ -367,7 +353,7 @@ func (*ImageRemoveResponse) ProtoMessage() {}
func (x *ImageRemoveResponse) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -400,11 +386,9 @@ type ImagePruneRequest struct {
func (x *ImagePruneRequest) Reset() {
*x = ImagePruneRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImagePruneRequest) String() string {
@ -415,7 +399,7 @@ func (*ImagePruneRequest) ProtoMessage() {}
func (x *ImagePruneRequest) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -454,11 +438,9 @@ type ImagePruneResponse struct {
func (x *ImagePruneResponse) Reset() {
*x = ImagePruneResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImagePruneResponse) String() string {
@ -469,7 +451,7 @@ func (*ImagePruneResponse) ProtoMessage() {}
func (x *ImagePruneResponse) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -503,11 +485,9 @@ type ImageListResponse_Image struct {
func (x *ImageListResponse_Image) Reset() {
*x = ImageListResponse_Image{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageListResponse_Image) String() string {
@ -518,7 +498,7 @@ func (*ImageListResponse_Image) ProtoMessage() {}
func (x *ImageListResponse_Image) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -565,11 +545,9 @@ type ImageInspectResponse_Image struct {
func (x *ImageInspectResponse_Image) Reset() {
*x = ImageInspectResponse_Image{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImageInspectResponse_Image) String() string {
@ -580,7 +558,7 @@ func (*ImageInspectResponse_Image) ProtoMessage() {}
func (x *ImageInspectResponse_Image) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -620,11 +598,9 @@ type ImagePruneResponse_Image struct {
func (x *ImagePruneResponse_Image) Reset() {
*x = ImagePruneResponse_Image{}
if protoimpl.UnsafeEnabled {
mi := &file_image_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_image_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ImagePruneResponse_Image) String() string {
@ -635,7 +611,7 @@ func (*ImagePruneResponse_Image) ProtoMessage() {}
func (x *ImagePruneResponse_Image) ProtoReflect() protoreflect.Message {
mi := &file_image_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -769,7 +745,7 @@ func file_image_proto_rawDescGZIP() []byte {
}
var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_image_proto_goTypes = []interface{}{
var file_image_proto_goTypes = []any{
(*Manifest)(nil), // 0: pb.Manifest
(*ImageListRequest)(nil), // 1: pb.ImageListRequest
(*ImageListResponse)(nil), // 2: pb.ImageListResponse
@ -815,152 +791,6 @@ func file_image_proto_init() {
if File_image_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_image_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Manifest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageListRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageListResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageInspectRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageInspectResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageRemoveRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageRemoveResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImagePruneRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImagePruneResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageListResponse_Image); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImageInspectResponse_Image); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_image_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImagePruneResponse_Image); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

View file

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.33.0
// protoc-gen-go v1.35.2
// protoc v3.17.3
// source: notif.proto
@ -28,11 +28,9 @@ type NotifTestRequest struct {
func (x *NotifTestRequest) Reset() {
*x = NotifTestRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_notif_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_notif_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NotifTestRequest) String() string {
@ -43,7 +41,7 @@ func (*NotifTestRequest) ProtoMessage() {}
func (x *NotifTestRequest) ProtoReflect() protoreflect.Message {
mi := &file_notif_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -68,11 +66,9 @@ type NotifTestResponse struct {
func (x *NotifTestResponse) Reset() {
*x = NotifTestResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_notif_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_notif_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NotifTestResponse) String() string {
@ -83,7 +79,7 @@ func (*NotifTestResponse) ProtoMessage() {}
func (x *NotifTestResponse) ProtoReflect() protoreflect.Message {
mi := &file_notif_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -136,7 +132,7 @@ func file_notif_proto_rawDescGZIP() []byte {
}
var file_notif_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_notif_proto_goTypes = []interface{}{
var file_notif_proto_goTypes = []any{
(*NotifTestRequest)(nil), // 0: pb.NotifTestRequest
(*NotifTestResponse)(nil), // 1: pb.NotifTestResponse
}
@ -155,32 +151,6 @@ func file_notif_proto_init() {
if File_notif_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_notif_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NotifTestRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_notif_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NotifTestResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

View file

@ -17,6 +17,7 @@ import (
"unicode/utf8"
"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/internal/editionssupport"
"google.golang.org/protobuf/internal/encoding/tag"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/genid"
@ -29,7 +30,10 @@ import (
)
// SupportedFeatures reports the set of supported protobuf language features.
var SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
var SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL | pluginpb.CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS)
var SupportedEditionsMinimum = editionssupport.Minimum
var SupportedEditionsMaximum = editionssupport.Maximum
// GenerateVersionMarkers specifies whether to generate version markers.
var GenerateVersionMarkers = true
@ -37,6 +41,7 @@ var GenerateVersionMarkers = true
// Standard library dependencies.
const (
base64Package = protogen.GoImportPath("encoding/base64")
jsonPackage = protogen.GoImportPath("encoding/json")
mathPackage = protogen.GoImportPath("math")
reflectPackage = protogen.GoImportPath("reflect")
sortPackage = protogen.GoImportPath("sort")
@ -71,11 +76,14 @@ func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated
g := gen.NewGeneratedFile(filename, file.GoImportPath)
f := newFileInfo(file)
genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Syntax_field_number))
genGeneratedHeader(gen, g, f)
genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Package_field_number))
var packageDoc protogen.Comments
if !gen.InternalStripForEditionsDiff() {
genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Syntax_field_number))
genGeneratedHeader(gen, g, f)
genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Package_field_number))
packageDoc := genPackageKnownComment(f)
packageDoc = genPackageKnownComment(f)
}
g.P(packageDoc, "package ", f.GoPackageName)
g.P()
@ -101,7 +109,23 @@ func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated
}
genExtensions(g, f)
genReflectFileDescriptor(gen, g, f)
// The descriptor contains a lot of information about the syntax which is
// quite different between the proto2/3 version of a file and the equivalent
// editions version. For example, when a proto3 file is translated from
// proto3 to editions every field in that file that is marked optional in
// proto3 will have a features.field_presence option set.
// Another problem is that the descriptor contains implementation details
// that are not relevant for the semantic. For example, proto3 optional
// fields are implemented as oneof fields with one case. The descriptor
// contains different information about oneofs. If the file is translated
// to editions it no longer is treated as a oneof with one case and thus
// none of the oneof specific information is generated.
// To be able to compare the descriptor before and after translation of the
// associated proto file, we would need to trim many parts. This would lead
// to a brittle implementation in case the translation ever changes.
if !g.InternalStripForEditionsDiff() {
genReflectFileDescriptor(gen, g, f)
}
return g
}
@ -227,7 +251,7 @@ func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp
func genEnum(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo) {
// Enum type declaration.
g.Annotate(e.GoIdent.GoName, e.Location)
g.AnnotateSymbol(e.GoIdent.GoName, protogen.Annotation{Location: e.Location})
leadingComments := appendDeprecationSuffix(e.Comments.Leading,
e.Desc.ParentFile(),
e.Desc.Options().(*descriptorpb.EnumOptions).GetDeprecated())
@ -236,17 +260,35 @@ func genEnum(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo) {
// Enum value constants.
g.P("const (")
anyOldName := false
for _, value := range e.Values {
g.Annotate(value.GoIdent.GoName, value.Location)
g.AnnotateSymbol(value.GoIdent.GoName, protogen.Annotation{Location: value.Location})
leadingComments := appendDeprecationSuffix(value.Comments.Leading,
value.Desc.ParentFile(),
value.Desc.Options().(*descriptorpb.EnumValueOptions).GetDeprecated())
g.P(leadingComments,
value.GoIdent, " ", e.GoIdent, " = ", value.Desc.Number(),
trailingComment(value.Comments.Trailing))
if value.PrefixedAlias.GoName != "" &&
value.PrefixedAlias.GoName != value.GoIdent.GoName {
anyOldName = true
}
}
g.P(")")
g.P()
if anyOldName {
g.P("// Old (prefixed) names for ", e.GoIdent, " enum values.")
g.P("const (")
for _, value := range e.Values {
if value.PrefixedAlias.GoName != "" &&
value.PrefixedAlias.GoName != value.GoIdent.GoName {
g.P(value.PrefixedAlias, " ", e.GoIdent, " = ", value.GoIdent)
}
}
g.P(")")
g.P()
}
// Enum value maps.
g.P("// Enum value maps for ", e.GoIdent, ".")
@ -289,11 +331,11 @@ func genEnum(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo) {
genEnumReflectMethods(g, f, e)
// UnmarshalJSON method.
needsUnmarshalJSONMethod := e.genJSONMethod && e.Desc.Syntax() == protoreflect.Proto2
if fde, ok := e.Desc.(*filedesc.Enum); ok && fde.L1.EditionFeatures.GenerateLegacyUnmarshalJSON {
needsUnmarshalJSONMethod = true
needsUnmarshalJSONMethod := false
if fde, ok := e.Desc.(*filedesc.Enum); ok {
needsUnmarshalJSONMethod = fde.L1.EditionFeatures.GenerateLegacyUnmarshalJSON
}
if needsUnmarshalJSONMethod {
if e.genJSONMethod && needsUnmarshalJSONMethod {
g.P("// Deprecated: Do not use.")
g.P("func (x *", e.GoIdent, ") UnmarshalJSON(b []byte) error {")
g.P("num, err := ", protoimplPackage.Ident("X"), ".UnmarshalJSONEnum(x.Descriptor(), b)")
@ -327,7 +369,7 @@ func genMessage(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
}
// Message type declaration.
g.Annotate(m.GoIdent.GoName, m.Location)
g.AnnotateSymbol(m.GoIdent.GoName, protogen.Annotation{Location: m.Location})
leadingComments := appendDeprecationSuffix(m.Comments.Leading,
m.Desc.ParentFile(),
m.Desc.Options().(*descriptorpb.MessageOptions).GetDeprecated())
@ -388,7 +430,7 @@ func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, fie
tags = append(tags, gotrackTags...)
}
g.Annotate(m.GoIdent.GoName+"."+oneof.GoName, oneof.Location)
g.AnnotateSymbol(m.GoIdent.GoName+"."+oneof.GoName, protogen.Annotation{Location: oneof.Location})
leadingComments := oneof.Comments.Leading
if leadingComments != "" {
leadingComments += "\n"
@ -427,7 +469,7 @@ func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, fie
if field.Desc.IsWeak() {
name = genid.WeakFieldPrefix_goname + name
}
g.Annotate(m.GoIdent.GoName+"."+name, field.Location)
g.AnnotateSymbol(m.GoIdent.GoName+"."+name, protogen.Annotation{Location: field.Location})
leadingComments := appendDeprecationSuffix(field.Comments.Leading,
field.Desc.ParentFile(),
field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
@ -513,12 +555,10 @@ func genMessageBaseMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInf
// Reset method.
g.P("func (x *", m.GoIdent, ") Reset() {")
g.P("*x = ", m.GoIdent, "{}")
g.P("if ", protoimplPackage.Ident("UnsafeEnabled"), " {")
g.P("mi := &", messageTypesVarName(f), "[", f.allMessagesByPtr[m], "]")
g.P("ms := ", protoimplPackage.Ident("X"), ".MessageStateOf(", protoimplPackage.Ident("Pointer"), "(x))")
g.P("ms.StoreMessageInfo(mi)")
g.P("}")
g.P("}")
g.P()
// String method.
@ -555,7 +595,7 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI
// Getter for parent oneof.
if oneof := field.Oneof; oneof != nil && oneof.Fields[0] == field && !oneof.Desc.IsSynthetic() {
g.Annotate(m.GoIdent.GoName+".Get"+oneof.GoName, oneof.Location)
g.AnnotateSymbol(m.GoIdent.GoName+".Get"+oneof.GoName, protogen.Annotation{Location: oneof.Location})
g.P("func (m *", m.GoIdent.GoName, ") Get", oneof.GoName, "() ", oneofInterfaceName(oneof), " {")
g.P("if m != nil {")
g.P("return m.", oneof.GoName)
@ -568,7 +608,7 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI
// Getter for message field.
goType, pointer := fieldGoType(g, f, field)
defaultValue := fieldDefaultValue(g, f, m, field)
g.Annotate(m.GoIdent.GoName+".Get"+field.GoName, field.Location)
g.AnnotateSymbol(m.GoIdent.GoName+".Get"+field.GoName, protogen.Annotation{Location: field.Location})
leadingComments := appendDeprecationSuffix("",
field.Desc.ParentFile(),
field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
@ -811,8 +851,8 @@ func genMessageOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo, m *mess
g.P("}")
g.P()
for _, field := range oneof.Fields {
g.Annotate(field.GoIdent.GoName, field.Location)
g.Annotate(field.GoIdent.GoName+"."+field.GoName, field.Location)
g.AnnotateSymbol(field.GoIdent.GoName, protogen.Annotation{Location: field.Location})
g.AnnotateSymbol(field.GoIdent.GoName+"."+field.GoName, protogen.Annotation{Location: field.Location})
g.P("type ", field.GoIdent, " struct {")
goType, _ := fieldGoType(g, f, field)
tags := structTags{

View file

@ -132,7 +132,7 @@ func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f
panic("too many dependencies") // sanity check
}
g.P("var ", goTypesVarName(f), " = []interface{}{")
g.P("var ", goTypesVarName(f), " = []any{")
for _, s := range goTypes {
g.P(s)
}
@ -163,27 +163,6 @@ func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f
}
if len(f.allMessages) > 0 {
// Populate MessageInfo.Exporters.
g.P("if !", protoimplPackage.Ident("UnsafeEnabled"), " {")
for _, message := range f.allMessages {
if sf := f.allMessageFieldsByPtr[message]; len(sf.unexported) > 0 {
idx := f.allMessagesByPtr[message]
typesVar := messageTypesVarName(f)
g.P(typesVar, "[", idx, "].Exporter = func(v interface{}, i int) interface{} {")
g.P("switch v := v.(*", message.GoIdent, "); i {")
for i := 0; i < sf.count; i++ {
if name := sf.unexported[i]; name != "" {
g.P("case ", i, ": return &v.", name)
}
}
g.P("default: return nil")
g.P("}")
g.P("}")
}
}
g.P("}")
// Populate MessageInfo.OneofWrappers.
for _, message := range f.allMessages {
if len(message.Oneofs) > 0 {
@ -191,7 +170,7 @@ func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f
typesVar := messageTypesVarName(f)
// Associate the wrapper types by directly passing them to the MessageInfo.
g.P(typesVar, "[", idx, "].OneofWrappers = []interface{} {")
g.P(typesVar, "[", idx, "].OneofWrappers = []any {")
for _, oneof := range message.Oneofs {
if !oneof.Desc.IsSynthetic() {
for _, field := range oneof.Fields {
@ -331,7 +310,7 @@ func genMessageReflectMethods(g *protogen.GeneratedFile, f *fileInfo, m *message
// ProtoReflect method.
g.P("func (x *", m.GoIdent, ") ProtoReflect() ", protoreflectPackage.Ident("Message"), " {")
g.P("mi := &", typesVar, "[", idx, "]")
g.P("if ", protoimplPackage.Ident("UnsafeEnabled"), " && x != nil {")
g.P("if x != nil {")
g.P("ms := ", protoimplPackage.Ident("X"), ".MessageStateOf(", protoimplPackage.Ident("Pointer"), "(x))")
g.P("if ms.LoadMessageInfo() == nil {")
g.P("ms.StoreMessageInfo(mi)")

View file

@ -213,11 +213,11 @@ func genPackageKnownComment(f *fileInfo) protogen.Comments {
The standard Go "encoding/json" package has functionality to serialize
arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and
ListValue.AsSlice methods can convert the protobuf message representation into
a form represented by interface{}, map[string]interface{}, and []interface{}.
a form represented by any, map[string]any, and []any.
This form can be used with other packages that operate on such data structures
and also directly with the standard json package.
In order to convert the interface{}, map[string]interface{}, and []interface{}
In order to convert the any, map[string]any, and []any
forms back as Value, Struct, and ListValue messages, use the NewStruct,
NewList, and NewValue constructor functions.
@ -252,28 +252,28 @@ func genPackageKnownComment(f *fileInfo) protogen.Comments {
To construct a Value message representing the above JSON object:
m, err := structpb.NewValue(map[string]interface{}{
m, err := structpb.NewValue(map[string]any{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": map[string]interface{}{
"address": map[string]any{
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100",
},
"phoneNumbers": []interface{}{
map[string]interface{}{
"phoneNumbers": []any{
map[string]any{
"type": "home",
"number": "212 555-1234",
},
map[string]interface{}{
map[string]any{
"type": "office",
"number": "646 555-4567",
},
},
"children": []interface{}{},
"children": []any{},
"spouse": nil,
})
if err != nil {
@ -634,7 +634,7 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P("// NewStruct constructs a Struct from a general-purpose Go map.")
g.P("// The map keys must be valid UTF-8.")
g.P("// The map values are converted using NewValue.")
g.P("func NewStruct(v map[string]interface{}) (*Struct, error) {")
g.P("func NewStruct(v map[string]any) (*Struct, error) {")
g.P(" x := &Struct{Fields: make(map[string]*Value, len(v))}")
g.P(" for k, v := range v {")
g.P(" if !", utf8Package.Ident("ValidString"), "(k) {")
@ -652,9 +652,9 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P("// AsMap converts x to a general-purpose Go map.")
g.P("// The map values are converted by calling Value.AsInterface.")
g.P("func (x *Struct) AsMap() map[string]interface{} {")
g.P("func (x *Struct) AsMap() map[string]any {")
g.P(" f := x.GetFields()")
g.P(" vs := make(map[string]interface{}, len(f))")
g.P(" vs := make(map[string]any, len(f))")
g.P(" for k, v := range f {")
g.P(" vs[k] = v.AsInterface()")
g.P(" }")
@ -675,7 +675,7 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
case genid.ListValue_message_fullname:
g.P("// NewList constructs a ListValue from a general-purpose Go slice.")
g.P("// The slice elements are converted using NewValue.")
g.P("func NewList(v []interface{}) (*ListValue, error) {")
g.P("func NewList(v []any) (*ListValue, error) {")
g.P(" x := &ListValue{Values: make([]*Value, len(v))}")
g.P(" for i, v := range v {")
g.P(" var err error")
@ -690,9 +690,9 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P("// AsSlice converts x to a general-purpose Go slice.")
g.P("// The slice elements are converted by calling Value.AsInterface.")
g.P("func (x *ListValue) AsSlice() []interface{} {")
g.P("func (x *ListValue) AsSlice() []any {")
g.P(" vals := x.GetValues()")
g.P(" vs := make([]interface{}, len(vals))")
g.P(" vs := make([]any, len(vals))")
g.P(" for i, v := range vals {")
g.P(" vs[i] = v.AsInterface()")
g.P(" }")
@ -713,23 +713,24 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
case genid.Value_message_fullname:
g.P("// NewValue constructs a Value from a general-purpose Go interface.")
g.P("//")
g.P("// ╔════════════════════════╤════════════════════════════════════════════╗")
g.P("// ║ Go type │ Conversion ║")
g.P("// ╠════════════════════════╪════════════════════════════════════════════╣")
g.P("// ║ nil │ stored as NullValue ║")
g.P("// ║ bool │ stored as BoolValue ║")
g.P("// ║ int, int32, int64 │ stored as NumberValue ║")
g.P("// ║ uint, uint32, uint64 │ stored as NumberValue ║")
g.P("// ║ float32, float64 │ stored as NumberValue ║")
g.P("// ║ string │ stored as StringValue; must be valid UTF-8 ║")
g.P("// ║ []byte │ stored as StringValue; base64-encoded ║")
g.P("// ║ map[string]interface{} │ stored as StructValue ║")
g.P("// ║ []interface{} │ stored as ListValue ║")
g.P("// ╚════════════════════════╧════════════════════════════════════════════╝")
g.P("// ╔═══════════════════════════════════════╤════════════════════════════════════════════╗")
g.P("// ║ Go type │ Conversion ║")
g.P("// ╠═══════════════════════════════════════╪════════════════════════════════════════════╣")
g.P("// ║ nil │ stored as NullValue ║")
g.P("// ║ bool │ stored as BoolValue ║")
g.P("// ║ int, int8, int16, int32, int64 │ stored as NumberValue ║")
g.P("// ║ uint, uint8, uint16, uint32, uint64 │ stored as NumberValue ║")
g.P("// ║ float32, float64 │ stored as NumberValue ║")
g.P("// ║ json.Number │ stored as NumberValue ║")
g.P("// ║ string │ stored as StringValue; must be valid UTF-8 ║")
g.P("// ║ []byte │ stored as StringValue; base64-encoded ║")
g.P("// ║ map[string]any │ stored as StructValue ║")
g.P("// ║ []any │ stored as ListValue ║")
g.P("// ╚═══════════════════════════════════════╧════════════════════════════════════════════╝")
g.P("//")
g.P("// When converting an int64 or uint64 to a NumberValue, numeric precision loss")
g.P("// is possible since they are stored as a float64.")
g.P("func NewValue(v interface{}) (*Value, error) {")
g.P("func NewValue(v any) (*Value, error) {")
g.P(" switch v := v.(type) {")
g.P(" case nil:")
g.P(" return NewNullValue(), nil")
@ -737,12 +738,20 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P(" return NewBoolValue(v), nil")
g.P(" case int:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case int8:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case int16:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case int32:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case int64:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case uint:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case uint8:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case uint16:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case uint32:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case uint64:")
@ -751,6 +760,12 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case float64:")
g.P(" return NewNumberValue(float64(v)), nil")
g.P(" case ", jsonPackage.Ident("Number"), ":")
g.P(" n, err := v.Float64()")
g.P(" if err != nil {")
g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid number format %q, expected a float64: %v\", v, err)")
g.P(" }")
g.P(" return NewNumberValue(n), nil")
g.P(" case string:")
g.P(" if !", utf8Package.Ident("ValidString"), "(v) {")
g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid UTF-8 in string: %q\", v)")
@ -759,13 +774,13 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P(" case []byte:")
g.P(" s := ", base64Package.Ident("StdEncoding"), ".EncodeToString(v)")
g.P(" return NewStringValue(s), nil")
g.P(" case map[string]interface{}:")
g.P(" case map[string]any:")
g.P(" v2, err := NewStruct(v)")
g.P(" if err != nil {")
g.P(" return nil, err")
g.P(" }")
g.P(" return NewStructValue(v2), nil")
g.P(" case []interface{}:")
g.P(" case []any:")
g.P(" v2, err := NewList(v)")
g.P(" if err != nil {")
g.P(" return nil, err")
@ -820,7 +835,7 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message
g.P("//")
g.P("// Floating-point values (i.e., \"NaN\", \"Infinity\", and \"-Infinity\") are")
g.P("// converted as strings to remain compatible with MarshalJSON.")
g.P("func (x *Value) AsInterface() interface{} {")
g.P("func (x *Value) AsInterface() any {")
g.P(" switch v := x.GetKind().(type) {")
g.P(" case *Value_NumberValue:")
g.P(" if v != nil {")

View file

@ -35,11 +35,13 @@ func main() {
}
var (
flags flag.FlagSet
plugins = flags.String("plugins", "", "deprecated option")
flags flag.FlagSet
plugins = flags.String("plugins", "", "deprecated option")
experimentalStripNonFunctionalCodegen = flags.Bool("experimental_strip_nonfunctional_codegen", false, "experimental_strip_nonfunctional_codegen true means that the plugin will not emit certain parts of the generated code in order to make it possible to compare a proto2/proto3 file with its equivalent (according to proto spec) editions file. Primarily, this is the encoded descriptor.")
)
protogen.Options{
ParamFunc: flags.Set,
ParamFunc: flags.Set,
InternalStripForEditionsDiff: experimentalStripNonFunctionalCodegen,
}.Run(func(gen *protogen.Plugin) error {
if *plugins != "" {
return errors.New("protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC\n\n" +
@ -51,6 +53,8 @@ func main() {
}
}
gen.SupportedFeatures = gengo.SupportedFeatures
gen.SupportedEditionsMinimum = gengo.SupportedEditionsMinimum
gen.SupportedEditionsMaximum = gengo.SupportedEditionsMaximum
return nil
})
}

View file

@ -19,7 +19,7 @@ import (
"go/printer"
"go/token"
"go/types"
"io/ioutil"
"io"
"os"
"path"
"path/filepath"
@ -28,6 +28,7 @@ import (
"strings"
"google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
@ -37,6 +38,7 @@ import (
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/dynamicpb"
"google.golang.org/protobuf/types/gofeaturespb"
"google.golang.org/protobuf/types/pluginpb"
)
@ -60,7 +62,7 @@ func run(opts Options, f func(*Plugin) error) error {
if len(os.Args) > 1 {
return fmt.Errorf("unknown argument %q (this program should be run by protoc, not directly)", os.Args[1])
}
in, err := ioutil.ReadAll(os.Stdin)
in, err := io.ReadAll(os.Stdin)
if err != nil {
return err
}
@ -108,6 +110,9 @@ type Plugin struct {
// google.protobuf.CodeGeneratorResponse.supported_features for details.
SupportedFeatures uint64
SupportedEditionsMinimum descriptorpb.Edition
SupportedEditionsMaximum descriptorpb.Edition
fileReg *protoregistry.Files
enumsByName map[protoreflect.FullName]*Enum
messagesByName map[protoreflect.FullName]*Message
@ -140,7 +145,7 @@ type Options struct {
// opts := &protogen.Options{
// ParamFunc: flags.Set,
// }
// protogen.Run(opts, func(p *protogen.Plugin) error {
// opts.Run(func(p *protogen.Plugin) error {
// if *value { ... }
// })
ParamFunc func(name, value string) error
@ -149,6 +154,18 @@ type Options struct {
// imported by a generated file. It returns the import path to use
// for this package.
ImportRewriteFunc func(GoImportPath) GoImportPath
// StripForEditionsDiff true means that the plugin will not emit certain
// parts of the generated code in order to make it possible to compare a
// proto2/proto3 file with its equivalent (according to proto spec)
// editions file. Primarily, this is the encoded descriptor.
//
// This must be a registered flag that is initialized by ParamFunc. It will
// be used by Options.New after it has parsed the flags.
//
// This struct field is for internal use by Go Protobuf only. Do not use it,
// we might remove it at any time.
InternalStripForEditionsDiff *bool
}
// New returns a new Plugin.
@ -341,6 +358,15 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) {
return gen, nil
}
// InternalStripForEditionsDiff returns whether or not to strip non-functional
// codegen for editions diff testing.
//
// This function is for internal use by Go Protobuf only. Do not use it, we
// might remove it at any time.
func (gen *Plugin) InternalStripForEditionsDiff() bool {
return gen.opts.InternalStripForEditionsDiff != nil && *gen.opts.InternalStripForEditionsDiff
}
// Error records an error in code generation. The generator will report the
// error back to protoc and will not produce output.
func (gen *Plugin) Error(err error) {
@ -352,6 +378,20 @@ func (gen *Plugin) Error(err error) {
// Response returns the generator output.
func (gen *Plugin) Response() *pluginpb.CodeGeneratorResponse {
resp := &pluginpb.CodeGeneratorResponse{}
// Always report the support for editions. Otherwise protoc might obfuscate
// the error by saying editions are not supported by the plugin.
// It is arguable if protoc should handle this but it is possible that the
// error only exists because the plugin does not support editions and thus
// it is not unreasonable for protoc to suspect it is the lack of editions
// support that led to this error.
if gen.SupportedFeatures > 0 {
resp.SupportedFeatures = proto.Uint64(gen.SupportedFeatures)
}
if gen.SupportedEditionsMinimum != descriptorpb.Edition_EDITION_UNKNOWN && gen.SupportedEditionsMaximum != descriptorpb.Edition_EDITION_UNKNOWN {
resp.MinimumEdition = proto.Int32(int32(gen.SupportedEditionsMinimum))
resp.MaximumEdition = proto.Int32(int32(gen.SupportedEditionsMaximum))
}
if gen.err != nil {
resp.Error = proto.String(gen.err.Error())
return resp
@ -393,9 +433,6 @@ func (gen *Plugin) Response() *pluginpb.CodeGeneratorResponse {
})
}
}
if gen.SupportedFeatures > 0 {
resp.SupportedFeatures = proto.Uint64(gen.SupportedFeatures)
}
return resp
}
@ -524,7 +561,7 @@ func newEnum(gen *Plugin, f *File, parent *Message, desc protoreflect.EnumDescri
Desc: desc,
GoIdent: newGoIdent(f, desc),
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
gen.enumsByName[desc.FullName()] = enum
for i, vds := 0, enum.Desc.Values(); i < vds.Len(); i++ {
@ -539,6 +576,12 @@ type EnumValue struct {
GoIdent GoIdent // name of the generated Go declaration
// PrefixedAlias is usually empty, except when the strip_enum_prefix feature
// for this enum was set to GENERATE_BOTH, in which case PrefixedAlias holds
// the old name which should be generated as an alias for the new name for
// compatibility.
PrefixedAlias GoIdent
Parent *Enum // enum in which this value is declared
Location Location // location of this enum value
@ -555,14 +598,46 @@ func newEnumValue(gen *Plugin, f *File, message *Message, enum *Enum, desc proto
parentIdent = message.GoIdent
}
name := parentIdent.GoName + "_" + string(desc.Name())
var prefixedName string
loc := enum.Location.appendPath(genid.EnumDescriptorProto_Value_field_number, desc.Index())
return &EnumValue{
if ed, ok := enum.Desc.(*filedesc.Enum); ok {
prefix := strings.Replace(strings.ToLower(string(enum.Desc.Name())), "_", "", -1)
// Start with the StripEnumPrefix of the enum descriptor,
// then override it with the StripEnumPrefix of the enum value descriptor,
// if any.
sep := ed.L1.EditionFeatures.StripEnumPrefix
evof := desc.Options().(*descriptorpb.EnumValueOptions).GetFeatures()
if proto.HasExtension(evof, gofeaturespb.E_Go) {
gf := proto.GetExtension(evof, gofeaturespb.E_Go).(*gofeaturespb.GoFeatures)
if gf.StripEnumPrefix != nil {
sep = int(*gf.StripEnumPrefix)
}
}
switch sep {
case genid.GoFeatures_STRIP_ENUM_PREFIX_KEEP_enum_value:
// keep long name
case genid.GoFeatures_STRIP_ENUM_PREFIX_STRIP_enum_value:
name = parentIdent.GoName + "_" + strs.TrimEnumPrefix(string(desc.Name()), prefix)
case genid.GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH_enum_value:
prefixedName = name
name = parentIdent.GoName + "_" + strs.TrimEnumPrefix(string(desc.Name()), prefix)
}
}
ev := &EnumValue{
Desc: desc,
GoIdent: f.GoImportPath.Ident(name),
Parent: enum,
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
if prefixedName != "" {
ev.PrefixedAlias = f.GoImportPath.Ident(prefixedName)
}
return ev
}
// A Message describes a message.
@ -593,7 +668,7 @@ func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.Message
Desc: desc,
GoIdent: newGoIdent(f, desc),
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
gen.messagesByName[desc.FullName()] = message
for i, eds := 0, desc.Enums(); i < eds.Len(); i++ {
@ -763,7 +838,7 @@ func newField(gen *Plugin, f *File, message *Message, desc protoreflect.FieldDes
},
Parent: message,
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
return field
}
@ -830,7 +905,7 @@ func newOneof(gen *Plugin, f *File, message *Message, desc protoreflect.OneofDes
GoName: parentPrefix + camelCased,
},
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
}
@ -855,7 +930,7 @@ func newService(gen *Plugin, f *File, desc protoreflect.ServiceDescriptor) *Serv
Desc: desc,
GoName: strs.GoCamelCase(string(desc.Name())),
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
for i, mds := 0, desc.Methods(); i < mds.Len(); i++ {
service.Methods = append(service.Methods, newMethod(gen, f, service, mds.Get(i)))
@ -885,7 +960,7 @@ func newMethod(gen *Plugin, f *File, service *Service, desc protoreflect.MethodD
GoName: strs.GoCamelCase(string(desc.Name())),
Parent: service,
Location: loc,
Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
Comments: makeCommentSet(gen, f.Desc.SourceLocations().ByDescriptor(desc)),
}
return method
}
@ -912,28 +987,30 @@ func (method *Method) resolveDependencies(gen *Plugin) error {
// A GeneratedFile is a generated file.
type GeneratedFile struct {
gen *Plugin
skip bool
filename string
goImportPath GoImportPath
buf bytes.Buffer
packageNames map[GoImportPath]GoPackageName
usedPackageNames map[GoPackageName]bool
manualImports map[GoImportPath]bool
annotations map[string][]Annotation
gen *Plugin
skip bool
filename string
goImportPath GoImportPath
buf bytes.Buffer
packageNames map[GoImportPath]GoPackageName
usedPackageNames map[GoPackageName]bool
manualImports map[GoImportPath]bool
annotations map[string][]Annotation
stripForEditionsDiff bool
}
// NewGeneratedFile creates a new generated file with the given filename
// and import path.
func (gen *Plugin) NewGeneratedFile(filename string, goImportPath GoImportPath) *GeneratedFile {
g := &GeneratedFile{
gen: gen,
filename: filename,
goImportPath: goImportPath,
packageNames: make(map[GoImportPath]GoPackageName),
usedPackageNames: make(map[GoPackageName]bool),
manualImports: make(map[GoImportPath]bool),
annotations: make(map[string][]Annotation),
gen: gen,
filename: filename,
goImportPath: goImportPath,
packageNames: make(map[GoImportPath]GoPackageName),
usedPackageNames: make(map[GoPackageName]bool),
manualImports: make(map[GoImportPath]bool),
annotations: make(map[string][]Annotation),
stripForEditionsDiff: gen.InternalStripForEditionsDiff(),
}
// All predeclared identifiers in Go are already used.
@ -948,7 +1025,7 @@ func (gen *Plugin) NewGeneratedFile(filename string, goImportPath GoImportPath)
// P prints a line to the generated output. It converts each parameter to a
// string following the same rules as [fmt.Print]. It never inserts spaces
// between parameters.
func (g *GeneratedFile) P(v ...interface{}) {
func (g *GeneratedFile) P(v ...any) {
for _, x := range v {
switch x := x.(type) {
case GoIdent:
@ -1006,6 +1083,17 @@ func (g *GeneratedFile) Unskip() {
g.skip = false
}
// InternalStripForEditionsDiff returns true if the plugin should not emit certain
// parts of the generated code in order to make it possible to compare a
// proto2/proto3 file with its equivalent (according to proto spec) editions
// file. Primarily, this is the encoded descriptor.
//
// This function is for internal use by Go Protobuf only. Do not use it, we
// might remove it at any time.
func (g *GeneratedFile) InternalStripForEditionsDiff() bool {
return g.stripForEditionsDiff
}
// Annotate associates a symbol in a generated Go file with a location in a
// source .proto file.
//
@ -1284,7 +1372,10 @@ type CommentSet struct {
Trailing Comments
}
func makeCommentSet(loc protoreflect.SourceLocation) CommentSet {
func makeCommentSet(gen *Plugin, loc protoreflect.SourceLocation) CommentSet {
if gen.InternalStripForEditionsDiff() {
return CommentSet{}
}
var leadingDetached []Comments
for _, s := range loc.LeadingDetachedComments {
leadingDetached = append(leadingDetached, Comments(s))

View file

@ -102,7 +102,7 @@ type decoder struct {
}
// newError returns an error object with position info.
func (d decoder) newError(pos int, f string, x ...interface{}) error {
func (d decoder) newError(pos int, f string, x ...any) error {
line, column := d.Position(pos)
head := fmt.Sprintf("(line %d:%d): ", line, column)
return errors.New(head+f, x...)
@ -114,7 +114,7 @@ func (d decoder) unexpectedTokenError(tok json.Token) error {
}
// syntaxError returns a syntax error for given position.
func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
func (d decoder) syntaxError(pos int, f string, x ...any) error {
line, column := d.Position(pos)
head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
return errors.New(head+f, x...)
@ -351,7 +351,7 @@ func (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.
panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", kind))
}
return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v field %v: %v", kind, fd.JSONName(), tok.RawString())
}
func unmarshalInt(tok json.Token, bitSize int) (protoreflect.Value, bool) {

View file

@ -25,15 +25,17 @@ const defaultIndent = " "
// Format formats the message as a multiline string.
// This function is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func Format(m proto.Message) string {
return MarshalOptions{Multiline: true}.Format(m)
}
// Marshal writes the given [proto.Message] in JSON format using default options.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func Marshal(m proto.Message) ([]byte, error) {
return MarshalOptions{}.Marshal(m)
}
@ -110,8 +112,9 @@ type MarshalOptions struct {
// Format formats the message as a string.
// This method is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func (o MarshalOptions) Format(m proto.Message) string {
if m == nil || !m.ProtoReflect().IsValid() {
return "<nil>" // invalid syntax, but okay since this is for debugging
@ -122,8 +125,9 @@ func (o MarshalOptions) Format(m proto.Message) string {
}
// Marshal marshals the given [proto.Message] in the JSON format using options in
// MarshalOptions. Do not depend on the output being stable. It may change over
// time across different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
return o.marshal(nil, m)
}
@ -212,9 +216,7 @@ func (m unpopulatedFieldRanger) Range(f func(protoreflect.FieldDescriptor, proto
}
v := m.Get(fd)
isProto2Scalar := fd.Syntax() == protoreflect.Proto2 && fd.Default().IsValid()
isSingularMessage := fd.Cardinality() != protoreflect.Repeated && fd.Message() != nil
if isProto2Scalar || isSingularMessage {
if fd.HasPresence() {
if m.skipNull {
continue
}

View file

@ -348,7 +348,11 @@ func (d decoder) unmarshalAnyValue(unmarshal unmarshalFunc, m protoreflect.Messa
switch tok.Kind() {
case json.ObjectClose:
if !found {
return d.newError(tok.Pos(), `missing "value" field`)
// We tolerate an omitted `value` field with the google.protobuf.Empty Well-Known-Type,
// for compatibility with other proto runtimes that have interpreted the spec differently.
if m.Descriptor().FullName() != genid.Empty_message_fullname {
return d.newError(tok.Pos(), `missing "value" field`)
}
}
return nil

View file

@ -84,7 +84,7 @@ type decoder struct {
}
// newError returns an error object with position info.
func (d decoder) newError(pos int, f string, x ...interface{}) error {
func (d decoder) newError(pos int, f string, x ...any) error {
line, column := d.Position(pos)
head := fmt.Sprintf("(line %d:%d): ", line, column)
return errors.New(head+f, x...)
@ -96,7 +96,7 @@ func (d decoder) unexpectedTokenError(tok text.Token) error {
}
// syntaxError returns a syntax error for given position.
func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
func (d decoder) syntaxError(pos int, f string, x ...any) error {
line, column := d.Position(pos)
head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
return errors.New(head+f, x...)

View file

@ -27,15 +27,17 @@ const defaultIndent = " "
// Format formats the message as a multiline string.
// This function is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func Format(m proto.Message) string {
return MarshalOptions{Multiline: true}.Format(m)
}
// Marshal writes the given [proto.Message] in textproto format using default
// options. Do not depend on the output being stable. It may change over time
// across different versions of the program.
// options. Do not depend on the output being stable. Its output will change
// across different builds of your program, even when using the same version of
// the protobuf module.
func Marshal(m proto.Message) ([]byte, error) {
return MarshalOptions{}.Marshal(m)
}
@ -84,8 +86,9 @@ type MarshalOptions struct {
// Format formats the message as a string.
// This method is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
// Do not depend on the output being stable. Its output will change across
// different builds of your program, even when using the same version of the
// protobuf module.
func (o MarshalOptions) Format(m proto.Message) string {
if m == nil || !m.ProtoReflect().IsValid() {
return "<nil>" // invalid syntax, but okay since this is for debugging
@ -98,8 +101,9 @@ func (o MarshalOptions) Format(m proto.Message) string {
}
// Marshal writes the given [proto.Message] in textproto format using options in
// MarshalOptions object. Do not depend on the output being stable. It may
// change over time across different versions of the program.
// MarshalOptions object. Do not depend on the output being stable. Its output
// will change across different builds of your program, even when using the
// same version of the protobuf module.
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
return o.marshal(nil, m)
}

View file

@ -252,6 +252,7 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu
{rv.MethodByName("Values"), "Values"},
{rv.MethodByName("ReservedNames"), "ReservedNames"},
{rv.MethodByName("ReservedRanges"), "ReservedRanges"},
{rv.MethodByName("IsClosed"), "IsClosed"},
}...)
case protoreflect.EnumValueDescriptor:

View file

@ -9,7 +9,7 @@
// dependency on the descriptor proto package).
package descopts
import pref "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
// These variables are set by the init function in descriptor.pb.go via logic
// in internal/filetype. In other words, so long as the descriptor proto package
@ -17,13 +17,13 @@ import pref "google.golang.org/protobuf/reflect/protoreflect"
//
// Each variable is populated with a nil pointer to the options struct.
var (
File pref.ProtoMessage
Enum pref.ProtoMessage
EnumValue pref.ProtoMessage
Message pref.ProtoMessage
Field pref.ProtoMessage
Oneof pref.ProtoMessage
ExtensionRange pref.ProtoMessage
Service pref.ProtoMessage
Method pref.ProtoMessage
File protoreflect.ProtoMessage
Enum protoreflect.ProtoMessage
EnumValue protoreflect.ProtoMessage
Message protoreflect.ProtoMessage
Field protoreflect.ProtoMessage
Oneof protoreflect.ProtoMessage
ExtensionRange protoreflect.ProtoMessage
Service protoreflect.ProtoMessage
Method protoreflect.ProtoMessage
)

View file

@ -0,0 +1,18 @@
// Copyright 2024 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 editionssupport defines constants for editions that are supported.
package editionssupport
import "google.golang.org/protobuf/types/descriptorpb"
const (
Minimum = descriptorpb.Edition_EDITION_PROTO2
Maximum = descriptorpb.Edition_EDITION_2023
// MaximumKnown is the maximum edition that is known to Go Protobuf, but not
// declared as supported. In other words: end users cannot use it, but
// testprotos inside Go Protobuf can.
MaximumKnown = descriptorpb.Edition_EDITION_2024
)

View file

@ -214,7 +214,7 @@ func (d *Decoder) parseNext() (Token, error) {
// newSyntaxError returns an error with line and column information useful for
// syntax errors.
func (d *Decoder) newSyntaxError(pos int, f string, x ...interface{}) error {
func (d *Decoder) newSyntaxError(pos int, f string, x ...any) error {
e := errors.New(f, x...)
line, column := d.Position(pos)
return errors.New("syntax error (line %d:%d): %v", line, column, e)

View file

@ -32,6 +32,7 @@ var byteType = reflect.TypeOf(byte(0))
func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor {
f := new(filedesc.Field)
f.L0.ParentFile = filedesc.SurrogateProto2
f.L1.EditionFeatures = f.L0.ParentFile.L1.EditionFeatures
for len(tag) > 0 {
i := strings.IndexByte(tag, ',')
if i < 0 {
@ -107,8 +108,7 @@ func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescri
f.L1.StringName.InitJSON(jsonName)
}
case s == "packed":
f.L1.HasPacked = true
f.L1.IsPacked = true
f.L1.EditionFeatures.IsPacked = true
case strings.HasPrefix(s, "weak="):
f.L1.IsWeak = true
f.L1.Message = filedesc.PlaceholderMessage(protoreflect.FullName(s[len("weak="):]))

View file

@ -601,7 +601,7 @@ func (d *Decoder) consumeToken(kind Kind, size int, attrs uint8) Token {
// newSyntaxError returns a syntax error with line and column information for
// current position.
func (d *Decoder) newSyntaxError(f string, x ...interface{}) error {
func (d *Decoder) newSyntaxError(f string, x ...any) error {
e := errors.New(f, x...)
line, column := d.Position(len(d.orig) - len(d.in))
return errors.New("syntax error (line %d:%d): %v", line, column, e)

View file

@ -17,7 +17,7 @@ var Error = errors.New("protobuf error")
// New formats a string according to the format specifier and arguments and
// returns an error that has a "proto" prefix.
func New(f string, x ...interface{}) error {
func New(f string, x ...any) error {
return &prefixError{s: format(f, x...)}
}
@ -43,7 +43,7 @@ func (e *prefixError) Unwrap() error {
// Wrap returns an error that has a "proto" prefix, the formatted string described
// by the format specifier and arguments, and a suffix of err. The error wraps err.
func Wrap(err error, f string, x ...interface{}) error {
func Wrap(err error, f string, x ...any) error {
return &wrapError{
s: format(f, x...),
err: err,
@ -67,7 +67,7 @@ func (e *wrapError) Is(target error) bool {
return target == Error
}
func format(f string, x ...interface{}) string {
func format(f string, x ...any) string {
// avoid "proto: " prefix when chaining
for i := 0; i < len(x); i++ {
switch e := x[i].(type) {
@ -87,3 +87,18 @@ func InvalidUTF8(name string) error {
func RequiredNotSet(name string) error {
return New("required field %v not set", name)
}
type SizeMismatchError struct {
Calculated, Measured int
}
func (e *SizeMismatchError) Error() string {
return fmt.Sprintf("size mismatch (see https://github.com/golang/protobuf/issues/1609): calculated=%d, measured=%d", e.Calculated, e.Measured)
}
func MismatchedSizeCalculation(calculated, measured int) error {
return &SizeMismatchError{
Calculated: calculated,
Measured: measured,
}
}

View file

@ -7,6 +7,7 @@ package filedesc
import (
"bytes"
"fmt"
"strings"
"sync"
"sync/atomic"
@ -31,6 +32,7 @@ const (
EditionProto2 Edition = 998
EditionProto3 Edition = 999
Edition2023 Edition = 1000
Edition2024 Edition = 1001
EditionUnsupported Edition = 100000
)
@ -76,28 +78,42 @@ type (
Locations SourceLocations
}
// EditionFeatures is a frequently-instantiated struct, so please take care
// to minimize padding when adding new fields to this struct (add them in
// the right place/order).
EditionFeatures struct {
// StripEnumPrefix determines if the plugin generates enum value
// constants as-is, with their prefix stripped, or both variants.
StripEnumPrefix int
// IsFieldPresence is true if field_presence is EXPLICIT
// https://protobuf.dev/editions/features/#field_presence
IsFieldPresence bool
// IsFieldPresence is true if field_presence is LEGACY_REQUIRED
// https://protobuf.dev/editions/features/#field_presence
IsLegacyRequired bool
// IsOpenEnum is true if enum_type is OPEN
// https://protobuf.dev/editions/features/#enum_type
IsOpenEnum bool
// IsPacked is true if repeated_field_encoding is PACKED
// https://protobuf.dev/editions/features/#repeated_field_encoding
IsPacked bool
// IsUTF8Validated is true if utf_validation is VERIFY
// https://protobuf.dev/editions/features/#utf8_validation
IsUTF8Validated bool
// IsDelimitedEncoded is true if message_encoding is DELIMITED
// https://protobuf.dev/editions/features/#message_encoding
IsDelimitedEncoded bool
// IsJSONCompliant is true if json_format is ALLOW
// https://protobuf.dev/editions/features/#json_format
IsJSONCompliant bool
// GenerateLegacyUnmarshalJSON determines if the plugin generates the
// UnmarshalJSON([]byte) error method for enums.
GenerateLegacyUnmarshalJSON bool
@ -108,9 +124,12 @@ func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
func (fd *File) Parent() protoreflect.Descriptor { return nil }
func (fd *File) Index() int { return 0 }
func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax }
func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() }
func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
func (fd *File) IsPlaceholder() bool { return false }
// Not exported and just used to reconstruct the original FileDescriptor proto
func (fd *File) Edition() int32 { return int32(fd.L1.Edition) }
func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() }
func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
func (fd *File) IsPlaceholder() bool { return false }
func (fd *File) Options() protoreflect.ProtoMessage {
if f := fd.lazyInit().Options; f != nil {
return f()
@ -202,6 +221,9 @@ func (ed *Enum) lazyInit() *EnumL2 {
ed.L0.ParentFile.lazyInit() // implicitly initializes L2
return ed.L2
}
func (ed *Enum) IsClosed() bool {
return !ed.L1.EditionFeatures.IsOpenEnum
}
func (ed *EnumValue) Options() protoreflect.ProtoMessage {
if f := ed.L1.Options; f != nil {
@ -251,10 +273,7 @@ type (
StringName stringName
IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
IsWeak bool // promoted from google.protobuf.FieldOptions
HasPacked bool // promoted from google.protobuf.FieldOptions
IsPacked bool // promoted from google.protobuf.FieldOptions
HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions
EnforceUTF8 bool // promoted from google.protobuf.FieldOptions
IsLazy bool // promoted from google.protobuf.FieldOptions
Default defaultValue
ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
Enum protoreflect.EnumDescriptor
@ -331,8 +350,7 @@ func (fd *Field) HasPresence() bool {
if fd.L1.Cardinality == protoreflect.Repeated {
return false
}
explicitFieldPresence := fd.Syntax() == protoreflect.Editions && fd.L1.EditionFeatures.IsFieldPresence
return fd.Syntax() == protoreflect.Proto2 || explicitFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil
return fd.IsExtension() || fd.L1.EditionFeatures.IsFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil
}
func (fd *Field) HasOptionalKeyword() bool {
return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
@ -345,17 +363,11 @@ func (fd *Field) IsPacked() bool {
case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
return false
}
if fd.L0.ParentFile.L1.Syntax == protoreflect.Editions {
return fd.L1.EditionFeatures.IsPacked
}
if fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3 {
// proto3 repeated fields are packed by default.
return !fd.L1.HasPacked || fd.L1.IsPacked
}
return fd.L1.IsPacked
return fd.L1.EditionFeatures.IsPacked
}
func (fd *Field) IsExtension() bool { return false }
func (fd *Field) IsWeak() bool { return fd.L1.IsWeak }
func (fd *Field) IsLazy() bool { return fd.L1.IsLazy }
func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
func (fd *Field) MapKey() protoreflect.FieldDescriptor {
@ -388,6 +400,10 @@ func (fd *Field) Message() protoreflect.MessageDescriptor {
}
return fd.L1.Message
}
func (fd *Field) IsMapEntry() bool {
parent, ok := fd.L0.Parent.(protoreflect.MessageDescriptor)
return ok && parent.IsMapEntry()
}
func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
@ -399,13 +415,7 @@ func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *Field) EnforceUTF8() bool {
if fd.L0.ParentFile.L1.Syntax == protoreflect.Editions {
return fd.L1.EditionFeatures.IsUTF8Validated
}
if fd.L1.HasEnforceUTF8 {
return fd.L1.EnforceUTF8
}
return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3
return fd.L1.EditionFeatures.IsUTF8Validated
}
func (od *Oneof) IsSynthetic() bool {
@ -432,13 +442,13 @@ type (
Extendee protoreflect.MessageDescriptor
Cardinality protoreflect.Cardinality
Kind protoreflect.Kind
IsLazy bool
EditionFeatures EditionFeatures
}
ExtensionL2 struct {
Options func() protoreflect.ProtoMessage
StringName stringName
IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
IsPacked bool // promoted from google.protobuf.FieldOptions
Default defaultValue
Enum protoreflect.EnumDescriptor
Message protoreflect.MessageDescriptor
@ -461,9 +471,19 @@ func (xd *Extension) HasPresence() bool { return xd.L1.Cardi
func (xd *Extension) HasOptionalKeyword() bool {
return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
}
func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked }
func (xd *Extension) IsPacked() bool {
if xd.L1.Cardinality != protoreflect.Repeated {
return false
}
switch xd.L1.Kind {
case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
return false
}
return xd.L1.EditionFeatures.IsPacked
}
func (xd *Extension) IsExtension() bool { return true }
func (xd *Extension) IsWeak() bool { return false }
func (xd *Extension) IsLazy() bool { return xd.L1.IsLazy }
func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated }
func (xd *Extension) IsMap() bool { return false }
func (xd *Extension) MapKey() protoreflect.FieldDescriptor { return nil }
@ -542,8 +562,9 @@ func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
// Surrogate files are can be used to create standalone descriptors
// where the syntax is only information derived from the parent file.
var (
SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
SurrogateEdition2023 = &File{L1: FileL1{Syntax: protoreflect.Editions, Edition: Edition2023}, L2: &FileL2{}}
)
type (
@ -585,6 +606,34 @@ func (s *stringName) InitJSON(name string) {
s.nameJSON = name
}
// Returns true if this field is structured like the synthetic field of a proto2
// group. This allows us to expand our treatment of delimited fields without
// breaking proto2 files that have been upgraded to editions.
func isGroupLike(fd protoreflect.FieldDescriptor) bool {
// Groups are always group types.
if fd.Kind() != protoreflect.GroupKind {
return false
}
// Group fields are always the lowercase type name.
if strings.ToLower(string(fd.Message().Name())) != string(fd.Name()) {
return false
}
// Groups could only be defined in the same file they're used.
if fd.Message().ParentFile() != fd.ParentFile() {
return false
}
// Group messages are always defined in the same scope as the field. File
// level extensions will compare NULL == NULL here, which is why the file
// comparison above is necessary to ensure both come from the same file.
if fd.IsExtension() {
return fd.Parent() == fd.Message().Parent()
}
return fd.ContainingMessage() == fd.Message().Parent()
}
func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
s.once.Do(func() {
if fd.IsExtension() {
@ -605,7 +654,7 @@ func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
// Format the text name.
s.nameText = string(fd.Name())
if fd.Kind() == protoreflect.GroupKind {
if isGroupLike(fd) {
s.nameText = string(fd.Message().Name())
}
}

View file

@ -113,8 +113,10 @@ func (fd *File) unmarshalSeed(b []byte) {
switch string(v) {
case "proto2":
fd.L1.Syntax = protoreflect.Proto2
fd.L1.Edition = EditionProto2
case "proto3":
fd.L1.Syntax = protoreflect.Proto3
fd.L1.Edition = EditionProto3
case "editions":
fd.L1.Syntax = protoreflect.Editions
default:
@ -177,11 +179,10 @@ func (fd *File) unmarshalSeed(b []byte) {
// If syntax is missing, it is assumed to be proto2.
if fd.L1.Syntax == 0 {
fd.L1.Syntax = protoreflect.Proto2
fd.L1.Edition = EditionProto2
}
if fd.L1.Syntax == protoreflect.Editions {
fd.L1.EditionFeatures = getFeaturesFor(fd.L1.Edition)
}
fd.L1.EditionFeatures = getFeaturesFor(fd.L1.Edition)
// Parse editions features from options if any
if options != nil {
@ -267,6 +268,7 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protorefl
ed.L0.ParentFile = pf
ed.L0.Parent = pd
ed.L0.Index = i
ed.L1.EditionFeatures = featuresFromParentDesc(ed.Parent())
var numValues int
for b := b; len(b) > 0; {
@ -443,6 +445,7 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd prot
xd.L0.ParentFile = pf
xd.L0.Parent = pd
xd.L0.Index = i
xd.L1.EditionFeatures = featuresFromParentDesc(pd)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
@ -467,6 +470,40 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd prot
xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
case genid.FieldDescriptorProto_Extendee_field_number:
xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
case genid.FieldDescriptorProto_Options_field_number:
xd.unmarshalOptions(v)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
if xd.L1.Kind == protoreflect.MessageKind && xd.L1.EditionFeatures.IsDelimitedEncoded {
xd.L1.Kind = protoreflect.GroupKind
}
}
func (xd *Extension) unmarshalOptions(b []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case genid.FieldOptions_Packed_field_number:
xd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v)
case genid.FieldOptions_Lazy_field_number:
xd.L1.IsLazy = protowire.DecodeBool(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case genid.FieldOptions_Features_field_number:
xd.L1.EditionFeatures = unmarshalFeatureSet(v, xd.L1.EditionFeatures)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
@ -499,7 +536,7 @@ func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protor
}
var nameBuilderPool = sync.Pool{
New: func() interface{} { return new(strs.Builder) },
New: func() any { return new(strs.Builder) },
}
func getBuilder() *strs.Builder {

View file

@ -45,6 +45,11 @@ func (file *File) resolveMessages() {
case protoreflect.MessageKind, protoreflect.GroupKind:
fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
depIdx++
if fd.L1.Kind == protoreflect.GroupKind && (fd.IsMap() || fd.IsMapEntry()) {
// A map field might inherit delimited encoding from a file-wide default feature.
// But maps never actually use delimited encoding. (At least for now...)
fd.L1.Kind = protoreflect.MessageKind
}
}
// Default is resolved here since it depends on Enum being resolved.
@ -466,10 +471,10 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoref
b = b[m:]
}
}
if fd.Syntax() == protoreflect.Editions && fd.L1.Kind == protoreflect.MessageKind && fd.L1.EditionFeatures.IsDelimitedEncoded {
if fd.L1.Kind == protoreflect.MessageKind && fd.L1.EditionFeatures.IsDelimitedEncoded {
fd.L1.Kind = protoreflect.GroupKind
}
if fd.Syntax() == protoreflect.Editions && fd.L1.EditionFeatures.IsLegacyRequired {
if fd.L1.EditionFeatures.IsLegacyRequired {
fd.L1.Cardinality = protoreflect.Required
}
if rawTypeName != nil {
@ -496,13 +501,13 @@ func (fd *Field) unmarshalOptions(b []byte) {
b = b[m:]
switch num {
case genid.FieldOptions_Packed_field_number:
fd.L1.HasPacked = true
fd.L1.IsPacked = protowire.DecodeBool(v)
fd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v)
case genid.FieldOptions_Weak_field_number:
fd.L1.IsWeak = protowire.DecodeBool(v)
case genid.FieldOptions_Lazy_field_number:
fd.L1.IsLazy = protowire.DecodeBool(v)
case FieldOptions_EnforceUTF8:
fd.L1.HasEnforceUTF8 = true
fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
fd.L1.EditionFeatures.IsUTF8Validated = protowire.DecodeBool(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
@ -548,7 +553,6 @@ func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoref
func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
var rawTypeName []byte
var rawOptions []byte
xd.L1.EditionFeatures = featuresFromParentDesc(xd.L1.Extendee)
xd.L2 = new(ExtensionL2)
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
@ -572,7 +576,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
case genid.FieldDescriptorProto_TypeName_field_number:
rawTypeName = v
case genid.FieldDescriptorProto_Options_field_number:
xd.unmarshalOptions(v)
rawOptions = appendOptions(rawOptions, v)
}
default:
@ -580,12 +583,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
b = b[m:]
}
}
if xd.Syntax() == protoreflect.Editions && xd.L1.Kind == protoreflect.MessageKind && xd.L1.EditionFeatures.IsDelimitedEncoded {
xd.L1.Kind = protoreflect.GroupKind
}
if xd.Syntax() == protoreflect.Editions && xd.L1.EditionFeatures.IsLegacyRequired {
xd.L1.Cardinality = protoreflect.Required
}
if rawTypeName != nil {
name := makeFullName(sb, rawTypeName)
switch xd.L1.Kind {
@ -598,32 +595,6 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
}
func (xd *Extension) unmarshalOptions(b []byte) {
for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b)
b = b[n:]
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
switch num {
case genid.FieldOptions_Packed_field_number:
xd.L2.IsPacked = protowire.DecodeBool(v)
}
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case genid.FieldOptions_Features_field_number:
xd.L1.EditionFeatures = unmarshalFeatureSet(v, xd.L1.EditionFeatures)
}
default:
m := protowire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
}
}
func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
var rawMethods [][]byte
var rawOptions []byte

View file

@ -8,6 +8,7 @@ package filedesc
import (
"fmt"
"strings"
"sync"
"google.golang.org/protobuf/internal/descfmt"
@ -198,6 +199,16 @@ func (p *Fields) lazyInit() *Fields {
if _, ok := p.byText[d.TextName()]; !ok {
p.byText[d.TextName()] = d
}
if isGroupLike(d) {
lowerJSONName := strings.ToLower(d.JSONName())
if _, ok := p.byJSON[lowerJSONName]; !ok {
p.byJSON[lowerJSONName] = d
}
lowerTextName := strings.ToLower(d.TextName())
if _, ok := p.byText[lowerTextName]; !ok {
p.byText[lowerTextName] = d
}
}
if _, ok := p.byNum[d.Number()]; !ok {
p.byNum[d.Number()] = d
}

View file

@ -14,9 +14,13 @@ import (
)
var defaultsCache = make(map[Edition]EditionFeatures)
var defaultsKeys = []Edition{}
func init() {
unmarshalEditionDefaults(editiondefaults.Defaults)
SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2)
SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3)
SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023)
}
func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
@ -28,6 +32,10 @@ func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
v, m := protowire.ConsumeVarint(b)
b = b[m:]
parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
case genid.GoFeatures_StripEnumPrefix_field_number:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
parent.StripEnumPrefix = int(v)
default:
panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
}
@ -64,7 +72,7 @@ func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
case genid.FeatureSet_Go_ext_number:
parent = unmarshalGoFeature(v, parent)
}
}
@ -104,12 +112,15 @@ func unmarshalEditionDefault(b []byte) {
v, m := protowire.ConsumeBytes(b)
b = b[m:]
switch num {
case genid.FeatureSetDefaults_FeatureSetEditionDefault_Features_field_number:
case genid.FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_number:
fs = unmarshalFeatureSet(v, fs)
case genid.FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_number:
fs = unmarshalFeatureSet(v, fs)
}
}
}
defaultsCache[ed] = fs
defaultsKeys = append(defaultsKeys, ed)
}
func unmarshalEditionDefaults(b []byte) {
@ -135,8 +146,15 @@ func unmarshalEditionDefaults(b []byte) {
}
func getFeaturesFor(ed Edition) EditionFeatures {
if def, ok := defaultsCache[ed]; ok {
return def
match := EditionUnknown
for _, key := range defaultsKeys {
if key > ed {
break
}
match = key
}
panic(fmt.Sprintf("unsupported edition: %v", ed))
if match == EditionUnknown {
panic(fmt.Sprintf("unsupported edition: %v", ed))
}
return defaultsCache[match]
}

View file

@ -63,6 +63,7 @@ func (e PlaceholderEnum) Options() protoreflect.ProtoMessage { return des
func (e PlaceholderEnum) Values() protoreflect.EnumValueDescriptors { return emptyEnumValues }
func (e PlaceholderEnum) ReservedNames() protoreflect.Names { return emptyNames }
func (e PlaceholderEnum) ReservedRanges() protoreflect.EnumRanges { return emptyEnumRanges }
func (e PlaceholderEnum) IsClosed() bool { return false }
func (e PlaceholderEnum) ProtoType(protoreflect.EnumDescriptor) { return }
func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return }

View file

@ -68,7 +68,7 @@ type Builder struct {
// and for input and output messages referenced by service methods.
// Dependencies must come after declarations, but the ordering of
// dependencies themselves is unspecified.
GoTypes []interface{}
GoTypes []any
// DependencyIndexes is an ordered list of indexes into GoTypes for the
// dependencies of messages, extensions, or services.
@ -268,7 +268,7 @@ func (x depIdxs) Get(i, j int32) int32 {
type (
resolverByIndex struct {
goTypes []interface{}
goTypes []any
depIdxs depIdxs
fileRegistry
}

View file

@ -21,6 +21,7 @@ const (
// Enum values for google.protobuf.Edition.
const (
Edition_EDITION_UNKNOWN_enum_value = 0
Edition_EDITION_LEGACY_enum_value = 900
Edition_EDITION_PROTO2_enum_value = 998
Edition_EDITION_PROTO3_enum_value = 999
Edition_EDITION_2023_enum_value = 1000
@ -653,6 +654,7 @@ const (
FieldOptions_Targets_field_name protoreflect.Name = "targets"
FieldOptions_EditionDefaults_field_name protoreflect.Name = "edition_defaults"
FieldOptions_Features_field_name protoreflect.Name = "features"
FieldOptions_FeatureSupport_field_name protoreflect.Name = "feature_support"
FieldOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option"
FieldOptions_Ctype_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.ctype"
@ -667,6 +669,7 @@ const (
FieldOptions_Targets_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.targets"
FieldOptions_EditionDefaults_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.edition_defaults"
FieldOptions_Features_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.features"
FieldOptions_FeatureSupport_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.feature_support"
FieldOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.uninterpreted_option"
)
@ -684,6 +687,7 @@ const (
FieldOptions_Targets_field_number protoreflect.FieldNumber = 19
FieldOptions_EditionDefaults_field_number protoreflect.FieldNumber = 20
FieldOptions_Features_field_number protoreflect.FieldNumber = 21
FieldOptions_FeatureSupport_field_number protoreflect.FieldNumber = 22
FieldOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999
)
@ -767,6 +771,33 @@ const (
FieldOptions_EditionDefault_Value_field_number protoreflect.FieldNumber = 2
)
// Names for google.protobuf.FieldOptions.FeatureSupport.
const (
FieldOptions_FeatureSupport_message_name protoreflect.Name = "FeatureSupport"
FieldOptions_FeatureSupport_message_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport"
)
// Field names for google.protobuf.FieldOptions.FeatureSupport.
const (
FieldOptions_FeatureSupport_EditionIntroduced_field_name protoreflect.Name = "edition_introduced"
FieldOptions_FeatureSupport_EditionDeprecated_field_name protoreflect.Name = "edition_deprecated"
FieldOptions_FeatureSupport_DeprecationWarning_field_name protoreflect.Name = "deprecation_warning"
FieldOptions_FeatureSupport_EditionRemoved_field_name protoreflect.Name = "edition_removed"
FieldOptions_FeatureSupport_EditionIntroduced_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_introduced"
FieldOptions_FeatureSupport_EditionDeprecated_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_deprecated"
FieldOptions_FeatureSupport_DeprecationWarning_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.deprecation_warning"
FieldOptions_FeatureSupport_EditionRemoved_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_removed"
)
// Field numbers for google.protobuf.FieldOptions.FeatureSupport.
const (
FieldOptions_FeatureSupport_EditionIntroduced_field_number protoreflect.FieldNumber = 1
FieldOptions_FeatureSupport_EditionDeprecated_field_number protoreflect.FieldNumber = 2
FieldOptions_FeatureSupport_DeprecationWarning_field_number protoreflect.FieldNumber = 3
FieldOptions_FeatureSupport_EditionRemoved_field_number protoreflect.FieldNumber = 4
)
// Names for google.protobuf.OneofOptions.
const (
OneofOptions_message_name protoreflect.Name = "OneofOptions"
@ -829,11 +860,13 @@ const (
EnumValueOptions_Deprecated_field_name protoreflect.Name = "deprecated"
EnumValueOptions_Features_field_name protoreflect.Name = "features"
EnumValueOptions_DebugRedact_field_name protoreflect.Name = "debug_redact"
EnumValueOptions_FeatureSupport_field_name protoreflect.Name = "feature_support"
EnumValueOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option"
EnumValueOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.deprecated"
EnumValueOptions_Features_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.features"
EnumValueOptions_DebugRedact_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.debug_redact"
EnumValueOptions_FeatureSupport_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.feature_support"
EnumValueOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.uninterpreted_option"
)
@ -842,6 +875,7 @@ const (
EnumValueOptions_Deprecated_field_number protoreflect.FieldNumber = 1
EnumValueOptions_Features_field_number protoreflect.FieldNumber = 2
EnumValueOptions_DebugRedact_field_number protoreflect.FieldNumber = 3
EnumValueOptions_FeatureSupport_field_number protoreflect.FieldNumber = 4
EnumValueOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999
)
@ -1110,17 +1144,20 @@ const (
// Field names for google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.
const (
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_name protoreflect.Name = "edition"
FeatureSetDefaults_FeatureSetEditionDefault_Features_field_name protoreflect.Name = "features"
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_name protoreflect.Name = "edition"
FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_name protoreflect.Name = "overridable_features"
FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_name protoreflect.Name = "fixed_features"
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_fullname protoreflect.FullName = "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition"
FeatureSetDefaults_FeatureSetEditionDefault_Features_field_fullname protoreflect.FullName = "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.features"
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_fullname protoreflect.FullName = "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition"
FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_fullname protoreflect.FullName = "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features"
FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_fullname protoreflect.FullName = "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features"
)
// Field numbers for google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.
const (
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number protoreflect.FieldNumber = 3
FeatureSetDefaults_FeatureSetEditionDefault_Features_field_number protoreflect.FieldNumber = 2
FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number protoreflect.FieldNumber = 3
FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_number protoreflect.FieldNumber = 4
FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_number protoreflect.FieldNumber = 5
)
// Names for google.protobuf.SourceCodeInfo.

View file

@ -6,6 +6,6 @@
// and the well-known types.
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
const GoogleProtobuf_package protoreflect.FullName = "google.protobuf"

View file

@ -10,22 +10,44 @@ import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
)
const File_reflect_protodesc_proto_go_features_proto = "reflect/protodesc/proto/go_features.proto"
const File_google_protobuf_go_features_proto = "google/protobuf/go_features.proto"
// Names for google.protobuf.GoFeatures.
// Names for pb.GoFeatures.
const (
GoFeatures_message_name protoreflect.Name = "GoFeatures"
GoFeatures_message_fullname protoreflect.FullName = "google.protobuf.GoFeatures"
GoFeatures_message_fullname protoreflect.FullName = "pb.GoFeatures"
)
// Field names for google.protobuf.GoFeatures.
// Field names for pb.GoFeatures.
const (
GoFeatures_LegacyUnmarshalJsonEnum_field_name protoreflect.Name = "legacy_unmarshal_json_enum"
GoFeatures_StripEnumPrefix_field_name protoreflect.Name = "strip_enum_prefix"
GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "google.protobuf.GoFeatures.legacy_unmarshal_json_enum"
GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "pb.GoFeatures.legacy_unmarshal_json_enum"
GoFeatures_StripEnumPrefix_field_fullname protoreflect.FullName = "pb.GoFeatures.strip_enum_prefix"
)
// Field numbers for google.protobuf.GoFeatures.
// Field numbers for pb.GoFeatures.
const (
GoFeatures_LegacyUnmarshalJsonEnum_field_number protoreflect.FieldNumber = 1
GoFeatures_StripEnumPrefix_field_number protoreflect.FieldNumber = 3
)
// Full and short names for pb.GoFeatures.StripEnumPrefix.
const (
GoFeatures_StripEnumPrefix_enum_fullname = "pb.GoFeatures.StripEnumPrefix"
GoFeatures_StripEnumPrefix_enum_name = "StripEnumPrefix"
)
// Enum values for pb.GoFeatures.StripEnumPrefix.
const (
GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED_enum_value = 0
GoFeatures_STRIP_ENUM_PREFIX_KEEP_enum_value = 1
GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH_enum_value = 2
GoFeatures_STRIP_ENUM_PREFIX_STRIP_enum_value = 3
)
// Extension numbers
const (
FeatureSet_Go_ext_number protoreflect.FieldNumber = 1002
)

View file

@ -4,7 +4,7 @@
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
// Generic field names and numbers for synthetic map entry messages.
const (

View file

@ -4,7 +4,7 @@
package genid
import protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import "google.golang.org/protobuf/reflect/protoreflect"
// Generic field name and number for messages in wrappers.proto.
const (

View file

@ -22,13 +22,13 @@ type Export struct{}
// NewError formats a string according to the format specifier and arguments and
// returns an error that has a "proto" prefix.
func (Export) NewError(f string, x ...interface{}) error {
func (Export) NewError(f string, x ...any) error {
return errors.New(f, x...)
}
// enum is any enum type generated by protoc-gen-go
// and must be a named int32 type.
type enum = interface{}
type enum = any
// EnumOf returns the protoreflect.Enum interface over e.
// It returns nil if e is nil.
@ -81,7 +81,7 @@ func (Export) EnumStringOf(ed protoreflect.EnumDescriptor, n protoreflect.EnumNu
// message is any message type generated by protoc-gen-go
// and must be a pointer to a named struct type.
type message = interface{}
type message = any
// legacyMessageWrapper wraps a v2 message as a v1 message.
type legacyMessageWrapper struct{ m protoreflect.ProtoMessage }

View file

@ -68,7 +68,7 @@ func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
}
for _, x := range *ext {
ei := getExtensionFieldInfo(x.Type())
if ei.funcs.isInit == nil {
if ei.funcs.isInit == nil || x.isUnexpandedLazy() {
continue
}
v := x.Value()

View file

@ -67,7 +67,6 @@ type lazyExtensionValue struct {
xi *extensionFieldInfo
value protoreflect.Value
b []byte
fn func() protoreflect.Value
}
type ExtensionField struct {
@ -99,6 +98,28 @@ func (f *ExtensionField) canLazy(xt protoreflect.ExtensionType) bool {
return false
}
// isUnexpandedLazy returns true if the ExensionField is lazy and not
// yet expanded, which means it's present and already checked for
// initialized required fields.
func (f *ExtensionField) isUnexpandedLazy() bool {
return f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0
}
// lazyBuffer retrieves the buffer for a lazy extension if it's not yet expanded.
//
// The returned buffer has to be kept over whatever operation we're planning,
// as re-retrieving it will fail after the message is lazily decoded.
func (f *ExtensionField) lazyBuffer() []byte {
// This function might be in the critical path, so check the atomic without
// taking a look first, then only take the lock if needed.
if !f.isUnexpandedLazy() {
return nil
}
f.lazy.mu.Lock()
defer f.lazy.mu.Unlock()
return f.lazy.b
}
func (f *ExtensionField) lazyInit() {
f.lazy.mu.Lock()
defer f.lazy.mu.Unlock()
@ -136,10 +157,9 @@ func (f *ExtensionField) lazyInit() {
}
f.lazy.value = val
} else {
f.lazy.value = f.lazy.fn()
panic("No support for lazy fns for ExtensionField")
}
f.lazy.xi = nil
f.lazy.fn = nil
f.lazy.b = nil
atomic.StoreUint32(&f.lazy.atomicOnce, 1)
}
@ -152,13 +172,6 @@ func (f *ExtensionField) Set(t protoreflect.ExtensionType, v protoreflect.Value)
f.lazy = nil
}
// SetLazy sets the type and a value that is to be lazily evaluated upon first use.
// This must not be called concurrently.
func (f *ExtensionField) SetLazy(t protoreflect.ExtensionType, fn func() protoreflect.Value) {
f.typ = t
f.lazy = &lazyExtensionValue{fn: fn}
}
// Value returns the value of the extension field.
// This may be called concurrently.
func (f *ExtensionField) Value() protoreflect.Value {

View file

@ -65,6 +65,9 @@ func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si
if err != nil {
return out, err
}
if cf.funcs.isInit == nil {
out.initialized = true
}
vi.Set(vw)
return out, nil
}
@ -233,9 +236,15 @@ func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
}
func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
calculatedSize := f.mi.sizePointer(p.Elem(), opts)
b = protowire.AppendVarint(b, f.wiretag)
b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
return f.mi.marshalAppendPointer(b, p.Elem(), opts)
b = protowire.AppendVarint(b, uint64(calculatedSize))
before := len(b)
b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
}
return b, err
}
func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
@ -262,14 +271,21 @@ func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
return f.mi.checkInitializedPointer(p.Elem())
}
func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
return protowire.SizeBytes(proto.Size(m)) + tagsize
func sizeMessage(m proto.Message, tagsize int, opts marshalOptions) int {
return protowire.SizeBytes(opts.Options().Size(m)) + tagsize
}
func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
mopts := opts.Options()
calculatedSize := mopts.Size(m)
b = protowire.AppendVarint(b, wiretag)
b = protowire.AppendVarint(b, uint64(proto.Size(m)))
return opts.Options().MarshalAppend(b, m)
b = protowire.AppendVarint(b, uint64(calculatedSize))
before := len(b)
b, err := mopts.MarshalAppend(b, m)
if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
}
return b, err
}
func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
@ -405,8 +421,8 @@ func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInf
return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
}
func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
return 2*tagsize + proto.Size(m)
func sizeGroup(m proto.Message, tagsize int, opts marshalOptions) int {
return 2*tagsize + opts.Options().Size(m)
}
func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
@ -482,10 +498,14 @@ func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshal
b = protowire.AppendVarint(b, f.wiretag)
siz := f.mi.sizePointer(v, opts)
b = protowire.AppendVarint(b, uint64(siz))
before := len(b)
b, err = f.mi.marshalAppendPointer(b, v, opts)
if err != nil {
return b, err
}
if measuredSize := len(b) - before; siz != measuredSize {
return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
}
}
return b, nil
}
@ -520,28 +540,34 @@ func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
return nil
}
func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, opts marshalOptions) int {
mopts := opts.Options()
s := p.PointerSlice()
n := 0
for _, v := range s {
m := asMessage(v.AsValueOf(goType.Elem()))
n += protowire.SizeBytes(proto.Size(m)) + tagsize
n += protowire.SizeBytes(mopts.Size(m)) + tagsize
}
return n
}
func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
mopts := opts.Options()
s := p.PointerSlice()
var err error
for _, v := range s {
m := asMessage(v.AsValueOf(goType.Elem()))
b = protowire.AppendVarint(b, wiretag)
siz := proto.Size(m)
siz := mopts.Size(m)
b = protowire.AppendVarint(b, uint64(siz))
b, err = opts.Options().MarshalAppend(b, m)
before := len(b)
b, err = mopts.MarshalAppend(b, m)
if err != nil {
return b, err
}
if measuredSize := len(b) - before; siz != measuredSize {
return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
}
}
return b, nil
}
@ -582,11 +608,12 @@ func isInitMessageSlice(p pointer, goType reflect.Type) error {
// Slices of messages
func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
mopts := opts.Options()
list := listv.List()
n := 0
for i, llen := 0, list.Len(); i < llen; i++ {
m := list.Get(i).Message().Interface()
n += protowire.SizeBytes(proto.Size(m)) + tagsize
n += protowire.SizeBytes(mopts.Size(m)) + tagsize
}
return n
}
@ -597,13 +624,17 @@ func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64,
for i, llen := 0, list.Len(); i < llen; i++ {
m := list.Get(i).Message().Interface()
b = protowire.AppendVarint(b, wiretag)
siz := proto.Size(m)
siz := mopts.Size(m)
b = protowire.AppendVarint(b, uint64(siz))
before := len(b)
var err error
b, err = mopts.MarshalAppend(b, m)
if err != nil {
return b, err
}
if measuredSize := len(b) - before; siz != measuredSize {
return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
}
}
return b, nil
}
@ -651,11 +682,12 @@ var coderMessageSliceValue = valueCoderFuncs{
}
func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
mopts := opts.Options()
list := listv.List()
n := 0
for i, llen := 0, list.Len(); i < llen; i++ {
m := list.Get(i).Message().Interface()
n += 2*tagsize + proto.Size(m)
n += 2*tagsize + mopts.Size(m)
}
return n
}
@ -738,12 +770,13 @@ func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type)
}
}
func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, opts marshalOptions) int {
mopts := opts.Options()
s := p.PointerSlice()
n := 0
for _, v := range s {
m := asMessage(v.AsValueOf(messageType.Elem()))
n += 2*tagsize + proto.Size(m)
n += 2*tagsize + mopts.Size(m)
}
return n
}

View file

@ -9,6 +9,7 @@ import (
"sort"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/reflect/protoreflect"
)
@ -240,11 +241,16 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coder
size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
size += mapi.valFuncs.size(val, mapValTagSize, opts)
b = protowire.AppendVarint(b, uint64(size))
before := len(b)
b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
if err != nil {
return nil, err
}
return mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts)
b, err = mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts)
if measuredSize := len(b) - before; size != measuredSize && err == nil {
return nil, errors.MismatchedSizeCalculation(size, measuredSize)
}
return b, err
} else {
key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
val := pointerOfValue(valrv)
@ -259,7 +265,12 @@ func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coder
}
b = protowire.AppendVarint(b, mapi.valWiretag)
b = protowire.AppendVarint(b, uint64(valSize))
return f.mi.marshalAppendPointer(b, val, opts)
before := len(b)
b, err = f.mi.marshalAppendPointer(b, val, opts)
if measuredSize := len(b) - before; valSize != measuredSize && err == nil {
return nil, errors.MismatchedSizeCalculation(valSize, measuredSize)
}
return b, err
}
}

View file

@ -189,6 +189,9 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
if mi.methods.Merge == nil {
mi.methods.Merge = mi.merge
}
if mi.methods.Equal == nil {
mi.methods.Equal = equal
}
}
// getUnknownBytes returns a *[]byte for the unknown fields.

View file

@ -26,6 +26,15 @@ func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int)
}
num, _ := protowire.DecodeTag(xi.wiretag)
size += messageset.SizeField(num)
if fullyLazyExtensions(opts) {
// Don't expand the extension, instead use the buffer to calculate size
if lb := x.lazyBuffer(); lb != nil {
// We got hold of the buffer, so it's still lazy.
// Don't count the tag size in the extension buffer, it's already added.
size += protowire.SizeTag(messageset.FieldMessage) + len(lb) - xi.tagsize
continue
}
}
size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts)
}
@ -85,6 +94,19 @@ func marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts ma
xi := getExtensionFieldInfo(x.Type())
num, _ := protowire.DecodeTag(xi.wiretag)
b = messageset.AppendFieldStart(b, num)
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
// The tag inside the lazy buffer is a different tag (the extension
// number), but what we need here is the tag for FieldMessage:
b = protowire.AppendVarint(b, protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType))
b = append(b, lb[xi.tagsize:]...)
b = messageset.AppendFieldEnd(b)
return b, nil
}
}
b, err := xi.funcs.marshal(b, x.Value(), protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType), opts)
if err != nil {
return b, err

View file

@ -1,210 +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.
//go:build purego || appengine
// +build purego appengine
package impl
import (
"reflect"
"google.golang.org/protobuf/encoding/protowire"
)
func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
v := p.v.Elem().Int()
return f.tagsize + protowire.SizeVarint(uint64(v))
}
func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
v := p.v.Elem().Int()
b = protowire.AppendVarint(b, f.wiretag)
b = protowire.AppendVarint(b, uint64(v))
return b, nil
}
func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.VarintType {
return out, errUnknown
}
v, n := protowire.ConsumeVarint(b)
if n < 0 {
return out, errDecode
}
p.v.Elem().SetInt(int64(v))
out.n = n
return out, nil
}
func mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
dst.v.Elem().Set(src.v.Elem())
}
var coderEnum = pointerCoderFuncs{
size: sizeEnum,
marshal: appendEnum,
unmarshal: consumeEnum,
merge: mergeEnum,
}
func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
if p.v.Elem().Int() == 0 {
return 0
}
return sizeEnum(p, f, opts)
}
func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
if p.v.Elem().Int() == 0 {
return b, nil
}
return appendEnum(b, p, f, opts)
}
func mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
if src.v.Elem().Int() != 0 {
dst.v.Elem().Set(src.v.Elem())
}
}
var coderEnumNoZero = pointerCoderFuncs{
size: sizeEnumNoZero,
marshal: appendEnumNoZero,
unmarshal: consumeEnum,
merge: mergeEnumNoZero,
}
func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
return sizeEnum(pointer{p.v.Elem()}, f, opts)
}
func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
return appendEnum(b, pointer{p.v.Elem()}, f, opts)
}
func consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.VarintType {
return out, errUnknown
}
if p.v.Elem().IsNil() {
p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
}
return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
}
func mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
if !src.v.Elem().IsNil() {
v := reflect.New(dst.v.Type().Elem().Elem())
v.Elem().Set(src.v.Elem().Elem())
dst.v.Elem().Set(v)
}
}
var coderEnumPtr = pointerCoderFuncs{
size: sizeEnumPtr,
marshal: appendEnumPtr,
unmarshal: consumeEnumPtr,
merge: mergeEnumPtr,
}
func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
s := p.v.Elem()
for i, llen := 0, s.Len(); i < llen; i++ {
size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
}
return size
}
func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
s := p.v.Elem()
for i, llen := 0, s.Len(); i < llen; i++ {
b = protowire.AppendVarint(b, f.wiretag)
b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
}
return b, nil
}
func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
s := p.v.Elem()
if wtyp == protowire.BytesType {
b, n := protowire.ConsumeBytes(b)
if n < 0 {
return out, errDecode
}
for len(b) > 0 {
v, n := protowire.ConsumeVarint(b)
if n < 0 {
return out, errDecode
}
rv := reflect.New(s.Type().Elem()).Elem()
rv.SetInt(int64(v))
s.Set(reflect.Append(s, rv))
b = b[n:]
}
out.n = n
return out, nil
}
if wtyp != protowire.VarintType {
return out, errUnknown
}
v, n := protowire.ConsumeVarint(b)
if n < 0 {
return out, errDecode
}
rv := reflect.New(s.Type().Elem()).Elem()
rv.SetInt(int64(v))
s.Set(reflect.Append(s, rv))
out.n = n
return out, nil
}
func mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
}
var coderEnumSlice = pointerCoderFuncs{
size: sizeEnumSlice,
marshal: appendEnumSlice,
unmarshal: consumeEnumSlice,
merge: mergeEnumSlice,
}
func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
s := p.v.Elem()
llen := s.Len()
if llen == 0 {
return 0
}
n := 0
for i := 0; i < llen; i++ {
n += protowire.SizeVarint(uint64(s.Index(i).Int()))
}
return f.tagsize + protowire.SizeBytes(n)
}
func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
s := p.v.Elem()
llen := s.Len()
if llen == 0 {
return b, nil
}
b = protowire.AppendVarint(b, f.wiretag)
n := 0
for i := 0; i < llen; i++ {
n += protowire.SizeVarint(uint64(s.Index(i).Int()))
}
b = protowire.AppendVarint(b, uint64(n))
for i := 0; i < llen; i++ {
b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
}
return b, nil
}
var coderEnumPackedSlice = pointerCoderFuncs{
size: sizeEnumPackedSlice,
marshal: appendEnumPackedSlice,
unmarshal: consumeEnumSlice,
merge: mergeEnumSlice,
}

View file

@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine
package impl
// When using unsafe pointers, we can just treat enum values as int32s.

View file

@ -14,7 +14,7 @@ import (
// unwrapper unwraps the value to the underlying value.
// This is implemented by List and Map.
type unwrapper interface {
protoUnwrap() interface{}
protoUnwrap() any
}
// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
@ -322,7 +322,7 @@ func (c *stringConverter) PBValueOf(v reflect.Value) protoreflect.Value {
return protoreflect.ValueOfString(v.Convert(stringType).String())
}
func (c *stringConverter) GoValueOf(v protoreflect.Value) reflect.Value {
// pref.Value.String never panics, so we go through an interface
// protoreflect.Value.String never panics, so we go through an interface
// conversion here to check the type.
s := v.Interface().(string)
if c.goType.Kind() == reflect.Slice && s == "" {

View file

@ -136,6 +136,6 @@ func (ls *listReflect) NewElement() protoreflect.Value {
func (ls *listReflect) IsValid() bool {
return !ls.v.IsNil()
}
func (ls *listReflect) protoUnwrap() interface{} {
func (ls *listReflect) protoUnwrap() any {
return ls.v.Interface()
}

View file

@ -116,6 +116,6 @@ func (ms *mapReflect) NewValue() protoreflect.Value {
func (ms *mapReflect) IsValid() bool {
return !ms.v.IsNil()
}
func (ms *mapReflect) protoUnwrap() interface{} {
func (ms *mapReflect) protoUnwrap() any {
return ms.v.Interface()
}

View file

@ -10,7 +10,7 @@ import (
"sync/atomic"
"google.golang.org/protobuf/internal/flags"
proto "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/proto"
piface "google.golang.org/protobuf/runtime/protoiface"
)
@ -49,8 +49,11 @@ func (mi *MessageInfo) sizePointer(p pointer, opts marshalOptions) (size int) {
return 0
}
if opts.UseCachedSize() && mi.sizecacheOffset.IsValid() {
if size := atomic.LoadInt32(p.Apply(mi.sizecacheOffset).Int32()); size >= 0 {
return int(size)
// The size cache contains the size + 1, to allow the
// zero value to be invalid, while also allowing for a
// 0 size to be cached.
if size := atomic.LoadInt32(p.Apply(mi.sizecacheOffset).Int32()); size > 0 {
return int(size - 1)
}
}
return mi.sizePointerSlow(p, opts)
@ -60,7 +63,7 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int
if flags.ProtoLegacy && mi.isMessageSet {
size = sizeMessageSet(mi, p, opts)
if mi.sizecacheOffset.IsValid() {
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size+1))
}
return size
}
@ -84,13 +87,16 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int
}
}
if mi.sizecacheOffset.IsValid() {
if size > math.MaxInt32 {
if size > (math.MaxInt32 - 1) {
// The size is too large for the int32 sizecache field.
// We will need to recompute the size when encoding;
// unfortunately expensive, but better than invalid output.
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), -1)
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), 0)
} else {
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
// The size cache contains the size + 1, to allow the
// zero value to be invalid, while also allowing for a
// 0 size to be cached.
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size+1))
}
}
return size
@ -149,6 +155,14 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
return b, nil
}
// fullyLazyExtensions returns true if we should attempt to keep extensions lazy over size and marshal.
func fullyLazyExtensions(opts marshalOptions) bool {
// When deterministic marshaling is requested, force an unmarshal for lazy
// extensions to produce a deterministic result, instead of passing through
// bytes lazily that may or may not match what Go Protobuf would produce.
return opts.flags&piface.MarshalDeterministic == 0
}
func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
if ext == nil {
return 0
@ -158,6 +172,14 @@ func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marsha
if xi.funcs.size == nil {
continue
}
if fullyLazyExtensions(opts) {
// Don't expand the extension, instead use the buffer to calculate size
if lb := x.lazyBuffer(); lb != nil {
// We got hold of the buffer, so it's still lazy.
n += len(lb)
continue
}
}
n += xi.funcs.size(x.Value(), xi.tagsize, opts)
}
return n
@ -176,6 +198,13 @@ func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField,
var err error
for _, x := range *ext {
xi := getExtensionFieldInfo(x.Type())
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
b = append(b, lb...)
continue
}
}
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
}
return b, err
@ -191,6 +220,13 @@ func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField,
for _, k := range keys {
x := (*ext)[int32(k)]
xi := getExtensionFieldInfo(x.Type())
if fullyLazyExtensions(opts) {
// Don't expand the extension if it's still in wire format, instead use the buffer content.
if lb := x.lazyBuffer(); lb != nil {
b = append(b, lb...)
continue
}
}
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
if err != nil {
return b, err

View file

@ -0,0 +1,224 @@
// Copyright 2024 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 impl
import (
"bytes"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface"
)
func equal(in protoiface.EqualInput) protoiface.EqualOutput {
return protoiface.EqualOutput{Equal: equalMessage(in.MessageA, in.MessageB)}
}
// equalMessage is a fast-path variant of protoreflect.equalMessage.
// It takes advantage of the internal messageState type to avoid
// unnecessary allocations, type assertions.
func equalMessage(mx, my protoreflect.Message) bool {
if mx == nil || my == nil {
return mx == my
}
if mx.Descriptor() != my.Descriptor() {
return false
}
msx, ok := mx.(*messageState)
if !ok {
return protoreflect.ValueOfMessage(mx).Equal(protoreflect.ValueOfMessage(my))
}
msy, ok := my.(*messageState)
if !ok {
return protoreflect.ValueOfMessage(mx).Equal(protoreflect.ValueOfMessage(my))
}
mi := msx.messageInfo()
miy := msy.messageInfo()
if mi != miy {
return protoreflect.ValueOfMessage(mx).Equal(protoreflect.ValueOfMessage(my))
}
mi.init()
// Compares regular fields
// Modified Message.Range code that compares two messages of the same type
// while going over the fields.
for _, ri := range mi.rangeInfos {
var fd protoreflect.FieldDescriptor
var vx, vy protoreflect.Value
switch ri := ri.(type) {
case *fieldInfo:
hx := ri.has(msx.pointer())
hy := ri.has(msy.pointer())
if hx != hy {
return false
}
if !hx {
continue
}
fd = ri.fieldDesc
vx = ri.get(msx.pointer())
vy = ri.get(msy.pointer())
case *oneofInfo:
fnx := ri.which(msx.pointer())
fny := ri.which(msy.pointer())
if fnx != fny {
return false
}
if fnx <= 0 {
continue
}
fi := mi.fields[fnx]
fd = fi.fieldDesc
vx = fi.get(msx.pointer())
vy = fi.get(msy.pointer())
}
if !equalValue(fd, vx, vy) {
return false
}
}
// Compare extensions.
// This is more complicated because mx or my could have empty/nil extension maps,
// however some populated extension map values are equal to nil extension maps.
emx := mi.extensionMap(msx.pointer())
emy := mi.extensionMap(msy.pointer())
if emx != nil {
for k, x := range *emx {
xd := x.Type().TypeDescriptor()
xv := x.Value()
var y ExtensionField
ok := false
if emy != nil {
y, ok = (*emy)[k]
}
// We need to treat empty lists as equal to nil values
if emy == nil || !ok {
if xd.IsList() && xv.List().Len() == 0 {
continue
}
return false
}
if !equalValue(xd, xv, y.Value()) {
return false
}
}
}
if emy != nil {
// emy may have extensions emx does not have, need to check them as well
for k, y := range *emy {
if emx != nil {
// emx has the field, so we already checked it
if _, ok := (*emx)[k]; ok {
continue
}
}
// Empty lists are equal to nil
if y.Type().TypeDescriptor().IsList() && y.Value().List().Len() == 0 {
continue
}
// Cant be equal if the extension is populated
return false
}
}
return equalUnknown(mx.GetUnknown(), my.GetUnknown())
}
func equalValue(fd protoreflect.FieldDescriptor, vx, vy protoreflect.Value) bool {
// slow path
if fd.Kind() != protoreflect.MessageKind {
return vx.Equal(vy)
}
// fast path special cases
if fd.IsMap() {
if fd.MapValue().Kind() == protoreflect.MessageKind {
return equalMessageMap(vx.Map(), vy.Map())
}
return vx.Equal(vy)
}
if fd.IsList() {
return equalMessageList(vx.List(), vy.List())
}
return equalMessage(vx.Message(), vy.Message())
}
// Mostly copied from protoreflect.equalMap.
// This variant only works for messages as map types.
// All other map types should be handled via Value.Equal.
func equalMessageMap(mx, my protoreflect.Map) bool {
if mx.Len() != my.Len() {
return false
}
equal := true
mx.Range(func(k protoreflect.MapKey, vx protoreflect.Value) bool {
if !my.Has(k) {
equal = false
return false
}
vy := my.Get(k)
equal = equalMessage(vx.Message(), vy.Message())
return equal
})
return equal
}
// Mostly copied from protoreflect.equalList.
// The only change is the usage of equalImpl instead of protoreflect.equalValue.
func equalMessageList(lx, ly protoreflect.List) bool {
if lx.Len() != ly.Len() {
return false
}
for i := 0; i < lx.Len(); i++ {
// We only operate on messages here since equalImpl will not call us in any other case.
if !equalMessage(lx.Get(i).Message(), ly.Get(i).Message()) {
return false
}
}
return true
}
// equalUnknown compares unknown fields by direct comparison on the raw bytes
// of each individual field number.
// Copied from protoreflect.equalUnknown.
func equalUnknown(x, y protoreflect.RawFields) bool {
if len(x) != len(y) {
return false
}
if bytes.Equal([]byte(x), []byte(y)) {
return true
}
mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
my := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
for len(x) > 0 {
fnum, _, n := protowire.ConsumeField(x)
mx[fnum] = append(mx[fnum], x[:n]...)
x = x[n:]
}
for len(y) > 0 {
fnum, _, n := protowire.ConsumeField(y)
my[fnum] = append(my[fnum], y[:n]...)
y = y[n:]
}
if len(mx) != len(my) {
return false
}
for k, v1 := range mx {
if v2, ok := my[k]; !ok || !bytes.Equal([]byte(v1), []byte(v2)) {
return false
}
}
return true
}

View file

@ -53,7 +53,7 @@ type ExtensionInfo struct {
// type returned by InterfaceOf may not be identical.
//
// Deprecated: Use InterfaceOf(xt.Zero()) instead.
ExtensionType interface{}
ExtensionType any
// Field is the field number of the extension.
//
@ -95,16 +95,16 @@ func (xi *ExtensionInfo) New() protoreflect.Value {
func (xi *ExtensionInfo) Zero() protoreflect.Value {
return xi.lazyInit().Zero()
}
func (xi *ExtensionInfo) ValueOf(v interface{}) protoreflect.Value {
func (xi *ExtensionInfo) ValueOf(v any) protoreflect.Value {
return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
}
func (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) interface{} {
func (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) any {
return xi.lazyInit().GoValueOf(v).Interface()
}
func (xi *ExtensionInfo) IsValidValue(v protoreflect.Value) bool {
return xi.lazyInit().IsValidPB(v)
}
func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
func (xi *ExtensionInfo) IsValidInterface(v any) bool {
return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
}
func (xi *ExtensionInfo) TypeDescriptor() protoreflect.ExtensionTypeDescriptor {

View file

@ -97,7 +97,7 @@ func (e *legacyEnumWrapper) Number() protoreflect.EnumNumber {
func (e *legacyEnumWrapper) ProtoReflect() protoreflect.Enum {
return e
}
func (e *legacyEnumWrapper) protoUnwrap() interface{} {
func (e *legacyEnumWrapper) protoUnwrap() any {
v := reflect.New(e.goTyp).Elem()
v.SetInt(int64(e.num))
return v.Interface()
@ -167,6 +167,7 @@ func aberrantLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor {
ed := &filedesc.Enum{L2: new(filedesc.EnumL2)}
ed.L0.FullName = AberrantDeriveFullName(t) // e.g., github_com.user.repo.MyEnum
ed.L0.ParentFile = filedesc.SurrogateProto3
ed.L1.EditionFeatures = ed.L0.ParentFile.L1.EditionFeatures
ed.L2.Values.List = append(ed.L2.Values.List, filedesc.EnumValue{})
// TODO: Use the presence of a UnmarshalJSON method to determine proto2?

View file

@ -118,7 +118,7 @@ func (xi *ExtensionInfo) initFromLegacy() {
xd.L1.Number = protoreflect.FieldNumber(xi.Field)
xd.L1.Cardinality = fd.L1.Cardinality
xd.L1.Kind = fd.L1.Kind
xd.L2.IsPacked = fd.L1.IsPacked
xd.L1.EditionFeatures = fd.L1.EditionFeatures
xd.L2.Default = fd.L1.Default
xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType)
xd.L2.Enum = ed
@ -160,6 +160,7 @@ func (x placeholderExtension) HasPresence() bool
func (x placeholderExtension) HasOptionalKeyword() bool { return false }
func (x placeholderExtension) IsExtension() bool { return true }
func (x placeholderExtension) IsWeak() bool { return false }
func (x placeholderExtension) IsLazy() bool { return false }
func (x placeholderExtension) IsPacked() bool { return false }
func (x placeholderExtension) IsList() bool { return false }
func (x placeholderExtension) IsMap() bool { return false }

View file

@ -7,7 +7,7 @@ package impl
import (
"bytes"
"compress/gzip"
"io/ioutil"
"io"
"sync"
"google.golang.org/protobuf/internal/filedesc"
@ -51,7 +51,7 @@ func legacyLoadFileDesc(b []byte) protoreflect.FileDescriptor {
if err != nil {
panic(err)
}
b2, err := ioutil.ReadAll(zr)
b2, err := io.ReadAll(zr)
if err != nil {
panic(err)
}

View file

@ -204,6 +204,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName
}
}
md.L1.EditionFeatures = md.L0.ParentFile.L1.EditionFeatures
// Obtain a list of oneof wrapper types.
var oneofWrappers []reflect.Type
methods := make([]reflect.Method, 0, 2)
@ -215,7 +216,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName
}
for _, fn := range methods {
for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
if vs, ok := v.Interface().([]interface{}); ok {
if vs, ok := v.Interface().([]any); ok {
for _, v := range vs {
oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
}
@ -250,6 +251,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName
od := &md.L2.Oneofs.List[n]
od.L0.FullName = md.FullName().Append(protoreflect.Name(tag))
od.L0.ParentFile = md.L0.ParentFile
od.L1.EditionFeatures = md.L1.EditionFeatures
od.L0.Parent = md
od.L0.Index = n
@ -260,6 +262,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName
aberrantAppendField(md, f.Type, tag, "", "")
fd := &md.L2.Fields.List[len(md.L2.Fields.List)-1]
fd.L1.ContainingOneof = od
fd.L1.EditionFeatures = od.L1.EditionFeatures
od.L1.Fields.List = append(od.L1.Fields.List, fd)
}
}
@ -307,14 +310,14 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
fd.L0.Parent = md
fd.L0.Index = n
if fd.L1.IsWeak || fd.L1.HasPacked {
if fd.L1.IsWeak || fd.L1.EditionFeatures.IsPacked {
fd.L1.Options = func() protoreflect.ProtoMessage {
opts := descopts.Field.ProtoReflect().New()
if fd.L1.IsWeak {
opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
}
if fd.L1.HasPacked {
opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked))
if fd.L1.EditionFeatures.IsPacked {
opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.EditionFeatures.IsPacked))
}
return opts.Interface()
}
@ -344,6 +347,7 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
md2.L0.ParentFile = md.L0.ParentFile
md2.L0.Parent = md
md2.L0.Index = n
md2.L1.EditionFeatures = md.L1.EditionFeatures
md2.L1.IsMapEntry = true
md2.L2.Options = func() protoreflect.ProtoMessage {
@ -563,6 +567,6 @@ func (m aberrantMessage) IsValid() bool {
func (m aberrantMessage) ProtoMethods() *protoiface.Methods {
return aberrantProtoMethods
}
func (m aberrantMessage) protoUnwrap() interface{} {
func (m aberrantMessage) protoUnwrap() any {
return m.v.Interface()
}

View file

@ -30,12 +30,12 @@ type MessageInfo struct {
// Desc is the underlying message descriptor type and must be populated.
Desc protoreflect.MessageDescriptor
// Exporter must be provided in a purego environment in order to provide
// access to unexported fields.
// Deprecated: Exporter will be removed the next time we bump
// protoimpl.GenVersion. See https://github.com/golang/protobuf/issues/1640
Exporter exporter
// OneofWrappers is list of pointers to oneof wrapper struct types.
OneofWrappers []interface{}
OneofWrappers []any
initMu sync.Mutex // protects all unexported fields
initDone uint32
@ -47,7 +47,7 @@ type MessageInfo struct {
// exporter is a function that returns a reference to the ith field of v,
// where v is a pointer to a struct. It returns nil if it does not support
// exporting the requested field (e.g., already exported).
type exporter func(v interface{}, i int) interface{}
type exporter func(v any, i int) any
// getMessageInfo returns the MessageInfo for any message type that
// is generated by our implementation of protoc-gen-go (for v2 and on).
@ -201,7 +201,7 @@ fieldLoop:
}
for _, fn := range methods {
for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
if vs, ok := v.Interface().([]interface{}); ok {
if vs, ok := v.Interface().([]any); ok {
oneofWrappers = vs
}
}
@ -256,7 +256,7 @@ func (mi *MessageInfo) Message(i int) protoreflect.MessageType {
type mapEntryType struct {
desc protoreflect.MessageDescriptor
valType interface{} // zero value of enum or message type
valType any // zero value of enum or message type
}
func (mt mapEntryType) New() protoreflect.Message {

View file

@ -20,7 +20,7 @@ type reflectMessageInfo struct {
// fieldTypes contains the zero value of an enum or message field.
// For lists, it contains the element type.
// For maps, it contains the entry value type.
fieldTypes map[protoreflect.FieldNumber]interface{}
fieldTypes map[protoreflect.FieldNumber]any
// denseFields is a subset of fields where:
// 0 < fieldDesc.Number() < len(denseFields)
@ -28,7 +28,7 @@ type reflectMessageInfo struct {
denseFields []*fieldInfo
// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
rangeInfos []interface{} // either *fieldInfo or *oneofInfo
rangeInfos []any // either *fieldInfo or *oneofInfo
getUnknown func(pointer) protoreflect.RawFields
setUnknown func(pointer, protoreflect.RawFields)
@ -224,7 +224,7 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) {
}
if ft != nil {
if mi.fieldTypes == nil {
mi.fieldTypes = make(map[protoreflect.FieldNumber]interface{})
mi.fieldTypes = make(map[protoreflect.FieldNumber]any)
}
mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface()
}
@ -247,39 +247,39 @@ func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.V
}
}
}
func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
func (m *extensionMap) Has(xd protoreflect.ExtensionTypeDescriptor) (ok bool) {
if m == nil {
return false
}
xd := xt.TypeDescriptor()
x, ok := (*m)[int32(xd.Number())]
if !ok {
return false
}
if x.isUnexpandedLazy() {
// Avoid calling x.Value(), which triggers a lazy unmarshal.
return true
}
switch {
case xd.IsList():
return x.Value().List().Len() > 0
case xd.IsMap():
return x.Value().Map().Len() > 0
case xd.Message() != nil:
return x.Value().Message().IsValid()
}
return true
}
func (m *extensionMap) Clear(xt protoreflect.ExtensionType) {
delete(*m, int32(xt.TypeDescriptor().Number()))
func (m *extensionMap) Clear(xd protoreflect.ExtensionTypeDescriptor) {
delete(*m, int32(xd.Number()))
}
func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value {
xd := xt.TypeDescriptor()
func (m *extensionMap) Get(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
if m != nil {
if x, ok := (*m)[int32(xd.Number())]; ok {
return x.Value()
}
}
return xt.Zero()
return xd.Type().Zero()
}
func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) {
xd := xt.TypeDescriptor()
func (m *extensionMap) Set(xd protoreflect.ExtensionTypeDescriptor, v protoreflect.Value) {
xt := xd.Type()
isValid := true
switch {
case !xt.IsValidValue(v):
@ -292,7 +292,7 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value)
isValid = v.Message().IsValid()
}
if !isValid {
panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
panic(fmt.Sprintf("%v: assigning invalid value", xd.FullName()))
}
if *m == nil {
@ -302,16 +302,15 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value)
x.Set(xt, v)
(*m)[int32(xd.Number())] = x
}
func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value {
xd := xt.TypeDescriptor()
func (m *extensionMap) Mutable(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() {
panic("invalid Mutable on field with non-composite type")
}
if x, ok := (*m)[int32(xd.Number())]; ok {
return x.Value()
}
v := xt.New()
m.Set(xt, v)
v := xd.Type().New()
m.Set(xd, v)
return v
}
@ -394,7 +393,7 @@ var (
// MessageOf returns a reflective view over a message. The input must be a
// pointer to a named Go struct. If the provided type has a ProtoReflect method,
// it must be implemented by calling this method.
func (mi *MessageInfo) MessageOf(m interface{}) protoreflect.Message {
func (mi *MessageInfo) MessageOf(m any) protoreflect.Message {
if reflect.TypeOf(m) != mi.GoReflectType {
panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
}
@ -422,13 +421,13 @@ func (m *messageIfaceWrapper) Reset() {
func (m *messageIfaceWrapper) ProtoReflect() protoreflect.Message {
return (*messageReflectWrapper)(m)
}
func (m *messageIfaceWrapper) protoUnwrap() interface{} {
func (m *messageIfaceWrapper) protoUnwrap() any {
return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
}
// checkField verifies that the provided field descriptor is valid.
// Exactly one of the returned values is populated.
func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) {
func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionTypeDescriptor) {
var fi *fieldInfo
if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
fi = mi.denseFields[n]
@ -457,7 +456,7 @@ func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo,
if !ok {
panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
}
return nil, xtd.Type()
return nil, xtd
}
panic(fmt.Sprintf("field %v is invalid", fd.FullName()))
}

View file

@ -23,12 +23,13 @@ func (m *messageState) New() protoreflect.Message {
func (m *messageState) Interface() protoreflect.ProtoMessage {
return m.protoUnwrap().(protoreflect.ProtoMessage)
}
func (m *messageState) protoUnwrap() interface{} {
func (m *messageState) protoUnwrap() any {
return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
}
func (m *messageState) ProtoMethods() *protoiface.Methods {
m.messageInfo().init()
return &m.messageInfo().methods
mi := m.messageInfo()
mi.init()
return &mi.methods
}
// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
@ -41,8 +42,9 @@ func (m *messageState) ProtoMessageInfo() *MessageInfo {
}
func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
m.messageInfo().init()
for _, ri := range m.messageInfo().rangeInfos {
mi := m.messageInfo()
mi.init()
for _, ri := range mi.rangeInfos {
switch ri := ri.(type) {
case *fieldInfo:
if ri.has(m.pointer()) {
@ -52,77 +54,86 @@ func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.V
}
case *oneofInfo:
if n := ri.which(m.pointer()); n > 0 {
fi := m.messageInfo().fields[n]
fi := mi.fields[n]
if !f(fi.fieldDesc, fi.get(m.pointer())) {
return
}
}
}
}
m.messageInfo().extensionMap(m.pointer()).Range(f)
mi.extensionMap(m.pointer()).Range(f)
}
func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.has(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Has(xt)
return mi.extensionMap(m.pointer()).Has(xd)
}
}
func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
fi.clear(m.pointer())
} else {
m.messageInfo().extensionMap(m.pointer()).Clear(xt)
mi.extensionMap(m.pointer()).Clear(xd)
}
}
func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.get(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Get(xt)
return mi.extensionMap(m.pointer()).Get(xd)
}
}
func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
fi.set(m.pointer(), v)
} else {
m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
mi.extensionMap(m.pointer()).Set(xd, v)
}
}
func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.mutable(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
return mi.extensionMap(m.pointer()).Mutable(xd)
}
}
func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.newField()
} else {
return xt.New()
return xd.Type().New()
}
}
func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
m.messageInfo().init()
if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
mi := m.messageInfo()
mi.init()
if oi := mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
return od.Fields().ByNumber(oi.which(m.pointer()))
}
panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
}
func (m *messageState) GetUnknown() protoreflect.RawFields {
m.messageInfo().init()
return m.messageInfo().getUnknown(m.pointer())
mi := m.messageInfo()
mi.init()
return mi.getUnknown(m.pointer())
}
func (m *messageState) SetUnknown(b protoreflect.RawFields) {
m.messageInfo().init()
m.messageInfo().setUnknown(m.pointer(), b)
mi := m.messageInfo()
mi.init()
mi.setUnknown(m.pointer(), b)
}
func (m *messageState) IsValid() bool {
return !m.pointer().IsNil()
@ -143,12 +154,13 @@ func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
}
return (*messageIfaceWrapper)(m)
}
func (m *messageReflectWrapper) protoUnwrap() interface{} {
func (m *messageReflectWrapper) protoUnwrap() any {
return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
}
func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods {
m.messageInfo().init()
return &m.messageInfo().methods
mi := m.messageInfo()
mi.init()
return &mi.methods
}
// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
@ -161,8 +173,9 @@ func (m *messageReflectWrapper) ProtoMessageInfo() *MessageInfo {
}
func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
m.messageInfo().init()
for _, ri := range m.messageInfo().rangeInfos {
mi := m.messageInfo()
mi.init()
for _, ri := range mi.rangeInfos {
switch ri := ri.(type) {
case *fieldInfo:
if ri.has(m.pointer()) {
@ -172,77 +185,86 @@ func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, proto
}
case *oneofInfo:
if n := ri.which(m.pointer()); n > 0 {
fi := m.messageInfo().fields[n]
fi := mi.fields[n]
if !f(fi.fieldDesc, fi.get(m.pointer())) {
return
}
}
}
}
m.messageInfo().extensionMap(m.pointer()).Range(f)
mi.extensionMap(m.pointer()).Range(f)
}
func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.has(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Has(xt)
return mi.extensionMap(m.pointer()).Has(xd)
}
}
func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
fi.clear(m.pointer())
} else {
m.messageInfo().extensionMap(m.pointer()).Clear(xt)
mi.extensionMap(m.pointer()).Clear(xd)
}
}
func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.get(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Get(xt)
return mi.extensionMap(m.pointer()).Get(xd)
}
}
func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
fi.set(m.pointer(), v)
} else {
m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
mi.extensionMap(m.pointer()).Set(xd, v)
}
}
func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.mutable(m.pointer())
} else {
return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
return mi.extensionMap(m.pointer()).Mutable(xd)
}
}
func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
m.messageInfo().init()
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
mi := m.messageInfo()
mi.init()
if fi, xd := mi.checkField(fd); fi != nil {
return fi.newField()
} else {
return xt.New()
return xd.Type().New()
}
}
func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
m.messageInfo().init()
if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
mi := m.messageInfo()
mi.init()
if oi := mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
return od.Fields().ByNumber(oi.which(m.pointer()))
}
panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
}
func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
m.messageInfo().init()
return m.messageInfo().getUnknown(m.pointer())
mi := m.messageInfo()
mi.init()
return mi.getUnknown(m.pointer())
}
func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) {
m.messageInfo().init()
m.messageInfo().setUnknown(m.pointer(), b)
mi := m.messageInfo()
mi.init()
mi.setUnknown(m.pointer(), b)
}
func (m *messageReflectWrapper) IsValid() bool {
return !m.pointer().IsNil()

View file

@ -1,215 +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.
//go:build purego || appengine
// +build purego appengine
package impl
import (
"fmt"
"reflect"
"sync"
)
const UnsafeEnabled = false
// Pointer is an opaque pointer type.
type Pointer interface{}
// offset represents the offset to a struct field, accessible from a pointer.
// The offset is the field index into a struct.
type offset struct {
index int
export exporter
}
// offsetOf returns a field offset for the struct field.
func offsetOf(f reflect.StructField, x exporter) offset {
if len(f.Index) != 1 {
panic("embedded structs are not supported")
}
if f.PkgPath == "" {
return offset{index: f.Index[0]} // field is already exported
}
if x == nil {
panic("exporter must be provided for unexported field")
}
return offset{index: f.Index[0], export: x}
}
// IsValid reports whether the offset is valid.
func (f offset) IsValid() bool { return f.index >= 0 }
// invalidOffset is an invalid field offset.
var invalidOffset = offset{index: -1}
// zeroOffset is a noop when calling pointer.Apply.
var zeroOffset = offset{index: 0}
// pointer is an abstract representation of a pointer to a struct or field.
type pointer struct{ v reflect.Value }
// pointerOf returns p as a pointer.
func pointerOf(p Pointer) pointer {
return pointerOfIface(p)
}
// pointerOfValue returns v as a pointer.
func pointerOfValue(v reflect.Value) pointer {
return pointer{v: v}
}
// pointerOfIface returns the pointer portion of an interface.
func pointerOfIface(v interface{}) pointer {
return pointer{v: reflect.ValueOf(v)}
}
// IsNil reports whether the pointer is nil.
func (p pointer) IsNil() bool {
return p.v.IsNil()
}
// Apply adds an offset to the pointer to derive a new pointer
// to a specified field. The current pointer must be pointing at a struct.
func (p pointer) Apply(f offset) pointer {
if f.export != nil {
if v := reflect.ValueOf(f.export(p.v.Interface(), f.index)); v.IsValid() {
return pointer{v: v}
}
}
return pointer{v: p.v.Elem().Field(f.index).Addr()}
}
// AsValueOf treats p as a pointer to an object of type t and returns the value.
// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
if got := p.v.Type().Elem(); got != t {
panic(fmt.Sprintf("invalid type: got %v, want %v", got, t))
}
return p.v
}
// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
// It is equivalent to p.AsValueOf(t).Interface()
func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
return p.AsValueOf(t).Interface()
}
func (p pointer) Bool() *bool { return p.v.Interface().(*bool) }
func (p pointer) BoolPtr() **bool { return p.v.Interface().(**bool) }
func (p pointer) BoolSlice() *[]bool { return p.v.Interface().(*[]bool) }
func (p pointer) Int32() *int32 { return p.v.Interface().(*int32) }
func (p pointer) Int32Ptr() **int32 { return p.v.Interface().(**int32) }
func (p pointer) Int32Slice() *[]int32 { return p.v.Interface().(*[]int32) }
func (p pointer) Int64() *int64 { return p.v.Interface().(*int64) }
func (p pointer) Int64Ptr() **int64 { return p.v.Interface().(**int64) }
func (p pointer) Int64Slice() *[]int64 { return p.v.Interface().(*[]int64) }
func (p pointer) Uint32() *uint32 { return p.v.Interface().(*uint32) }
func (p pointer) Uint32Ptr() **uint32 { return p.v.Interface().(**uint32) }
func (p pointer) Uint32Slice() *[]uint32 { return p.v.Interface().(*[]uint32) }
func (p pointer) Uint64() *uint64 { return p.v.Interface().(*uint64) }
func (p pointer) Uint64Ptr() **uint64 { return p.v.Interface().(**uint64) }
func (p pointer) Uint64Slice() *[]uint64 { return p.v.Interface().(*[]uint64) }
func (p pointer) Float32() *float32 { return p.v.Interface().(*float32) }
func (p pointer) Float32Ptr() **float32 { return p.v.Interface().(**float32) }
func (p pointer) Float32Slice() *[]float32 { return p.v.Interface().(*[]float32) }
func (p pointer) Float64() *float64 { return p.v.Interface().(*float64) }
func (p pointer) Float64Ptr() **float64 { return p.v.Interface().(**float64) }
func (p pointer) Float64Slice() *[]float64 { return p.v.Interface().(*[]float64) }
func (p pointer) String() *string { return p.v.Interface().(*string) }
func (p pointer) StringPtr() **string { return p.v.Interface().(**string) }
func (p pointer) StringSlice() *[]string { return p.v.Interface().(*[]string) }
func (p pointer) Bytes() *[]byte { return p.v.Interface().(*[]byte) }
func (p pointer) BytesPtr() **[]byte { return p.v.Interface().(**[]byte) }
func (p pointer) BytesSlice() *[][]byte { return p.v.Interface().(*[][]byte) }
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.v.Interface().(*WeakFields)) }
func (p pointer) Extensions() *map[int32]ExtensionField {
return p.v.Interface().(*map[int32]ExtensionField)
}
func (p pointer) Elem() pointer {
return pointer{v: p.v.Elem()}
}
// PointerSlice copies []*T from p as a new []pointer.
// This behavior differs from the implementation in pointer_unsafe.go.
func (p pointer) PointerSlice() []pointer {
// TODO: reconsider this
if p.v.IsNil() {
return nil
}
n := p.v.Elem().Len()
s := make([]pointer, n)
for i := 0; i < n; i++ {
s[i] = pointer{v: p.v.Elem().Index(i)}
}
return s
}
// AppendPointerSlice appends v to p, which must be a []*T.
func (p pointer) AppendPointerSlice(v pointer) {
sp := p.v.Elem()
sp.Set(reflect.Append(sp, v.v))
}
// SetPointer sets *p to v.
func (p pointer) SetPointer(v pointer) {
p.v.Elem().Set(v.v)
}
func growSlice(p pointer, addCap int) {
// TODO: Once we only support Go 1.20 and newer, use reflect.Grow.
in := p.v.Elem()
out := reflect.MakeSlice(in.Type(), in.Len(), in.Len()+addCap)
reflect.Copy(out, in)
p.v.Elem().Set(out)
}
func (p pointer) growBoolSlice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growInt32Slice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growUint32Slice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growInt64Slice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growUint64Slice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growFloat64Slice(addCap int) {
growSlice(p, addCap)
}
func (p pointer) growFloat32Slice(addCap int) {
growSlice(p, addCap)
}
func (Export) MessageStateOf(p Pointer) *messageState { panic("not supported") }
func (ms *messageState) pointer() pointer { panic("not supported") }
func (ms *messageState) messageInfo() *MessageInfo { panic("not supported") }
func (ms *messageState) LoadMessageInfo() *MessageInfo { panic("not supported") }
func (ms *messageState) StoreMessageInfo(mi *MessageInfo) { panic("not supported") }
type atomicNilMessage struct {
once sync.Once
m messageReflectWrapper
}
func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
m.once.Do(func() {
m.m.p = pointerOfIface(reflect.Zero(mi.GoReflectType).Interface())
m.m.mi = mi
})
return &m.m
}

View file

@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine
package impl
import (
@ -50,7 +47,7 @@ func pointerOfValue(v reflect.Value) pointer {
}
// pointerOfIface returns the pointer portion of an interface.
func pointerOfIface(v interface{}) pointer {
func pointerOfIface(v any) pointer {
type ifaceHeader struct {
Type unsafe.Pointer
Data unsafe.Pointer
@ -80,7 +77,7 @@ func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
// It is equivalent to p.AsValueOf(t).Interface()
func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
func (p pointer) AsIfaceOf(t reflect.Type) any {
// TODO: Use tricky unsafe magic to directly create ifaceHeader.
return p.AsValueOf(t).Interface()
}

View file

@ -86,7 +86,7 @@ func appendMessage(b []byte, m protoreflect.Message) []byte {
return b
}
var protocmpMessageType = reflect.TypeOf(map[string]interface{}(nil))
var protocmpMessageType = reflect.TypeOf(map[string]any(nil))
func appendKnownMessage(b []byte, m protoreflect.Message) []byte {
md := m.Descriptor()
@ -98,7 +98,7 @@ func appendKnownMessage(b []byte, m protoreflect.Message) []byte {
if v := reflect.ValueOf(m); v.Type().ConvertibleTo(protocmpMessageType) {
// For protocmp.Message, directly obtain the sub-message value
// which is stored in structured form, rather than as raw bytes.
m2 := v.Convert(protocmpMessageType).Interface().(map[string]interface{})
m2 := v.Convert(protocmpMessageType).Interface().(map[string]any)
v, ok := m2[string(genid.Any_Value_field_name)].(proto.Message)
if !ok {
return nil

View file

@ -18,7 +18,7 @@ type messageField struct {
}
var messageFieldPool = sync.Pool{
New: func() interface{} { return new([]messageField) },
New: func() any { return new([]messageField) },
}
type (
@ -69,7 +69,7 @@ type mapEntry struct {
}
var mapEntryPool = sync.Pool{
New: func() interface{} { return new([]mapEntry) },
New: func() any { return new([]mapEntry) },
}
type (

View file

@ -1,28 +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.
//go:build purego || appengine
// +build purego appengine
package strs
import pref "google.golang.org/protobuf/reflect/protoreflect"
func UnsafeString(b []byte) string {
return string(b)
}
func UnsafeBytes(s string) []byte {
return []byte(s)
}
type Builder struct{}
func (*Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName {
return prefix.Append(name)
}
func (*Builder) MakeString(b []byte) string {
return string(b)
}

View file

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && !go1.21
// +build !purego,!appengine,!go1.21
//go:build !go1.21
package strs

View file

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && go1.21
// +build !purego,!appengine,go1.21
//go:build go1.21
package strs

View file

@ -51,8 +51,8 @@ import (
// 10. Send out the CL for review and submit it.
const (
Major = 1
Minor = 33
Patch = 0
Minor = 35
Patch = 2
PreRelease = ""
)

View file

@ -51,6 +51,8 @@ type UnmarshalOptions struct {
// Unmarshal parses the wire-format message in b and places the result in m.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
//
// See the [UnmarshalOptions] type if you need more control.
func Unmarshal(b []byte, m Message) error {
_, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect())
return err

View file

@ -5,12 +5,17 @@
package proto
import (
"errors"
"fmt"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface"
protoerrors "google.golang.org/protobuf/internal/errors"
)
// MarshalOptions configures the marshaler.
@ -70,7 +75,32 @@ type MarshalOptions struct {
UseCachedSize bool
}
// flags turns the specified MarshalOptions (user-facing) into
// protoiface.MarshalInputFlags (used internally by the marshaler).
//
// See impl.marshalOptions.Options for the inverse operation.
func (o MarshalOptions) flags() protoiface.MarshalInputFlags {
var flags protoiface.MarshalInputFlags
// Note: o.AllowPartial is always forced to true by MarshalOptions.marshal,
// which is why it is not a part of MarshalInputFlags.
if o.Deterministic {
flags |= protoiface.MarshalDeterministic
}
if o.UseCachedSize {
flags |= protoiface.MarshalUseCachedSize
}
return flags
}
// Marshal returns the wire-format encoding of m.
//
// This is the most common entry point for encoding a Protobuf message.
//
// See the [MarshalOptions] type if you need more control.
func Marshal(m Message) ([]byte, error) {
// Treat nil message interface as an empty message; nothing to output.
if m == nil {
@ -116,6 +146,9 @@ func emptyBytesForMessage(m Message) []byte {
// MarshalAppend appends the wire-format encoding of m to b,
// returning the result.
//
// This is a less common entry point than [Marshal], which is only needed if you
// need to supply your own buffers for performance reasons.
func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
// Treat nil message interface as an empty message; nothing to append.
if m == nil {
@ -145,12 +178,7 @@ func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoifac
in := protoiface.MarshalInput{
Message: m,
Buf: b,
}
if o.Deterministic {
in.Flags |= protoiface.MarshalDeterministic
}
if o.UseCachedSize {
in.Flags |= protoiface.MarshalUseCachedSize
Flags: o.flags(),
}
if methods.Size != nil {
sout := methods.Size(protoiface.SizeInput{
@ -168,6 +196,10 @@ func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoifac
out.Buf, err = o.marshalMessageSlow(b, m)
}
if err != nil {
var mismatch *protoerrors.SizeMismatchError
if errors.As(err, &mismatch) {
return out, fmt.Errorf("marshaling %s: %v", string(m.Descriptor().FullName()), err)
}
return out, err
}
if allowPartial {

View file

@ -8,6 +8,7 @@ import (
"reflect"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface"
)
// Equal reports whether two messages are equal,
@ -51,6 +52,14 @@ func Equal(x, y Message) bool {
if mx.IsValid() != my.IsValid() {
return false
}
// Only one of the messages needs to implement the fast-path for it to work.
pmx := protoMethods(mx)
pmy := protoMethods(my)
if pmx != nil && pmy != nil && pmx.Equal != nil && pmy.Equal != nil {
return pmx.Equal(protoiface.EqualInput{MessageA: mx, MessageB: my}).Equal
}
vx := protoreflect.ValueOfMessage(mx)
vy := protoreflect.ValueOfMessage(my)
return vx.Equal(vy)

View file

@ -11,18 +11,21 @@ import (
// HasExtension reports whether an extension field is populated.
// It returns false if m is invalid or if xt does not extend m.
func HasExtension(m Message, xt protoreflect.ExtensionType) bool {
// Treat nil message interface as an empty message; no populated fields.
if m == nil {
// Treat nil message interface or descriptor as an empty message; no populated
// fields.
if m == nil || xt == nil {
return false
}
// As a special-case, we reports invalid or mismatching descriptors
// as always not being populated (since they aren't).
if xt == nil || m.ProtoReflect().Descriptor() != xt.TypeDescriptor().ContainingMessage() {
mr := m.ProtoReflect()
xd := xt.TypeDescriptor()
if mr.Descriptor() != xd.ContainingMessage() {
return false
}
return m.ProtoReflect().Has(xt.TypeDescriptor())
return mr.Has(xd)
}
// ClearExtension clears an extension field such that subsequent
@ -36,7 +39,49 @@ func ClearExtension(m Message, xt protoreflect.ExtensionType) {
// If the field is unpopulated, it returns the default value for
// scalars and an immutable, empty value for lists or messages.
// It panics if xt does not extend m.
func GetExtension(m Message, xt protoreflect.ExtensionType) interface{} {
//
// The type of the value is dependent on the field type of the extension.
// For extensions generated by protoc-gen-go, the Go type is as follows:
//
// ╔═══════════════════╤═════════════════════════╗
// ║ Go type │ Protobuf kind ║
// ╠═══════════════════╪═════════════════════════╣
// ║ bool │ bool ║
// ║ int32 │ int32, sint32, sfixed32 ║
// ║ int64 │ int64, sint64, sfixed64 ║
// ║ uint32 │ uint32, fixed32 ║
// ║ uint64 │ uint64, fixed64 ║
// ║ float32 │ float ║
// ║ float64 │ double ║
// ║ string │ string ║
// ║ []byte │ bytes ║
// ║ protoreflect.Enum │ enum ║
// ║ proto.Message │ message, group ║
// ╚═══════════════════╧═════════════════════════╝
//
// The protoreflect.Enum and proto.Message types are the concrete Go type
// associated with the named enum or message. Repeated fields are represented
// using a Go slice of the base element type.
//
// If a generated extension descriptor variable is directly passed to
// GetExtension, then the call should be followed immediately by a
// type assertion to the expected output value. For example:
//
// mm := proto.GetExtension(m, foopb.E_MyExtension).(*foopb.MyMessage)
//
// This pattern enables static analysis tools to verify that the asserted type
// matches the Go type associated with the extension field and
// also enables a possible future migration to a type-safe extension API.
//
// Since singular messages are the most common extension type, the pattern of
// calling HasExtension followed by GetExtension may be simplified to:
//
// if mm := proto.GetExtension(m, foopb.E_MyExtension).(*foopb.MyMessage); mm != nil {
// ... // make use of mm
// }
//
// The mm variable is non-nil if and only if HasExtension reports true.
func GetExtension(m Message, xt protoreflect.ExtensionType) any {
// Treat nil message interface as an empty message; return the default.
if m == nil {
return xt.InterfaceOf(xt.Zero())
@ -48,7 +93,36 @@ func GetExtension(m Message, xt protoreflect.ExtensionType) interface{} {
// SetExtension stores the value of an extension field.
// It panics if m is invalid, xt does not extend m, or if type of v
// is invalid for the specified extension field.
func SetExtension(m Message, xt protoreflect.ExtensionType, v interface{}) {
//
// The type of the value is dependent on the field type of the extension.
// For extensions generated by protoc-gen-go, the Go type is as follows:
//
// ╔═══════════════════╤═════════════════════════╗
// ║ Go type │ Protobuf kind ║
// ╠═══════════════════╪═════════════════════════╣
// ║ bool │ bool ║
// ║ int32 │ int32, sint32, sfixed32 ║
// ║ int64 │ int64, sint64, sfixed64 ║
// ║ uint32 │ uint32, fixed32 ║
// ║ uint64 │ uint64, fixed64 ║
// ║ float32 │ float ║
// ║ float64 │ double ║
// ║ string │ string ║
// ║ []byte │ bytes ║
// ║ protoreflect.Enum │ enum ║
// ║ proto.Message │ message, group ║
// ╚═══════════════════╧═════════════════════════╝
//
// The protoreflect.Enum and proto.Message types are the concrete Go type
// associated with the named enum or message. Repeated fields are represented
// using a Go slice of the base element type.
//
// If a generated extension descriptor variable is directly passed to
// SetExtension (e.g., foopb.E_MyExtension), then the value should be a
// concrete type that matches the expected Go type for the extension descriptor
// so that static analysis tools can verify type correctness.
// This also enables a possible future migration to a type-safe extension API.
func SetExtension(m Message, xt protoreflect.ExtensionType, v any) {
xd := xt.TypeDescriptor()
pv := xt.ValueOf(v)
@ -75,7 +149,7 @@ func SetExtension(m Message, xt protoreflect.ExtensionType, v interface{}) {
// It returns immediately if f returns false.
// While iterating, mutating operations may only be performed
// on the current extension field.
func RangeExtensions(m Message, f func(protoreflect.ExtensionType, interface{}) bool) {
func RangeExtensions(m Message, f func(protoreflect.ExtensionType, any) bool) {
// Treat nil message interface as an empty message; nothing to range over.
if m == nil {
return

View file

@ -47,11 +47,16 @@ func (o MarshalOptions) marshalMessageSet(b []byte, m protoreflect.Message) ([]b
func (o MarshalOptions) marshalMessageSetField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) {
b = messageset.AppendFieldStart(b, fd.Number())
b = protowire.AppendTag(b, messageset.FieldMessage, protowire.BytesType)
b = protowire.AppendVarint(b, uint64(o.Size(value.Message().Interface())))
calculatedSize := o.Size(value.Message().Interface())
b = protowire.AppendVarint(b, uint64(calculatedSize))
before := len(b)
b, err := o.marshalMessage(b, value.Message())
if err != nil {
return b, err
}
if measuredSize := len(b) - before; calculatedSize != measuredSize {
return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
}
b = messageset.AppendFieldEnd(b)
return b, nil
}

View file

@ -34,6 +34,7 @@ func (o MarshalOptions) size(m protoreflect.Message) (size int) {
if methods != nil && methods.Size != nil {
out := methods.Size(protoiface.SizeInput{
Message: m,
Flags: o.flags(),
})
return out.Size
}
@ -42,6 +43,7 @@ func (o MarshalOptions) size(m protoreflect.Message) (size int) {
// This case is mainly used for legacy types with a Marshal method.
out, _ := methods.Marshal(protoiface.MarshalInput{
Message: m,
Flags: o.flags(),
})
return len(out.Buf)
}

View file

@ -13,6 +13,9 @@
package protodesc
import (
"strings"
"google.golang.org/protobuf/internal/editionssupport"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/pragma"
@ -91,21 +94,27 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot
switch fd.GetSyntax() {
case "proto2", "":
f.L1.Syntax = protoreflect.Proto2
f.L1.Edition = filedesc.EditionProto2
case "proto3":
f.L1.Syntax = protoreflect.Proto3
f.L1.Edition = filedesc.EditionProto3
case "editions":
f.L1.Syntax = protoreflect.Editions
f.L1.Edition = fromEditionProto(fd.GetEdition())
default:
return nil, errors.New("invalid syntax: %q", fd.GetSyntax())
}
if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < SupportedEditionsMinimum || fd.GetEdition() > SupportedEditionsMaximum) {
return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition())
}
f.L1.Path = fd.GetName()
if f.L1.Path == "" {
return nil, errors.New("file path must be populated")
}
if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < editionssupport.Minimum || fd.GetEdition() > editionssupport.Maximum) {
// Allow cmd/protoc-gen-go/testdata to use any edition for easier
// testing of upcoming edition features.
if !strings.HasPrefix(fd.GetName(), "cmd/protoc-gen-go/testdata/") {
return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition())
}
}
f.L1.Package = protoreflect.FullName(fd.GetPackage())
if !f.L1.Package.IsValid() && f.L1.Package != "" {
return nil, errors.New("invalid package: %q", f.L1.Package)
@ -114,9 +123,7 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot
opts = proto.Clone(opts).(*descriptorpb.FileOptions)
f.L2.Options = func() protoreflect.ProtoMessage { return opts }
}
if f.L1.Syntax == protoreflect.Editions {
initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures())
}
initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures())
f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency()))
for _, i := range fd.GetPublicDependency() {
@ -219,10 +226,10 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot
if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil {
return nil, err
}
if err := validateMessageDeclarations(f.L1.Messages.List, fd.GetMessageType()); err != nil {
if err := validateMessageDeclarations(f, f.L1.Messages.List, fd.GetMessageType()); err != nil {
return nil, err
}
if err := validateExtensionDeclarations(f.L1.Extensions.List, fd.GetExtension()); err != nil {
if err := validateExtensionDeclarations(f, f.L1.Extensions.List, fd.GetExtension()); err != nil {
return nil, err
}

View file

@ -69,9 +69,7 @@ func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProt
if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
return nil, err
}
if m.Base.L0.ParentFile.Syntax() == protoreflect.Editions {
m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures())
}
m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures())
if opts := md.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.MessageOptions)
m.L2.Options = func() protoreflect.ProtoMessage { return opts }
@ -146,13 +144,16 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc
if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil {
return nil, err
}
f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures())
f.L1.IsProto3Optional = fd.GetProto3Optional()
if opts := fd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
f.L1.Options = func() protoreflect.ProtoMessage { return opts }
f.L1.IsWeak = opts.GetWeak()
f.L1.HasPacked = opts.Packed != nil
f.L1.IsPacked = opts.GetPacked()
f.L1.IsLazy = opts.GetLazy()
if opts.Packed != nil {
f.L1.EditionFeatures.IsPacked = opts.GetPacked()
}
}
f.L1.Number = protoreflect.FieldNumber(fd.GetNumber())
f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel())
@ -163,32 +164,12 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc
f.L1.StringName.InitJSON(fd.GetJsonName())
}
if f.Base.L0.ParentFile.Syntax() == protoreflect.Editions {
f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures())
if f.L1.EditionFeatures.IsLegacyRequired {
f.L1.Cardinality = protoreflect.Required
}
if f.L1.EditionFeatures.IsLegacyRequired {
f.L1.Cardinality = protoreflect.Required
}
// We reuse the existing field because the old option `[packed =
// true]` is mutually exclusive with the editions feature.
if canBePacked(fd) {
f.L1.HasPacked = true
f.L1.IsPacked = f.L1.EditionFeatures.IsPacked
}
// We pretend this option is always explicitly set because the only
// use of HasEnforceUTF8 is to determine whether to use EnforceUTF8
// or to return the appropriate default.
// When using editions we either parse the option or resolve the
// appropriate default here (instead of later when this option is
// requested from the descriptor).
// In proto2/proto3 syntax HasEnforceUTF8 might be false.
f.L1.HasEnforceUTF8 = true
f.L1.EnforceUTF8 = f.L1.EditionFeatures.IsUTF8Validated
if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded {
f.L1.Kind = protoreflect.GroupKind
}
if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded {
f.L1.Kind = protoreflect.GroupKind
}
}
return fs, nil
@ -201,12 +182,10 @@ func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDesc
if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil {
return nil, err
}
o.L1.EditionFeatures = mergeEditionFeatures(parent, od.GetOptions().GetFeatures())
if opts := od.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.OneofOptions)
o.L1.Options = func() protoreflect.ProtoMessage { return opts }
if parent.Syntax() == protoreflect.Editions {
o.L1.EditionFeatures = mergeEditionFeatures(parent, opts.GetFeatures())
}
}
}
return os, nil
@ -220,10 +199,13 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript
if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil {
return nil, err
}
x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures())
if opts := xd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
x.L2.Options = func() protoreflect.ProtoMessage { return opts }
x.L2.IsPacked = opts.GetPacked()
if opts.Packed != nil {
x.L1.EditionFeatures.IsPacked = opts.GetPacked()
}
}
x.L1.Number = protoreflect.FieldNumber(xd.GetNumber())
x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel())
@ -233,6 +215,9 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript
if xd.JsonName != nil {
x.L2.StringName.InitJSON(xd.GetJsonName())
}
if x.L1.Kind == protoreflect.MessageKind && x.L1.EditionFeatures.IsDelimitedEncoded {
x.L1.Kind = protoreflect.GroupKind
}
}
return xs, nil
}

View file

@ -46,6 +46,11 @@ func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*desc
if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName()), f.IsWeak()); err != nil {
return errors.New("message field %q cannot resolve type: %v", f.FullName(), err)
}
if f.L1.Kind == protoreflect.GroupKind && (f.IsMap() || f.IsMapEntry()) {
// A map field might inherit delimited encoding from a file-wide default feature.
// But maps never actually use delimited encoding. (At least for now...)
f.L1.Kind = protoreflect.MessageKind
}
if fd.DefaultValue != nil {
v, ev, err := unmarshalDefault(fd.GetDefaultValue(), f, r.allowUnresolvable)
if err != nil {

View file

@ -45,11 +45,11 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri
if allowAlias && !foundAlias {
return errors.New("enum %q allows aliases, but none were found", e.FullName())
}
if e.Syntax() == protoreflect.Proto3 {
if !e.IsClosed() {
if v := e.Values().Get(0); v.Number() != 0 {
return errors.New("enum %q using proto3 semantics must have zero number for the first value", v.FullName())
return errors.New("enum %q using open semantics must have zero number for the first value", v.FullName())
}
// Verify that value names in proto3 do not conflict if the
// Verify that value names in open enums do not conflict if the
// case-insensitive prefix is removed.
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055
names := map[string]protoreflect.EnumValueDescriptor{}
@ -58,7 +58,7 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri
v1 := e.Values().Get(i)
s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix))
if v2, ok := names[s]; ok && v1.Number() != v2.Number() {
return errors.New("enum %q using proto3 semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name())
return errors.New("enum %q using open semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name())
}
names[s] = v1
}
@ -80,7 +80,9 @@ func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescri
return nil
}
func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error {
func validateMessageDeclarations(file *filedesc.File, ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error {
// There are a few limited exceptions only for proto3
isProto3 := file.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3)
for i, md := range mds {
m := &ms[i]
@ -107,25 +109,13 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc
if isMessageSet && !flags.ProtoLegacy {
return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName())
}
if isMessageSet && (m.Syntax() == protoreflect.Proto3 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) {
if isMessageSet && (isProto3 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) {
return errors.New("message %q is an invalid proto1 MessageSet", m.FullName())
}
if m.Syntax() == protoreflect.Proto3 {
if isProto3 {
if m.ExtensionRanges().Len() > 0 {
return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName())
}
// Verify that field names in proto3 do not conflict if lowercased
// with all underscores removed.
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:5830-5847
names := map[string]protoreflect.FieldDescriptor{}
for i := 0; i < m.Fields().Len(); i++ {
f1 := m.Fields().Get(i)
s := strings.Replace(strings.ToLower(string(f1.Name())), "_", "", -1)
if f2, ok := names[s]; ok {
return errors.New("message %q using proto3 semantics has conflict: %q with %q", m.FullName(), f1.Name(), f2.Name())
}
names[s] = f1
}
}
for j, fd := range md.GetField() {
@ -149,7 +139,7 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc
return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee())
}
if f.L1.IsProto3Optional {
if f.Syntax() != protoreflect.Proto3 {
if !isProto3 {
return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName())
}
if f.Cardinality() != protoreflect.Optional {
@ -162,26 +152,29 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc
if f.IsWeak() && !flags.ProtoLegacy {
return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName())
}
if f.IsWeak() && (f.Syntax() != protoreflect.Proto2 || !isOptionalMessage(f) || f.ContainingOneof() != nil) {
if f.IsWeak() && (!f.HasPresence() || !isOptionalMessage(f) || f.ContainingOneof() != nil) {
return errors.New("message field %q may only be weak for an optional message", f.FullName())
}
if f.IsPacked() && !isPackable(f) {
return errors.New("message field %q is not packable", f.FullName())
}
if err := checkValidGroup(f); err != nil {
if err := checkValidGroup(file, f); err != nil {
return errors.New("message field %q is an invalid group: %v", f.FullName(), err)
}
if err := checkValidMap(f); err != nil {
return errors.New("message field %q is an invalid map: %v", f.FullName(), err)
}
if f.Syntax() == protoreflect.Proto3 {
if isProto3 {
if f.Cardinality() == protoreflect.Required {
return errors.New("message field %q using proto3 semantics cannot be required", f.FullName())
}
if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().Syntax() != protoreflect.Proto3 {
return errors.New("message field %q using proto3 semantics may only depend on a proto3 enum", f.FullName())
if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() {
return errors.New("message field %q using proto3 semantics may only depend on open enums", f.FullName())
}
}
if f.Cardinality() == protoreflect.Optional && !f.HasPresence() && f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() {
return errors.New("message field %q with implicit presence may only use open enums", f.FullName())
}
}
seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs
for j := range md.GetOneofDecl() {
@ -215,17 +208,17 @@ func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.Desc
if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil {
return err
}
if err := validateMessageDeclarations(m.L1.Messages.List, md.GetNestedType()); err != nil {
if err := validateMessageDeclarations(file, m.L1.Messages.List, md.GetNestedType()); err != nil {
return err
}
if err := validateExtensionDeclarations(m.L1.Extensions.List, md.GetExtension()); err != nil {
if err := validateExtensionDeclarations(file, m.L1.Extensions.List, md.GetExtension()); err != nil {
return err
}
}
return nil
}
func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error {
func validateExtensionDeclarations(f *filedesc.File, xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error {
for i, xd := range xds {
x := &xs[i]
// NOTE: Avoid using the IsValid method since extensions to MessageSet
@ -267,13 +260,13 @@ func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.
if x.IsPacked() && !isPackable(x) {
return errors.New("extension field %q is not packable", x.FullName())
}
if err := checkValidGroup(x); err != nil {
if err := checkValidGroup(f, x); err != nil {
return errors.New("extension field %q is an invalid group: %v", x.FullName(), err)
}
if md := x.Message(); md != nil && md.IsMapEntry() {
return errors.New("extension field %q cannot be a map entry", x.FullName())
}
if x.Syntax() == protoreflect.Proto3 {
if f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3) {
switch x.ContainingMessage().FullName() {
case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName():
@ -309,21 +302,25 @@ func isPackable(fd protoreflect.FieldDescriptor) bool {
// checkValidGroup reports whether fd is a valid group according to the same
// rules that protoc imposes.
func checkValidGroup(fd protoreflect.FieldDescriptor) error {
func checkValidGroup(f *filedesc.File, fd protoreflect.FieldDescriptor) error {
md := fd.Message()
switch {
case fd.Kind() != protoreflect.GroupKind:
return nil
case fd.Syntax() == protoreflect.Proto3:
case f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3):
return errors.New("invalid under proto3 semantics")
case md == nil || md.IsPlaceholder():
return errors.New("message must be resolvable")
case fd.FullName().Parent() != md.FullName().Parent():
return errors.New("message and field must be declared in the same scope")
case !unicode.IsUpper(rune(md.Name()[0])):
return errors.New("message name must start with an uppercase")
case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))):
return errors.New("field name must be lowercased form of the message name")
}
if f.L1.Edition < fromEditionProto(descriptorpb.Edition_EDITION_2023) {
switch {
case fd.FullName().Parent() != md.FullName().Parent():
return errors.New("message and field must be declared in the same scope")
case !unicode.IsUpper(rune(md.Name()[0])):
return errors.New("message name must start with an uppercase")
case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))):
return errors.New("field name must be lowercased form of the message name")
}
}
return nil
}

View file

@ -14,12 +14,7 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
gofeaturespb "google.golang.org/protobuf/types/gofeaturespb"
)
const (
SupportedEditionsMinimum = descriptorpb.Edition_EDITION_PROTO2
SupportedEditionsMaximum = descriptorpb.Edition_EDITION_2023
"google.golang.org/protobuf/types/gofeaturespb"
)
var defaults = &descriptorpb.FeatureSetDefaults{}
@ -48,6 +43,8 @@ func toEditionProto(ed filedesc.Edition) descriptorpb.Edition {
return descriptorpb.Edition_EDITION_PROTO3
case filedesc.Edition2023:
return descriptorpb.Edition_EDITION_2023
case filedesc.Edition2024:
return descriptorpb.Edition_EDITION_2024
default:
panic(fmt.Sprintf("unknown value for edition: %v", ed))
}
@ -67,18 +64,20 @@ func getFeatureSetFor(ed filedesc.Edition) *descriptorpb.FeatureSet {
fmt.Fprintf(os.Stderr, "internal error: unsupported edition %v (did you forget to update the embedded defaults (i.e. the bootstrap descriptor proto)?)\n", edpb)
os.Exit(1)
}
fs := defaults.GetDefaults()[0].GetFeatures()
fsed := defaults.GetDefaults()[0]
// Using a linear search for now.
// Editions are guaranteed to be sorted and thus we could use a binary search.
// Given that there are only a handful of editions (with one more per year)
// there is not much reason to use a binary search.
for _, def := range defaults.GetDefaults() {
if def.GetEdition() <= edpb {
fs = def.GetFeatures()
fsed = def
} else {
break
}
}
fs := proto.Clone(fsed.GetFixedFeatures()).(*descriptorpb.FeatureSet)
proto.Merge(fs, fsed.GetOverridableFeatures())
defaultsCache[ed] = fs
return fs
}
@ -130,6 +129,9 @@ func mergeEditionFeatures(parentDesc protoreflect.Descriptor, child *descriptorp
if luje := goFeatures.LegacyUnmarshalJsonEnum; luje != nil {
parentFS.GenerateLegacyUnmarshalJSON = *luje
}
if sep := goFeatures.StripEnumPrefix; sep != nil {
parentFS.StripEnumPrefix = int(*sep)
}
}
return parentFS

View file

@ -73,6 +73,16 @@ func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileD
if syntax := file.Syntax(); syntax != protoreflect.Proto2 && syntax.IsValid() {
p.Syntax = proto.String(file.Syntax().String())
}
if file.Syntax() == protoreflect.Editions {
desc := file
if fileImportDesc, ok := file.(protoreflect.FileImport); ok {
desc = fileImportDesc.FileDescriptor
}
if editionsInterface, ok := desc.(interface{ Edition() int32 }); ok {
p.Edition = descriptorpb.Edition(editionsInterface.Edition()).Enum()
}
}
return p
}
@ -153,6 +163,18 @@ func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.Fi
if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
p.Proto3Optional = proto.Bool(true)
}
if field.Syntax() == protoreflect.Editions {
// Editions have no group keyword, this type is only set so that downstream users continue
// treating this as delimited encoding.
if p.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP {
p.Type = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum()
}
// Editions have no required keyword, this label is only set so that downstream users continue
// treating it as required.
if p.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REQUIRED {
p.Label = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()
}
}
if field.HasDefault() {
def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
if err != nil && field.DefaultEnumValue() != nil {

View file

@ -23,6 +23,7 @@ type (
Unmarshal func(unmarshalInput) (unmarshalOutput, error)
Merge func(mergeInput) mergeOutput
CheckInitialized func(checkInitializedInput) (checkInitializedOutput, error)
Equal func(equalInput) equalOutput
}
supportFlags = uint64
sizeInput = struct {
@ -75,4 +76,13 @@ type (
checkInitializedOutput = struct {
pragma.NoUnkeyedLiterals
}
equalInput = struct {
pragma.NoUnkeyedLiterals
MessageA Message
MessageB Message
}
equalOutput = struct {
pragma.NoUnkeyedLiterals
Equal bool
}
)

View file

@ -161,7 +161,7 @@ const (
// IsValid reports whether the syntax is valid.
func (s Syntax) IsValid() bool {
switch s {
case Proto2, Proto3:
case Proto2, Proto3, Editions:
return true
default:
return false

View file

@ -373,6 +373,8 @@ func (p *SourcePath) appendFieldOptions(b []byte) []byte {
b = p.appendRepeatedField(b, "edition_defaults", (*SourcePath).appendFieldOptions_EditionDefault)
case 21:
b = p.appendSingularField(b, "features", (*SourcePath).appendFeatureSet)
case 22:
b = p.appendSingularField(b, "feature_support", (*SourcePath).appendFieldOptions_FeatureSupport)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
@ -483,6 +485,8 @@ func (p *SourcePath) appendEnumValueOptions(b []byte) []byte {
b = p.appendSingularField(b, "features", (*SourcePath).appendFeatureSet)
case 3:
b = p.appendSingularField(b, "debug_redact", nil)
case 4:
b = p.appendSingularField(b, "feature_support", (*SourcePath).appendFieldOptions_FeatureSupport)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
@ -519,6 +523,23 @@ func (p *SourcePath) appendFieldOptions_EditionDefault(b []byte) []byte {
return b
}
func (p *SourcePath) appendFieldOptions_FeatureSupport(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "edition_introduced", nil)
case 2:
b = p.appendSingularField(b, "edition_deprecated", nil)
case 3:
b = p.appendSingularField(b, "deprecation_warning", nil)
case 4:
b = p.appendSingularField(b, "edition_removed", nil)
}
return b
}
func (p *SourcePath) appendUninterpretedOption_NamePart(b []byte) []byte {
if len(*p) == 0 {
return b

View file

@ -510,7 +510,7 @@ type ExtensionType interface {
//
// ValueOf is more extensive than protoreflect.ValueOf for a given field's
// value as it has more type information available.
ValueOf(interface{}) Value
ValueOf(any) Value
// InterfaceOf completely unwraps the Value to the underlying Go type.
// InterfaceOf panics if the input is nil or does not represent the
@ -519,13 +519,13 @@ type ExtensionType interface {
//
// InterfaceOf is able to unwrap the Value further than Value.Interface
// as it has more type information available.
InterfaceOf(Value) interface{}
InterfaceOf(Value) any
// IsValidValue reports whether the Value is valid to assign to the field.
IsValidValue(Value) bool
// IsValidInterface reports whether the input is valid to assign to the field.
IsValidInterface(interface{}) bool
IsValidInterface(any) bool
}
// EnumDescriptor describes an enum and
@ -544,6 +544,12 @@ type EnumDescriptor interface {
// ReservedRanges is a list of reserved ranges of enum numbers.
ReservedRanges() EnumRanges
// IsClosed reports whether this enum uses closed semantics.
// See https://protobuf.dev/programming-guides/enum/#definitions.
// Note: the Go protobuf implementation is not spec compliant and treats
// all enums as open enums.
IsClosed() bool
isEnumDescriptor
}
type isEnumDescriptor interface{ ProtoType(EnumDescriptor) }

View file

@ -1,60 +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.
//go:build purego || appengine
// +build purego appengine
package protoreflect
import "google.golang.org/protobuf/internal/pragma"
type valueType int
const (
nilType valueType = iota
boolType
int32Type
int64Type
uint32Type
uint64Type
float32Type
float64Type
stringType
bytesType
enumType
ifaceType
)
// value is a union where only one type can be represented at a time.
// This uses a distinct field for each type. This is type safe in Go, but
// occupies more memory than necessary (72B).
type value struct {
pragma.DoNotCompare // 0B
typ valueType // 8B
num uint64 // 8B
str string // 16B
bin []byte // 24B
iface interface{} // 16B
}
func valueOfString(v string) Value {
return Value{typ: stringType, str: v}
}
func valueOfBytes(v []byte) Value {
return Value{typ: bytesType, bin: v}
}
func valueOfIface(v interface{}) Value {
return Value{typ: ifaceType, iface: v}
}
func (v Value) getString() string {
return v.str
}
func (v Value) getBytes() []byte {
return v.bin
}
func (v Value) getIface() interface{} {
return v.iface
}

View file

@ -69,8 +69,8 @@ import (
// composite Value. Modifying an empty, read-only value panics.
type Value value
// The protoreflect API uses a custom Value union type instead of interface{}
// to keep the future open for performance optimizations. Using an interface{}
// The protoreflect API uses a custom Value union type instead of any
// to keep the future open for performance optimizations. Using an any
// always incurs an allocation for primitives (e.g., int64) since it needs to
// be boxed on the heap (as interfaces can only contain pointers natively).
// Instead, we represent the Value union as a flat struct that internally keeps
@ -85,7 +85,7 @@ type Value value
// ValueOf returns a Value initialized with the concrete value stored in v.
// This panics if the type does not match one of the allowed types in the
// Value union.
func ValueOf(v interface{}) Value {
func ValueOf(v any) Value {
switch v := v.(type) {
case nil:
return Value{}
@ -192,10 +192,10 @@ func (v Value) IsValid() bool {
return v.typ != nilType
}
// Interface returns v as an interface{}.
// Interface returns v as an any.
//
// Invariant: v == ValueOf(v).Interface()
func (v Value) Interface() interface{} {
func (v Value) Interface() any {
switch v.typ {
case nilType:
return nil
@ -406,8 +406,8 @@ func (k MapKey) IsValid() bool {
return Value(k).IsValid()
}
// Interface returns k as an interface{}.
func (k MapKey) Interface() interface{} {
// Interface returns k as an any.
func (k MapKey) Interface() any {
return Value(k).Interface()
}

View file

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && !go1.21
// +build !purego,!appengine,!go1.21
//go:build !go1.21
package protoreflect
@ -45,7 +44,7 @@ var (
// typeOf returns a pointer to the Go type information.
// The pointer is comparable and equal if and only if the types are identical.
func typeOf(t interface{}) unsafe.Pointer {
func typeOf(t any) unsafe.Pointer {
return (*ifaceHeader)(unsafe.Pointer(&t)).Type
}
@ -80,7 +79,7 @@ func valueOfBytes(v []byte) Value {
p := (*sliceHeader)(unsafe.Pointer(&v))
return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))}
}
func valueOfIface(v interface{}) Value {
func valueOfIface(v any) Value {
p := (*ifaceHeader)(unsafe.Pointer(&v))
return Value{typ: p.Type, ptr: p.Data}
}
@ -93,7 +92,7 @@ func (v Value) getBytes() (x []byte) {
*(*sliceHeader)(unsafe.Pointer(&x)) = sliceHeader{Data: v.ptr, Len: int(v.num), Cap: int(v.num)}
return x
}
func (v Value) getIface() (x interface{}) {
func (v Value) getIface() (x any) {
*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
return x
}

View file

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !purego && !appengine && go1.21
// +build !purego,!appengine,go1.21
//go:build go1.21
package protoreflect
@ -15,7 +14,7 @@ import (
type (
ifaceHeader struct {
_ [0]interface{} // if interfaces have greater alignment than unsafe.Pointer, this will enforce it.
_ [0]any // if interfaces have greater alignment than unsafe.Pointer, this will enforce it.
Type unsafe.Pointer
Data unsafe.Pointer
}
@ -37,7 +36,7 @@ var (
// typeOf returns a pointer to the Go type information.
// The pointer is comparable and equal if and only if the types are identical.
func typeOf(t interface{}) unsafe.Pointer {
func typeOf(t any) unsafe.Pointer {
return (*ifaceHeader)(unsafe.Pointer(&t)).Type
}
@ -70,7 +69,7 @@ func valueOfString(v string) Value {
func valueOfBytes(v []byte) Value {
return Value{typ: bytesType, ptr: unsafe.Pointer(unsafe.SliceData(v)), num: uint64(len(v))}
}
func valueOfIface(v interface{}) Value {
func valueOfIface(v any) Value {
p := (*ifaceHeader)(unsafe.Pointer(&v))
return Value{typ: p.Type, ptr: p.Data}
}
@ -81,7 +80,7 @@ func (v Value) getString() string {
func (v Value) getBytes() []byte {
return unsafe.Slice((*byte)(v.ptr), v.num)
}
func (v Value) getIface() (x interface{}) {
func (v Value) getIface() (x any) {
*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
return x
}

View file

@ -95,7 +95,7 @@ type Files struct {
// multiple files. Only top-level declarations are registered.
// Note that enum values are in the top-level since that are in the same
// scope as the parent enum.
descsByName map[protoreflect.FullName]interface{}
descsByName map[protoreflect.FullName]any
filesByPath map[string][]protoreflect.FileDescriptor
numFiles int
}
@ -117,7 +117,7 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
defer globalMutex.Unlock()
}
if r.descsByName == nil {
r.descsByName = map[protoreflect.FullName]interface{}{
r.descsByName = map[protoreflect.FullName]any{
"": &packageDescriptor{},
}
r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
@ -485,7 +485,7 @@ type Types struct {
}
type (
typesByName map[protoreflect.FullName]interface{}
typesByName map[protoreflect.FullName]any
extensionsByMessage map[protoreflect.FullName]extensionsByNumber
extensionsByNumber map[protoreflect.FieldNumber]protoreflect.ExtensionType
)
@ -570,7 +570,7 @@ func (r *Types) RegisterExtension(xt protoreflect.ExtensionType) error {
return nil
}
func (r *Types) register(kind string, desc protoreflect.Descriptor, typ interface{}) error {
func (r *Types) register(kind string, desc protoreflect.Descriptor, typ any) error {
name := desc.FullName()
prev := r.typesByName[name]
if prev != nil {
@ -841,7 +841,7 @@ func (r *Types) RangeExtensionsByMessage(message protoreflect.FullName, f func(p
}
}
func typeName(t interface{}) string {
func typeName(t any) string {
switch t.(type) {
case protoreflect.EnumType:
return "enum"
@ -854,7 +854,7 @@ func typeName(t interface{}) string {
}
}
func amendErrorWithCaller(err error, prev, curr interface{}) error {
func amendErrorWithCaller(err error, prev, curr any) error {
prevPkg := goPackage(prev)
currPkg := goPackage(curr)
if prevPkg == "" || currPkg == "" || prevPkg == currPkg {
@ -863,7 +863,7 @@ func amendErrorWithCaller(err error, prev, curr interface{}) error {
return errors.New("%s\n\tpreviously from: %q\n\tcurrently from: %q", err, prevPkg, currPkg)
}
func goPackage(v interface{}) string {
func goPackage(v any) string {
switch d := v.(type) {
case protoreflect.EnumType:
v = d.Descriptor()

View file

@ -39,6 +39,9 @@ type Methods = struct {
// CheckInitialized returns an error if any required fields in the message are not set.
CheckInitialized func(CheckInitializedInput) (CheckInitializedOutput, error)
// Equal compares two messages and returns EqualOutput.Equal == true if they are equal.
Equal func(EqualInput) EqualOutput
}
// SupportFlags indicate support for optional features.
@ -166,3 +169,18 @@ type CheckInitializedInput = struct {
type CheckInitializedOutput = struct {
pragma.NoUnkeyedLiterals
}
// EqualInput is input to the Equal method.
type EqualInput = struct {
pragma.NoUnkeyedLiterals
MessageA protoreflect.Message
MessageB protoreflect.Message
}
// EqualOutput is output from the Equal method.
type EqualOutput = struct {
pragma.NoUnkeyedLiterals
Equal bool
}

File diff suppressed because it is too large Load diff

View file

@ -294,7 +294,7 @@ func (m *Message) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
case fd.IsMap():
return protoreflect.ValueOfMap(&dynamicMap{
desc: fd,
mapv: make(map[interface{}]protoreflect.Value),
mapv: make(map[any]protoreflect.Value),
})
case fd.IsList():
return protoreflect.ValueOfList(&dynamicList{desc: fd})
@ -450,7 +450,7 @@ func (x *dynamicList) IsValid() bool {
type dynamicMap struct {
desc protoreflect.FieldDescriptor
mapv map[interface{}]protoreflect.Value
mapv map[any]protoreflect.Value
}
func (x *dynamicMap) Get(k protoreflect.MapKey) protoreflect.Value { return x.mapv[k.Interface()] }
@ -634,11 +634,11 @@ func newListEntry(fd protoreflect.FieldDescriptor) protoreflect.Value {
//
// The InterfaceOf and ValueOf methods of the extension type are defined as:
//
// func (xt extensionType) ValueOf(iv interface{}) protoreflect.Value {
// func (xt extensionType) ValueOf(iv any) protoreflect.Value {
// return protoreflect.ValueOf(iv)
// }
//
// func (xt extensionType) InterfaceOf(v protoreflect.Value) interface{} {
// func (xt extensionType) InterfaceOf(v protoreflect.Value) any {
// return v.Interface()
// }
//
@ -658,7 +658,7 @@ func (xt extensionType) New() protoreflect.Value {
case xt.desc.IsMap():
return protoreflect.ValueOfMap(&dynamicMap{
desc: xt.desc,
mapv: make(map[interface{}]protoreflect.Value),
mapv: make(map[any]protoreflect.Value),
})
case xt.desc.IsList():
return protoreflect.ValueOfList(&dynamicList{desc: xt.desc})
@ -686,18 +686,18 @@ func (xt extensionType) TypeDescriptor() protoreflect.ExtensionTypeDescriptor {
return xt.desc
}
func (xt extensionType) ValueOf(iv interface{}) protoreflect.Value {
func (xt extensionType) ValueOf(iv any) protoreflect.Value {
v := protoreflect.ValueOf(iv)
typecheck(xt.desc, v)
return v
}
func (xt extensionType) InterfaceOf(v protoreflect.Value) interface{} {
func (xt extensionType) InterfaceOf(v protoreflect.Value) any {
typecheck(xt.desc, v)
return v.Interface()
}
func (xt extensionType) IsValidInterface(iv interface{}) bool {
func (xt extensionType) IsValidInterface(iv any) bool {
return typeIsValid(xt.desc, protoreflect.ValueOf(iv)) == nil
}

View file

@ -6,9 +6,9 @@
// https://developers.google.com/open-source/licenses/bsd
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: reflect/protodesc/proto/go_features.proto
// source: google/protobuf/go_features.proto
package proto
package gofeaturespb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@ -18,22 +18,83 @@ import (
sync "sync"
)
type GoFeatures_StripEnumPrefix int32
const (
GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED GoFeatures_StripEnumPrefix = 0
GoFeatures_STRIP_ENUM_PREFIX_KEEP GoFeatures_StripEnumPrefix = 1
GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH GoFeatures_StripEnumPrefix = 2
GoFeatures_STRIP_ENUM_PREFIX_STRIP GoFeatures_StripEnumPrefix = 3
)
// Enum value maps for GoFeatures_StripEnumPrefix.
var (
GoFeatures_StripEnumPrefix_name = map[int32]string{
0: "STRIP_ENUM_PREFIX_UNSPECIFIED",
1: "STRIP_ENUM_PREFIX_KEEP",
2: "STRIP_ENUM_PREFIX_GENERATE_BOTH",
3: "STRIP_ENUM_PREFIX_STRIP",
}
GoFeatures_StripEnumPrefix_value = map[string]int32{
"STRIP_ENUM_PREFIX_UNSPECIFIED": 0,
"STRIP_ENUM_PREFIX_KEEP": 1,
"STRIP_ENUM_PREFIX_GENERATE_BOTH": 2,
"STRIP_ENUM_PREFIX_STRIP": 3,
}
)
func (x GoFeatures_StripEnumPrefix) Enum() *GoFeatures_StripEnumPrefix {
p := new(GoFeatures_StripEnumPrefix)
*p = x
return p
}
func (x GoFeatures_StripEnumPrefix) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (GoFeatures_StripEnumPrefix) Descriptor() protoreflect.EnumDescriptor {
return file_google_protobuf_go_features_proto_enumTypes[0].Descriptor()
}
func (GoFeatures_StripEnumPrefix) Type() protoreflect.EnumType {
return &file_google_protobuf_go_features_proto_enumTypes[0]
}
func (x GoFeatures_StripEnumPrefix) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Do not use.
func (x *GoFeatures_StripEnumPrefix) UnmarshalJSON(b []byte) error {
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
*x = GoFeatures_StripEnumPrefix(num)
return nil
}
// Deprecated: Use GoFeatures_StripEnumPrefix.Descriptor instead.
func (GoFeatures_StripEnumPrefix) EnumDescriptor() ([]byte, []int) {
return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0, 0}
}
type GoFeatures struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Whether or not to generate the deprecated UnmarshalJSON method for enums.
LegacyUnmarshalJsonEnum *bool `protobuf:"varint,1,opt,name=legacy_unmarshal_json_enum,json=legacyUnmarshalJsonEnum" json:"legacy_unmarshal_json_enum,omitempty"`
LegacyUnmarshalJsonEnum *bool `protobuf:"varint,1,opt,name=legacy_unmarshal_json_enum,json=legacyUnmarshalJsonEnum" json:"legacy_unmarshal_json_enum,omitempty"`
StripEnumPrefix *GoFeatures_StripEnumPrefix `protobuf:"varint,3,opt,name=strip_enum_prefix,json=stripEnumPrefix,enum=pb.GoFeatures_StripEnumPrefix" json:"strip_enum_prefix,omitempty"`
}
func (x *GoFeatures) Reset() {
*x = GoFeatures{}
if protoimpl.UnsafeEnabled {
mi := &file_reflect_protodesc_proto_go_features_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_go_features_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GoFeatures) String() string {
@ -43,8 +104,8 @@ func (x *GoFeatures) String() string {
func (*GoFeatures) ProtoMessage() {}
func (x *GoFeatures) ProtoReflect() protoreflect.Message {
mi := &file_reflect_protodesc_proto_go_features_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
mi := &file_google_protobuf_go_features_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -56,7 +117,7 @@ func (x *GoFeatures) ProtoReflect() protoreflect.Message {
// Deprecated: Use GoFeatures.ProtoReflect.Descriptor instead.
func (*GoFeatures) Descriptor() ([]byte, []int) {
return file_reflect_protodesc_proto_go_features_proto_rawDescGZIP(), []int{0}
return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0}
}
func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool {
@ -66,112 +127,130 @@ func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool {
return false
}
var file_reflect_protodesc_proto_go_features_proto_extTypes = []protoimpl.ExtensionInfo{
func (x *GoFeatures) GetStripEnumPrefix() GoFeatures_StripEnumPrefix {
if x != nil && x.StripEnumPrefix != nil {
return *x.StripEnumPrefix
}
return GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED
}
var file_google_protobuf_go_features_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*descriptorpb.FeatureSet)(nil),
ExtensionType: (*GoFeatures)(nil),
Field: 1002,
Name: "google.protobuf.go",
Name: "pb.go",
Tag: "bytes,1002,opt,name=go",
Filename: "reflect/protodesc/proto/go_features.proto",
Filename: "google/protobuf/go_features.proto",
},
}
// Extension fields to descriptorpb.FeatureSet.
var (
// optional google.protobuf.GoFeatures go = 1002;
E_Go = &file_reflect_protodesc_proto_go_features_proto_extTypes[0]
// optional pb.GoFeatures go = 1002;
E_Go = &file_google_protobuf_go_features_proto_extTypes[0]
)
var File_reflect_protodesc_proto_go_features_proto protoreflect.FileDescriptor
var File_google_protobuf_go_features_proto protoreflect.FileDescriptor
var file_reflect_protodesc_proto_go_features_proto_rawDesc = []byte{
0x0a, 0x29, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x64,
0x65, 0x73, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61,
0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x20, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a,
0x0a, 0x0a, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x5c, 0x0a, 0x1a,
0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c,
0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x42, 0x1f, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72, 0x75,
0x65, 0x18, 0xe6, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18, 0xe7,
0x07, 0x52, 0x17, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68,
0x61, 0x6c, 0x4a, 0x73, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x49, 0x0a, 0x02, 0x67, 0x6f,
0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x18, 0xea, 0x07,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
0x73, 0x52, 0x02, 0x67, 0x6f, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x64, 0x65, 0x73, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
var file_google_protobuf_go_features_proto_rawDesc = []byte{
0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x03, 0x0a, 0x0a, 0x47, 0x6f,
0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x1a, 0x6c, 0x65, 0x67,
0x61, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x5f, 0x6a, 0x73,
0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x80, 0x01,
0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72,
0x75, 0x65, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18,
0xe7, 0x07, 0xb2, 0x01, 0x5b, 0x08, 0xe8, 0x07, 0x10, 0xe8, 0x07, 0x1a, 0x53, 0x54, 0x68, 0x65,
0x20, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x20, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61,
0x6c, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x41, 0x50, 0x49, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70,
0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c,
0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61,
0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x20, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x52, 0x17, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61,
0x6c, 0x4a, 0x73, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x7c, 0x0a, 0x11, 0x73, 0x74, 0x72,
0x69, 0x70, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74,
0x75, 0x72, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x70, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72,
0x65, 0x66, 0x69, 0x78, 0x42, 0x30, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x07, 0x98,
0x01, 0x01, 0xa2, 0x01, 0x1b, 0x12, 0x16, 0x53, 0x54, 0x52, 0x49, 0x50, 0x5f, 0x45, 0x4e, 0x55,
0x4d, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x5f, 0x4b, 0x45, 0x45, 0x50, 0x18, 0x84, 0x07,
0xb2, 0x01, 0x03, 0x08, 0xe9, 0x07, 0x52, 0x0f, 0x73, 0x74, 0x72, 0x69, 0x70, 0x45, 0x6e, 0x75,
0x6d, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x92, 0x01, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69,
0x70, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x21, 0x0a, 0x1d, 0x53,
0x54, 0x52, 0x49, 0x50, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58,
0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a,
0x0a, 0x16, 0x53, 0x54, 0x52, 0x49, 0x50, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x50, 0x52, 0x45,
0x46, 0x49, 0x58, 0x5f, 0x4b, 0x45, 0x45, 0x50, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x54,
0x52, 0x49, 0x50, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x5f,
0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x54, 0x48, 0x10, 0x02, 0x12,
0x1b, 0x0a, 0x17, 0x53, 0x54, 0x52, 0x49, 0x50, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x50, 0x52,
0x45, 0x46, 0x49, 0x58, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x50, 0x10, 0x03, 0x3a, 0x3c, 0x0a, 0x02,
0x67, 0x6f, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x18,
0xea, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x6f, 0x46, 0x65,
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x02, 0x67, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x67,
0x6f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x70, 0x62,
}
var (
file_reflect_protodesc_proto_go_features_proto_rawDescOnce sync.Once
file_reflect_protodesc_proto_go_features_proto_rawDescData = file_reflect_protodesc_proto_go_features_proto_rawDesc
file_google_protobuf_go_features_proto_rawDescOnce sync.Once
file_google_protobuf_go_features_proto_rawDescData = file_google_protobuf_go_features_proto_rawDesc
)
func file_reflect_protodesc_proto_go_features_proto_rawDescGZIP() []byte {
file_reflect_protodesc_proto_go_features_proto_rawDescOnce.Do(func() {
file_reflect_protodesc_proto_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(file_reflect_protodesc_proto_go_features_proto_rawDescData)
func file_google_protobuf_go_features_proto_rawDescGZIP() []byte {
file_google_protobuf_go_features_proto_rawDescOnce.Do(func() {
file_google_protobuf_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_go_features_proto_rawDescData)
})
return file_reflect_protodesc_proto_go_features_proto_rawDescData
return file_google_protobuf_go_features_proto_rawDescData
}
var file_reflect_protodesc_proto_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_reflect_protodesc_proto_go_features_proto_goTypes = []interface{}{
(*GoFeatures)(nil), // 0: google.protobuf.GoFeatures
(*descriptorpb.FeatureSet)(nil), // 1: google.protobuf.FeatureSet
var file_google_protobuf_go_features_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_protobuf_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_protobuf_go_features_proto_goTypes = []any{
(GoFeatures_StripEnumPrefix)(0), // 0: pb.GoFeatures.StripEnumPrefix
(*GoFeatures)(nil), // 1: pb.GoFeatures
(*descriptorpb.FeatureSet)(nil), // 2: google.protobuf.FeatureSet
}
var file_reflect_protodesc_proto_go_features_proto_depIdxs = []int32{
1, // 0: google.protobuf.go:extendee -> google.protobuf.FeatureSet
0, // 1: google.protobuf.go:type_name -> google.protobuf.GoFeatures
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
1, // [1:2] is the sub-list for extension type_name
0, // [0:1] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
var file_google_protobuf_go_features_proto_depIdxs = []int32{
0, // 0: pb.GoFeatures.strip_enum_prefix:type_name -> pb.GoFeatures.StripEnumPrefix
2, // 1: pb.go:extendee -> google.protobuf.FeatureSet
1, // 2: pb.go:type_name -> pb.GoFeatures
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
2, // [2:3] is the sub-list for extension type_name
1, // [1:2] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_reflect_protodesc_proto_go_features_proto_init() }
func file_reflect_protodesc_proto_go_features_proto_init() {
if File_reflect_protodesc_proto_go_features_proto != nil {
func init() { file_google_protobuf_go_features_proto_init() }
func file_google_protobuf_go_features_proto_init() {
if File_google_protobuf_go_features_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_reflect_protodesc_proto_go_features_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GoFeatures); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_reflect_protodesc_proto_go_features_proto_rawDesc,
NumEnums: 0,
RawDescriptor: file_google_protobuf_go_features_proto_rawDesc,
NumEnums: 1,
NumMessages: 1,
NumExtensions: 1,
NumServices: 0,
},
GoTypes: file_reflect_protodesc_proto_go_features_proto_goTypes,
DependencyIndexes: file_reflect_protodesc_proto_go_features_proto_depIdxs,
MessageInfos: file_reflect_protodesc_proto_go_features_proto_msgTypes,
ExtensionInfos: file_reflect_protodesc_proto_go_features_proto_extTypes,
GoTypes: file_google_protobuf_go_features_proto_goTypes,
DependencyIndexes: file_google_protobuf_go_features_proto_depIdxs,
EnumInfos: file_google_protobuf_go_features_proto_enumTypes,
MessageInfos: file_google_protobuf_go_features_proto_msgTypes,
ExtensionInfos: file_google_protobuf_go_features_proto_extTypes,
}.Build()
File_reflect_protodesc_proto_go_features_proto = out.File
file_reflect_protodesc_proto_go_features_proto_rawDesc = nil
file_reflect_protodesc_proto_go_features_proto_goTypes = nil
file_reflect_protodesc_proto_go_features_proto_depIdxs = nil
File_google_protobuf_go_features_proto = out.File
file_google_protobuf_go_features_proto_rawDesc = nil
file_google_protobuf_go_features_proto_goTypes = nil
file_google_protobuf_go_features_proto_depIdxs = nil
}

View file

@ -1,28 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package google.protobuf;
import "google/protobuf/descriptor.proto";
option go_package = "google.golang.org/protobuf/types/gofeaturespb";
extend google.protobuf.FeatureSet {
optional GoFeatures go = 1002;
}
message GoFeatures {
// Whether or not to generate the deprecated UnmarshalJSON method for enums.
optional bool legacy_unmarshal_json_enum = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ENUM,
edition_defaults = { edition: EDITION_PROTO2, value: "true" },
edition_defaults = { edition: EDITION_PROTO3, value: "false" }
];
}

View file

@ -368,11 +368,9 @@ func (x *Any) UnmarshalNew() (proto.Message, error) {
func (x *Any) Reset() {
*x = Any{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_any_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_any_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Any) String() string {
@ -383,7 +381,7 @@ func (*Any) ProtoMessage() {}
func (x *Any) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_any_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -445,7 +443,7 @@ func file_google_protobuf_any_proto_rawDescGZIP() []byte {
}
var file_google_protobuf_any_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_protobuf_any_proto_goTypes = []interface{}{
var file_google_protobuf_any_proto_goTypes = []any{
(*Any)(nil), // 0: google.protobuf.Any
}
var file_google_protobuf_any_proto_depIdxs = []int32{
@ -461,20 +459,6 @@ func file_google_protobuf_any_proto_init() {
if File_google_protobuf_any_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_google_protobuf_any_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Any); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

View file

@ -245,11 +245,9 @@ func (x *Duration) check() uint {
func (x *Duration) Reset() {
*x = Duration{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_duration_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_duration_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Duration) String() string {
@ -260,7 +258,7 @@ func (*Duration) ProtoMessage() {}
func (x *Duration) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_duration_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -323,7 +321,7 @@ func file_google_protobuf_duration_proto_rawDescGZIP() []byte {
}
var file_google_protobuf_duration_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_protobuf_duration_proto_goTypes = []interface{}{
var file_google_protobuf_duration_proto_goTypes = []any{
(*Duration)(nil), // 0: google.protobuf.Duration
}
var file_google_protobuf_duration_proto_depIdxs = []int32{
@ -339,20 +337,6 @@ func file_google_protobuf_duration_proto_init() {
if File_google_protobuf_duration_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_google_protobuf_duration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Duration); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

View file

@ -254,11 +254,9 @@ func (x *Timestamp) check() uint {
func (x *Timestamp) Reset() {
*x = Timestamp{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_timestamp_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_timestamp_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Timestamp) String() string {
@ -269,7 +267,7 @@ func (*Timestamp) ProtoMessage() {}
func (x *Timestamp) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_timestamp_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -332,7 +330,7 @@ func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte {
}
var file_google_protobuf_timestamp_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_protobuf_timestamp_proto_goTypes = []interface{}{
var file_google_protobuf_timestamp_proto_goTypes = []any{
(*Timestamp)(nil), // 0: google.protobuf.Timestamp
}
var file_google_protobuf_timestamp_proto_depIdxs = []int32{
@ -348,20 +346,6 @@ func file_google_protobuf_timestamp_proto_init() {
if File_google_protobuf_timestamp_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_google_protobuf_timestamp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Timestamp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

View file

@ -107,11 +107,9 @@ type Version struct {
func (x *Version) Reset() {
*x = Version{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Version) String() string {
@ -122,7 +120,7 @@ func (*Version) ProtoMessage() {}
func (x *Version) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -207,11 +205,9 @@ type CodeGeneratorRequest struct {
func (x *CodeGeneratorRequest) Reset() {
*x = CodeGeneratorRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CodeGeneratorRequest) String() string {
@ -222,7 +218,7 @@ func (*CodeGeneratorRequest) ProtoMessage() {}
func (x *CodeGeneratorRequest) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -305,11 +301,9 @@ type CodeGeneratorResponse struct {
func (x *CodeGeneratorResponse) Reset() {
*x = CodeGeneratorResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CodeGeneratorResponse) String() string {
@ -320,7 +314,7 @@ func (*CodeGeneratorResponse) ProtoMessage() {}
func (x *CodeGeneratorResponse) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -440,11 +434,9 @@ type CodeGeneratorResponse_File struct {
func (x *CodeGeneratorResponse_File) Reset() {
*x = CodeGeneratorResponse_File{}
if protoimpl.UnsafeEnabled {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CodeGeneratorResponse_File) String() string {
@ -455,7 +447,7 @@ func (*CodeGeneratorResponse_File) ProtoMessage() {}
func (x *CodeGeneratorResponse_File) ProtoReflect() protoreflect.Message {
mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -591,7 +583,7 @@ func file_google_protobuf_compiler_plugin_proto_rawDescGZIP() []byte {
var file_google_protobuf_compiler_plugin_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_protobuf_compiler_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_google_protobuf_compiler_plugin_proto_goTypes = []interface{}{
var file_google_protobuf_compiler_plugin_proto_goTypes = []any{
(CodeGeneratorResponse_Feature)(0), // 0: google.protobuf.compiler.CodeGeneratorResponse.Feature
(*Version)(nil), // 1: google.protobuf.compiler.Version
(*CodeGeneratorRequest)(nil), // 2: google.protobuf.compiler.CodeGeneratorRequest
@ -618,56 +610,6 @@ func file_google_protobuf_compiler_plugin_proto_init() {
if File_google_protobuf_compiler_plugin_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_google_protobuf_compiler_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Version); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_google_protobuf_compiler_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeGeneratorRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_google_protobuf_compiler_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeGeneratorResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_google_protobuf_compiler_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeGeneratorResponse_File); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{

5
vendor/modules.txt vendored
View file

@ -583,8 +583,8 @@ google.golang.org/grpc/tap
# google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
## explicit; go 1.17
google.golang.org/grpc/cmd/protoc-gen-go-grpc
# google.golang.org/protobuf v1.33.0
## explicit; go 1.17
# google.golang.org/protobuf v1.35.2
## explicit; go 1.21
google.golang.org/protobuf/cmd/protoc-gen-go
google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo
google.golang.org/protobuf/compiler/protogen
@ -595,6 +595,7 @@ google.golang.org/protobuf/internal/descfmt
google.golang.org/protobuf/internal/descopts
google.golang.org/protobuf/internal/detrand
google.golang.org/protobuf/internal/editiondefaults
google.golang.org/protobuf/internal/editionssupport
google.golang.org/protobuf/internal/encoding/defval
google.golang.org/protobuf/internal/encoding/json
google.golang.org/protobuf/internal/encoding/messageset