vendor: google.golang.org/protobuf v1.36.6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-06-12 14:11:07 +02:00
parent bab8478ef3
commit f6985b7a27
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
78 changed files with 4699 additions and 2162 deletions

View File

@ -106,5 +106,5 @@ require (
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
google.golang.org/grpc v1.69.4 // indirect google.golang.org/grpc v1.69.4 // indirect
google.golang.org/protobuf v1.35.2 // indirect google.golang.org/protobuf v1.36.6 // indirect
) )

View File

@ -386,8 +386,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=

View File

@ -192,11 +192,6 @@ func (d decoder) unmarshalMessage(m protoreflect.Message, skipTypeURL bool) erro
fd = fieldDescs.ByTextName(name) fd = fieldDescs.ByTextName(name)
} }
} }
if flags.ProtoLegacy {
if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
fd = nil // reset since the weak reference is not linked in
}
}
if fd == nil { if fd == nil {
// Field is unknown. // Field is unknown.

View File

@ -185,11 +185,6 @@ func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) erro
} else if xtErr != nil && xtErr != protoregistry.NotFound { } else if xtErr != nil && xtErr != protoregistry.NotFound {
return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr) return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr)
} }
if flags.ProtoLegacy {
if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
fd = nil // reset since the weak reference is not linked in
}
}
// Handle unknown fields. // Handle unknown fields.
if fd == nil { if fd == nil {

View File

@ -26,7 +26,7 @@ var byteType = reflect.TypeOf(byte(0))
// The type is the underlying field type (e.g., a repeated field may be // The type is the underlying field type (e.g., a repeated field may be
// represented by []T, but the Go type passed in is just T). // represented by []T, but the Go type passed in is just T).
// A list of enum value descriptors must be provided for enum fields. // A list of enum value descriptors must be provided for enum fields.
// This does not populate the Enum or Message (except for weak message). // This does not populate the Enum or Message.
// //
// This function is a best effort attempt; parsing errors are ignored. // This function is a best effort attempt; parsing errors are ignored.
func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor { func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor {
@ -109,9 +109,6 @@ func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescri
} }
case s == "packed": case s == "packed":
f.L1.EditionFeatures.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="):]))
case strings.HasPrefix(s, "def="): case strings.HasPrefix(s, "def="):
// The default tag is special in that everything afterwards is the // The default tag is special in that everything afterwards is the
// default regardless of the presence of commas. // default regardless of the presence of commas.
@ -183,9 +180,6 @@ func Marshal(fd protoreflect.FieldDescriptor, enumName string) string {
// the exact same semantics from the previous generator. // the exact same semantics from the previous generator.
tag = append(tag, "json="+jsonName) tag = append(tag, "json="+jsonName)
} }
if fd.IsWeak() {
tag = append(tag, "weak="+string(fd.Message().FullName()))
}
// The previous implementation does not tag extension fields as proto3, // The previous implementation does not tag extension fields as proto3,
// even when the field is defined in a proto3 file. Match that behavior // even when the field is defined in a proto3 file. Match that behavior
// for consistency. // for consistency.

View File

@ -1,40 +0,0 @@
// Copyright 2020 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 !go1.13
// +build !go1.13
package errors
import "reflect"
// Is is a copy of Go 1.13's errors.Is for use with older Go versions.
func Is(err, target error) bool {
if target == nil {
return err == target
}
isComparable := reflect.TypeOf(target).Comparable()
for {
if isComparable && err == target {
return true
}
if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
return true
}
if err = unwrap(err); err == nil {
return false
}
}
}
func unwrap(err error) error {
u, ok := err.(interface {
Unwrap() error
})
if !ok {
return nil
}
return u.Unwrap()
}

View File

@ -1,13 +0,0 @@
// Copyright 2020 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 go1.13
// +build go1.13
package errors
import "errors"
// Is is errors.Is.
func Is(err, target error) bool { return errors.Is(err, target) }

View File

@ -19,7 +19,6 @@ import (
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
) )
// Edition is an Enum for proto2.Edition // Edition is an Enum for proto2.Edition
@ -117,6 +116,9 @@ type (
// GenerateLegacyUnmarshalJSON determines if the plugin generates the // GenerateLegacyUnmarshalJSON determines if the plugin generates the
// UnmarshalJSON([]byte) error method for enums. // UnmarshalJSON([]byte) error method for enums.
GenerateLegacyUnmarshalJSON bool GenerateLegacyUnmarshalJSON bool
// APILevel controls which API (Open, Hybrid or Opaque) should be used
// for generated code (.pb.go files).
APILevel int
} }
) )
@ -272,7 +274,6 @@ type (
Kind protoreflect.Kind Kind protoreflect.Kind
StringName stringName StringName stringName
IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
IsWeak bool // promoted from google.protobuf.FieldOptions
IsLazy bool // promoted from google.protobuf.FieldOptions IsLazy bool // promoted from google.protobuf.FieldOptions
Default defaultValue Default defaultValue
ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
@ -366,7 +367,7 @@ func (fd *Field) IsPacked() bool {
return fd.L1.EditionFeatures.IsPacked return fd.L1.EditionFeatures.IsPacked
} }
func (fd *Field) IsExtension() bool { return false } func (fd *Field) IsExtension() bool { return false }
func (fd *Field) IsWeak() bool { return fd.L1.IsWeak } func (fd *Field) IsWeak() bool { return false }
func (fd *Field) IsLazy() bool { return fd.L1.IsLazy } func (fd *Field) IsLazy() bool { return fd.L1.IsLazy }
func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() } 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) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
@ -393,11 +394,6 @@ func (fd *Field) Enum() protoreflect.EnumDescriptor {
return fd.L1.Enum return fd.L1.Enum
} }
func (fd *Field) Message() protoreflect.MessageDescriptor { func (fd *Field) Message() protoreflect.MessageDescriptor {
if fd.L1.IsWeak {
if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
return d.(protoreflect.MessageDescriptor)
}
}
return fd.L1.Message return fd.L1.Message
} }
func (fd *Field) IsMapEntry() bool { func (fd *Field) IsMapEntry() bool {

View File

@ -32,11 +32,6 @@ func (file *File) resolveMessages() {
for j := range md.L2.Fields.List { for j := range md.L2.Fields.List {
fd := &md.L2.Fields.List[j] fd := &md.L2.Fields.List[j]
// Weak fields are resolved upon actual use.
if fd.L1.IsWeak {
continue
}
// Resolve message field dependency. // Resolve message field dependency.
switch fd.L1.Kind { switch fd.L1.Kind {
case protoreflect.EnumKind: case protoreflect.EnumKind:
@ -150,8 +145,6 @@ func (fd *File) unmarshalFull(b []byte) {
switch num { switch num {
case genid.FileDescriptorProto_PublicDependency_field_number: case genid.FileDescriptorProto_PublicDependency_field_number:
fd.L2.Imports[v].IsPublic = true fd.L2.Imports[v].IsPublic = true
case genid.FileDescriptorProto_WeakDependency_field_number:
fd.L2.Imports[v].IsWeak = true
} }
case protowire.BytesType: case protowire.BytesType:
v, m := protowire.ConsumeBytes(b) v, m := protowire.ConsumeBytes(b)
@ -502,8 +495,6 @@ func (fd *Field) unmarshalOptions(b []byte) {
switch num { switch num {
case genid.FieldOptions_Packed_field_number: case genid.FieldOptions_Packed_field_number:
fd.L1.EditionFeatures.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: case genid.FieldOptions_Lazy_field_number:
fd.L1.IsLazy = protowire.DecodeBool(v) fd.L1.IsLazy = protowire.DecodeBool(v)
case FieldOptions_EnforceUTF8: case FieldOptions_EnforceUTF8:

View File

@ -32,6 +32,10 @@ func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
v, m := protowire.ConsumeVarint(b) v, m := protowire.ConsumeVarint(b)
b = b[m:] b = b[m:]
parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v) parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
case genid.GoFeatures_ApiLevel_field_number:
v, m := protowire.ConsumeVarint(b)
b = b[m:]
parent.APILevel = int(v)
case genid.GoFeatures_StripEnumPrefix_field_number: case genid.GoFeatures_StripEnumPrefix_field_number:
v, m := protowire.ConsumeVarint(b) v, m := protowire.ConsumeVarint(b)
b = b[m:] b = b[m:]
@ -65,6 +69,9 @@ func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value
case genid.FeatureSet_JsonFormat_field_number: case genid.FeatureSet_JsonFormat_field_number:
parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value
case genid.FeatureSet_EnforceNamingStyle_field_number:
// EnforceNamingStyle is enforced in protoc, languages other than C++
// are not supposed to do anything with this feature.
default: default:
panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num)) panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
} }

View File

@ -63,7 +63,7 @@ type Builder struct {
// message declarations in "flattened ordering". // message declarations in "flattened ordering".
// //
// Dependencies are Go types for enums or messages referenced by // Dependencies are Go types for enums or messages referenced by
// message fields (excluding weak fields), for parent extended messages of // message fields, for parent extended messages of
// extension fields, for enums or messages referenced by extension fields, // extension fields, for enums or messages referenced by extension fields,
// and for input and output messages referenced by service methods. // and for input and output messages referenced by service methods.
// Dependencies must come after declarations, but the ordering of // Dependencies must come after declarations, but the ordering of

View File

@ -6,7 +6,7 @@
package flags package flags
// ProtoLegacy specifies whether to enable support for legacy functionality // ProtoLegacy specifies whether to enable support for legacy functionality
// such as MessageSets, weak fields, and various other obscure behavior // such as MessageSets, and various other obscure behavior
// that is necessary to maintain backwards compatibility with proto1 or // that is necessary to maintain backwards compatibility with proto1 or
// the pre-release variants of proto2 and proto3. // the pre-release variants of proto2 and proto3.
// //

View File

@ -1014,6 +1014,7 @@ const (
FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation" FeatureSet_Utf8Validation_field_name protoreflect.Name = "utf8_validation"
FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding" FeatureSet_MessageEncoding_field_name protoreflect.Name = "message_encoding"
FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format" FeatureSet_JsonFormat_field_name protoreflect.Name = "json_format"
FeatureSet_EnforceNamingStyle_field_name protoreflect.Name = "enforce_naming_style"
FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence" FeatureSet_FieldPresence_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.field_presence"
FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type" FeatureSet_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enum_type"
@ -1021,6 +1022,7 @@ const (
FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation" FeatureSet_Utf8Validation_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation"
FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding" FeatureSet_MessageEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding"
FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format" FeatureSet_JsonFormat_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.json_format"
FeatureSet_EnforceNamingStyle_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style"
) )
// Field numbers for google.protobuf.FeatureSet. // Field numbers for google.protobuf.FeatureSet.
@ -1031,6 +1033,7 @@ const (
FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4 FeatureSet_Utf8Validation_field_number protoreflect.FieldNumber = 4
FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5 FeatureSet_MessageEncoding_field_number protoreflect.FieldNumber = 5
FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6 FeatureSet_JsonFormat_field_number protoreflect.FieldNumber = 6
FeatureSet_EnforceNamingStyle_field_number protoreflect.FieldNumber = 7
) )
// Full and short names for google.protobuf.FeatureSet.FieldPresence. // Full and short names for google.protobuf.FeatureSet.FieldPresence.
@ -1112,6 +1115,19 @@ const (
FeatureSet_LEGACY_BEST_EFFORT_enum_value = 2 FeatureSet_LEGACY_BEST_EFFORT_enum_value = 2
) )
// Full and short names for google.protobuf.FeatureSet.EnforceNamingStyle.
const (
FeatureSet_EnforceNamingStyle_enum_fullname = "google.protobuf.FeatureSet.EnforceNamingStyle"
FeatureSet_EnforceNamingStyle_enum_name = "EnforceNamingStyle"
)
// Enum values for google.protobuf.FeatureSet.EnforceNamingStyle.
const (
FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN_enum_value = 0
FeatureSet_STYLE2024_enum_value = 1
FeatureSet_STYLE_LEGACY_enum_value = 2
)
// Names for google.protobuf.FeatureSetDefaults. // Names for google.protobuf.FeatureSetDefaults.
const ( const (
FeatureSetDefaults_message_name protoreflect.Name = "FeatureSetDefaults" FeatureSetDefaults_message_name protoreflect.Name = "FeatureSetDefaults"

View File

@ -21,18 +21,35 @@ const (
// Field names for pb.GoFeatures. // Field names for pb.GoFeatures.
const ( const (
GoFeatures_LegacyUnmarshalJsonEnum_field_name protoreflect.Name = "legacy_unmarshal_json_enum" GoFeatures_LegacyUnmarshalJsonEnum_field_name protoreflect.Name = "legacy_unmarshal_json_enum"
GoFeatures_ApiLevel_field_name protoreflect.Name = "api_level"
GoFeatures_StripEnumPrefix_field_name protoreflect.Name = "strip_enum_prefix" GoFeatures_StripEnumPrefix_field_name protoreflect.Name = "strip_enum_prefix"
GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "pb.GoFeatures.legacy_unmarshal_json_enum" GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "pb.GoFeatures.legacy_unmarshal_json_enum"
GoFeatures_ApiLevel_field_fullname protoreflect.FullName = "pb.GoFeatures.api_level"
GoFeatures_StripEnumPrefix_field_fullname protoreflect.FullName = "pb.GoFeatures.strip_enum_prefix" GoFeatures_StripEnumPrefix_field_fullname protoreflect.FullName = "pb.GoFeatures.strip_enum_prefix"
) )
// Field numbers for pb.GoFeatures. // Field numbers for pb.GoFeatures.
const ( const (
GoFeatures_LegacyUnmarshalJsonEnum_field_number protoreflect.FieldNumber = 1 GoFeatures_LegacyUnmarshalJsonEnum_field_number protoreflect.FieldNumber = 1
GoFeatures_ApiLevel_field_number protoreflect.FieldNumber = 2
GoFeatures_StripEnumPrefix_field_number protoreflect.FieldNumber = 3 GoFeatures_StripEnumPrefix_field_number protoreflect.FieldNumber = 3
) )
// Full and short names for pb.GoFeatures.APILevel.
const (
GoFeatures_APILevel_enum_fullname = "pb.GoFeatures.APILevel"
GoFeatures_APILevel_enum_name = "APILevel"
)
// Enum values for pb.GoFeatures.APILevel.
const (
GoFeatures_API_LEVEL_UNSPECIFIED_enum_value = 0
GoFeatures_API_OPEN_enum_value = 1
GoFeatures_API_HYBRID_enum_value = 2
GoFeatures_API_OPAQUE_enum_value = 3
)
// Full and short names for pb.GoFeatures.StripEnumPrefix. // Full and short names for pb.GoFeatures.StripEnumPrefix.
const ( const (
GoFeatures_StripEnumPrefix_enum_fullname = "pb.GoFeatures.StripEnumPrefix" GoFeatures_StripEnumPrefix_enum_fullname = "pb.GoFeatures.StripEnumPrefix"

View File

@ -11,15 +11,10 @@ const (
SizeCache_goname = "sizeCache" SizeCache_goname = "sizeCache"
SizeCacheA_goname = "XXX_sizecache" SizeCacheA_goname = "XXX_sizecache"
WeakFields_goname = "weakFields"
WeakFieldsA_goname = "XXX_weak"
UnknownFields_goname = "unknownFields" UnknownFields_goname = "unknownFields"
UnknownFieldsA_goname = "XXX_unrecognized" UnknownFieldsA_goname = "XXX_unrecognized"
ExtensionFields_goname = "extensionFields" ExtensionFields_goname = "extensionFields"
ExtensionFieldsA_goname = "XXX_InternalExtensions" ExtensionFieldsA_goname = "XXX_InternalExtensions"
ExtensionFieldsB_goname = "XXX_extensions" ExtensionFieldsB_goname = "XXX_extensions"
WeakFieldPrefix_goname = "XXX_weak_"
) )

View File

@ -0,0 +1,12 @@
// 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 genid
const (
NoUnkeyedLiteral_goname = "noUnkeyedLiteral"
NoUnkeyedLiteralA_goname = "XXX_NoUnkeyedLiteral"
BuilderSuffix_goname = "_builder"
)

View File

@ -0,0 +1,128 @@
// 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 (
"strconv"
"sync/atomic"
"unsafe"
"google.golang.org/protobuf/reflect/protoreflect"
)
func (Export) UnmarshalField(msg any, fieldNum int32) {
UnmarshalField(msg.(protoreflect.ProtoMessage).ProtoReflect(), protoreflect.FieldNumber(fieldNum))
}
// Present checks the presence set for a certain field number (zero
// based, ordered by appearance in original proto file). part is
// a pointer to the correct element in the bitmask array, num is the
// field number unaltered. Example (field number 70 -> part =
// &m.XXX_presence[1], num = 70)
func (Export) Present(part *uint32, num uint32) bool {
// This hook will read an unprotected shadow presence set if
// we're unning under the race detector
raceDetectHookPresent(part, num)
return atomic.LoadUint32(part)&(1<<(num%32)) > 0
}
// SetPresent adds a field to the presence set. part is a pointer to
// the relevant element in the array and num is the field number
// unaltered. size is the number of fields in the protocol
// buffer.
func (Export) SetPresent(part *uint32, num uint32, size uint32) {
// This hook will mutate an unprotected shadow presence set if
// we're running under the race detector
raceDetectHookSetPresent(part, num, presenceSize(size))
for {
old := atomic.LoadUint32(part)
if atomic.CompareAndSwapUint32(part, old, old|(1<<(num%32))) {
return
}
}
}
// SetPresentNonAtomic is like SetPresent, but operates non-atomically.
// It is meant for use by builder methods, where the message is known not
// to be accessible yet by other goroutines.
func (Export) SetPresentNonAtomic(part *uint32, num uint32, size uint32) {
// This hook will mutate an unprotected shadow presence set if
// we're running under the race detector
raceDetectHookSetPresent(part, num, presenceSize(size))
*part |= 1 << (num % 32)
}
// ClearPresence removes a field from the presence set. part is a
// pointer to the relevant element in the presence array and num is
// the field number unaltered.
func (Export) ClearPresent(part *uint32, num uint32) {
// This hook will mutate an unprotected shadow presence set if
// we're running under the race detector
raceDetectHookClearPresent(part, num)
for {
old := atomic.LoadUint32(part)
if atomic.CompareAndSwapUint32(part, old, old&^(1<<(num%32))) {
return
}
}
}
// interfaceToPointer takes a pointer to an empty interface whose value is a
// pointer type, and converts it into a "pointer" that points to the same
// target
func interfaceToPointer(i *any) pointer {
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
}
func (p pointer) atomicGetPointer() pointer {
return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))}
}
func (p pointer) atomicSetPointer(q pointer) {
atomic.StorePointer((*unsafe.Pointer)(p.p), q.p)
}
// AtomicCheckPointerIsNil takes an interface (which is a pointer to a
// pointer) and returns true if the pointed-to pointer is nil (using an
// atomic load). This function is inlineable and, on x86, just becomes a
// simple load and compare.
func (Export) AtomicCheckPointerIsNil(ptr any) bool {
return interfaceToPointer(&ptr).atomicGetPointer().IsNil()
}
// AtomicSetPointer takes two interfaces (first is a pointer to a pointer,
// second is a pointer) and atomically sets the second pointer into location
// referenced by first pointer. Unfortunately, atomicSetPointer() does not inline
// (even on x86), so this does not become a simple store on x86.
func (Export) AtomicSetPointer(dstPtr, valPtr any) {
interfaceToPointer(&dstPtr).atomicSetPointer(interfaceToPointer(&valPtr))
}
// AtomicLoadPointer loads the pointer at the location pointed at by src,
// and stores that pointer value into the location pointed at by dst.
func (Export) AtomicLoadPointer(ptr Pointer, dst Pointer) {
*(*unsafe.Pointer)(unsafe.Pointer(dst)) = atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(ptr)))
}
// AtomicInitializePointer makes ptr and dst point to the same value.
//
// If *ptr is a nil pointer, it sets *ptr = *dst.
//
// If *ptr is a non-nil pointer, it sets *dst = *ptr.
func (Export) AtomicInitializePointer(ptr Pointer, dst Pointer) {
if !atomic.CompareAndSwapPointer((*unsafe.Pointer)(ptr), unsafe.Pointer(nil), *(*unsafe.Pointer)(dst)) {
*(*unsafe.Pointer)(unsafe.Pointer(dst)) = atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(ptr)))
}
}
// MessageFieldStringOf returns the field formatted as a string,
// either as the field name if resolvable otherwise as a decimal string.
func (Export) MessageFieldStringOf(md protoreflect.MessageDescriptor, n protoreflect.FieldNumber) string {
fd := md.Fields().ByNumber(n)
if fd != nil {
return string(fd.Name())
}
return strconv.Itoa(int(n))
}

View File

@ -0,0 +1,34 @@
// 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.
//go:build !race
package impl
// There is no additional data as we're not running under race detector.
type RaceDetectHookData struct{}
// Empty stubs for when not using the race detector. Calls to these from index.go should be optimized away.
func (presence) raceDetectHookPresent(num uint32) {}
func (presence) raceDetectHookSetPresent(num uint32, size presenceSize) {}
func (presence) raceDetectHookClearPresent(num uint32) {}
func (presence) raceDetectHookAllocAndCopy(src presence) {}
// raceDetectHookPresent is called by the generated file interface
// (*proto.internalFuncs) Present to optionally read an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookPresent(field *uint32, num uint32) {}
// raceDetectHookSetPresent is called by the generated file interface
// (*proto.internalFuncs) SetPresent to optionally write an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookSetPresent(field *uint32, num uint32, size presenceSize) {}
// raceDetectHookClearPresent is called by the generated file interface
// (*proto.internalFuncs) ClearPresent to optionally write an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookClearPresent(field *uint32, num uint32) {}

View File

@ -0,0 +1,126 @@
// 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.
//go:build race
package impl
// When running under race detector, we add a presence map of bytes, that we can access
// in the hook functions so that we trigger the race detection whenever we have concurrent
// Read-Writes or Write-Writes. The race detector does not otherwise detect invalid concurrent
// access to lazy fields as all updates of bitmaps and pointers are done using atomic operations.
type RaceDetectHookData struct {
shadowPresence *[]byte
}
// Hooks for presence bitmap operations that allocate, read and write the shadowPresence
// using non-atomic operations.
func (data *RaceDetectHookData) raceDetectHookAlloc(size presenceSize) {
sp := make([]byte, size)
atomicStoreShadowPresence(&data.shadowPresence, &sp)
}
func (p presence) raceDetectHookPresent(num uint32) {
data := p.toRaceDetectData()
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp != nil {
_ = (*sp)[num]
}
}
func (p presence) raceDetectHookSetPresent(num uint32, size presenceSize) {
data := p.toRaceDetectData()
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp == nil {
data.raceDetectHookAlloc(size)
sp = atomicLoadShadowPresence(&data.shadowPresence)
}
(*sp)[num] = 1
}
func (p presence) raceDetectHookClearPresent(num uint32) {
data := p.toRaceDetectData()
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp != nil {
(*sp)[num] = 0
}
}
// raceDetectHookAllocAndCopy allocates a new shadowPresence slice at lazy and copies
// shadowPresence bytes from src to lazy.
func (p presence) raceDetectHookAllocAndCopy(q presence) {
sData := q.toRaceDetectData()
dData := p.toRaceDetectData()
if sData == nil {
return
}
srcSp := atomicLoadShadowPresence(&sData.shadowPresence)
if srcSp == nil {
atomicStoreShadowPresence(&dData.shadowPresence, nil)
return
}
n := len(*srcSp)
dSlice := make([]byte, n)
atomicStoreShadowPresence(&dData.shadowPresence, &dSlice)
for i := 0; i < n; i++ {
dSlice[i] = (*srcSp)[i]
}
}
// raceDetectHookPresent is called by the generated file interface
// (*proto.internalFuncs) Present to optionally read an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookPresent(field *uint32, num uint32) {
data := findPointerToRaceDetectData(field, num)
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp != nil {
_ = (*sp)[num]
}
}
// raceDetectHookSetPresent is called by the generated file interface
// (*proto.internalFuncs) SetPresent to optionally write an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookSetPresent(field *uint32, num uint32, size presenceSize) {
data := findPointerToRaceDetectData(field, num)
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp == nil {
data.raceDetectHookAlloc(size)
sp = atomicLoadShadowPresence(&data.shadowPresence)
}
(*sp)[num] = 1
}
// raceDetectHookClearPresent is called by the generated file interface
// (*proto.internalFuncs) ClearPresent to optionally write an unprotected
// shadow bitmap when race detection is enabled. In regular code it is
// a noop.
func raceDetectHookClearPresent(field *uint32, num uint32) {
data := findPointerToRaceDetectData(field, num)
if data == nil {
return
}
sp := atomicLoadShadowPresence(&data.shadowPresence)
if sp != nil {
(*sp)[num] = 0
}
}

View File

@ -35,6 +35,12 @@ func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
} }
return nil return nil
} }
var presence presence
if mi.presenceOffset.IsValid() {
presence = p.Apply(mi.presenceOffset).PresenceInfo()
}
if mi.extensionOffset.IsValid() { if mi.extensionOffset.IsValid() {
e := p.Apply(mi.extensionOffset).Extensions() e := p.Apply(mi.extensionOffset).Extensions()
if err := mi.isInitExtensions(e); err != nil { if err := mi.isInitExtensions(e); err != nil {
@ -45,6 +51,33 @@ func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
if !f.isRequired && f.funcs.isInit == nil { if !f.isRequired && f.funcs.isInit == nil {
continue continue
} }
if f.presenceIndex != noPresence {
if !presence.Present(f.presenceIndex) {
if f.isRequired {
return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
}
continue
}
if f.funcs.isInit != nil {
f.mi.init()
if f.mi.needsInitCheck {
if f.isLazy && p.Apply(f.offset).AtomicGetPointer().IsNil() {
lazy := *p.Apply(mi.lazyOffset).LazyInfoPtr()
if !lazy.AllowedPartial() {
// Nothing to see here, it was checked on unmarshal
continue
}
mi.lazyUnmarshal(p, f.num)
}
if err := f.funcs.isInit(p.Apply(f.offset), f); err != nil {
return err
}
}
}
continue
}
fptr := p.Apply(f.offset) fptr := p.Apply(f.offset)
if f.isPointer && fptr.Elem().IsNil() { if f.isPointer && fptr.Elem().IsNil() {
if f.isRequired { if f.isRequired {

View File

@ -5,15 +5,12 @@
package impl package impl
import ( import (
"fmt"
"reflect" "reflect"
"sync"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
@ -121,78 +118,6 @@ func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si
} }
} }
func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs {
var once sync.Once
var messageType protoreflect.MessageType
lazyInit := func() {
once.Do(func() {
messageName := fd.Message().FullName()
messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
})
}
return pointerCoderFuncs{
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
m, ok := p.WeakFields().get(f.num)
if !ok {
return 0
}
lazyInit()
if messageType == nil {
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
}
return sizeMessage(m, f.tagsize, opts)
},
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
m, ok := p.WeakFields().get(f.num)
if !ok {
return b, nil
}
lazyInit()
if messageType == nil {
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
}
return appendMessage(b, m, f.wiretag, opts)
},
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
fs := p.WeakFields()
m, ok := fs.get(f.num)
if !ok {
lazyInit()
if messageType == nil {
return unmarshalOutput{}, errUnknown
}
m = messageType.New().Interface()
fs.set(f.num, m)
}
return consumeMessage(b, m, wtyp, opts)
},
isInit: func(p pointer, f *coderFieldInfo) error {
m, ok := p.WeakFields().get(f.num)
if !ok {
return nil
}
return proto.CheckInitialized(m)
},
merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
sm, ok := src.WeakFields().get(f.num)
if !ok {
return
}
dm, ok := dst.WeakFields().get(f.num)
if !ok {
lazyInit()
if messageType == nil {
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
}
dm = messageType.New().Interface()
dst.WeakFields().set(f.num, dm)
}
opts.Merge(dm, sm)
},
}
}
func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
if mi := getMessageInfo(ft); mi != nil { if mi := getMessageInfo(ft); mi != nil {
funcs := pointerCoderFuncs{ funcs := pointerCoderFuncs{

View File

@ -0,0 +1,264 @@
// 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 (
"fmt"
"reflect"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/reflect/protoreflect"
)
func makeOpaqueMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
mi := getMessageInfo(ft)
if mi == nil {
panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", fd.FullName(), ft))
}
switch fd.Kind() {
case protoreflect.MessageKind:
return mi, pointerCoderFuncs{
size: sizeOpaqueMessage,
marshal: appendOpaqueMessage,
unmarshal: consumeOpaqueMessage,
isInit: isInitOpaqueMessage,
merge: mergeOpaqueMessage,
}
case protoreflect.GroupKind:
return mi, pointerCoderFuncs{
size: sizeOpaqueGroup,
marshal: appendOpaqueGroup,
unmarshal: consumeOpaqueGroup,
isInit: isInitOpaqueMessage,
merge: mergeOpaqueMessage,
}
}
panic("unexpected field kind")
}
func sizeOpaqueMessage(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
return protowire.SizeBytes(f.mi.sizePointer(p.AtomicGetPointer(), opts)) + f.tagsize
}
func appendOpaqueMessage(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
mp := p.AtomicGetPointer()
calculatedSize := f.mi.sizePointer(mp, opts)
b = protowire.AppendVarint(b, f.wiretag)
b = protowire.AppendVarint(b, uint64(calculatedSize))
before := len(b)
b, err := f.mi.marshalAppendPointer(b, mp, opts)
if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
}
return b, err
}
func consumeOpaqueMessage(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.BytesType {
return out, errUnknown
}
v, n := protowire.ConsumeBytes(b)
if n < 0 {
return out, errDecode
}
mp := p.AtomicGetPointer()
if mp.IsNil() {
mp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
}
o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
if err != nil {
return out, err
}
out.n = n
out.initialized = o.initialized
return out, nil
}
func isInitOpaqueMessage(p pointer, f *coderFieldInfo) error {
mp := p.AtomicGetPointer()
if mp.IsNil() {
return nil
}
return f.mi.checkInitializedPointer(mp)
}
func mergeOpaqueMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
dstmp := dst.AtomicGetPointer()
if dstmp.IsNil() {
dstmp = dst.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
}
f.mi.mergePointer(dstmp, src.AtomicGetPointer(), opts)
}
func sizeOpaqueGroup(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
return 2*f.tagsize + f.mi.sizePointer(p.AtomicGetPointer(), opts)
}
func appendOpaqueGroup(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
b = protowire.AppendVarint(b, f.wiretag) // start group
b, err := f.mi.marshalAppendPointer(b, p.AtomicGetPointer(), opts)
b = protowire.AppendVarint(b, f.wiretag+1) // end group
return b, err
}
func consumeOpaqueGroup(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.StartGroupType {
return out, errUnknown
}
mp := p.AtomicGetPointer()
if mp.IsNil() {
mp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
}
o, e := f.mi.unmarshalPointer(b, mp, f.num, opts)
return o, e
}
func makeOpaqueRepeatedMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid field: %v: unsupported type for opaque repeated message: %v", fd.FullName(), ft))
}
mt := ft.Elem().Elem() // *[]*T -> *T
mi := getMessageInfo(mt)
if mi == nil {
panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", fd.FullName(), mt))
}
switch fd.Kind() {
case protoreflect.MessageKind:
return mi, pointerCoderFuncs{
size: sizeOpaqueMessageSlice,
marshal: appendOpaqueMessageSlice,
unmarshal: consumeOpaqueMessageSlice,
isInit: isInitOpaqueMessageSlice,
merge: mergeOpaqueMessageSlice,
}
case protoreflect.GroupKind:
return mi, pointerCoderFuncs{
size: sizeOpaqueGroupSlice,
marshal: appendOpaqueGroupSlice,
unmarshal: consumeOpaqueGroupSlice,
isInit: isInitOpaqueMessageSlice,
merge: mergeOpaqueMessageSlice,
}
}
panic("unexpected field kind")
}
func sizeOpaqueMessageSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
s := p.AtomicGetPointer().PointerSlice()
n := 0
for _, v := range s {
n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
}
return n
}
func appendOpaqueMessageSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
s := p.AtomicGetPointer().PointerSlice()
var err error
for _, v := range s {
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
}
func consumeOpaqueMessageSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.BytesType {
return out, errUnknown
}
v, n := protowire.ConsumeBytes(b)
if n < 0 {
return out, errDecode
}
mp := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))
o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
if err != nil {
return out, err
}
sp := p.AtomicGetPointer()
if sp.IsNil() {
sp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem())))
}
sp.AppendPointerSlice(mp)
out.n = n
out.initialized = o.initialized
return out, nil
}
func isInitOpaqueMessageSlice(p pointer, f *coderFieldInfo) error {
sp := p.AtomicGetPointer()
if sp.IsNil() {
return nil
}
s := sp.PointerSlice()
for _, v := range s {
if err := f.mi.checkInitializedPointer(v); err != nil {
return err
}
}
return nil
}
func mergeOpaqueMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
ds := dst.AtomicGetPointer()
if ds.IsNil() {
ds = dst.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem())))
}
for _, sp := range src.AtomicGetPointer().PointerSlice() {
dm := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))
f.mi.mergePointer(dm, sp, opts)
ds.AppendPointerSlice(dm)
}
}
func sizeOpaqueGroupSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
s := p.AtomicGetPointer().PointerSlice()
n := 0
for _, v := range s {
n += 2*f.tagsize + f.mi.sizePointer(v, opts)
}
return n
}
func appendOpaqueGroupSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
s := p.AtomicGetPointer().PointerSlice()
var err error
for _, v := range s {
b = protowire.AppendVarint(b, f.wiretag) // start group
b, err = f.mi.marshalAppendPointer(b, v, opts)
if err != nil {
return b, err
}
b = protowire.AppendVarint(b, f.wiretag+1) // end group
}
return b, nil
}
func consumeOpaqueGroupSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
if wtyp != protowire.StartGroupType {
return out, errUnknown
}
mp := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))
out, err = f.mi.unmarshalPointer(b, mp, f.num, opts)
if err != nil {
return out, err
}
sp := p.AtomicGetPointer()
if sp.IsNil() {
sp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem())))
}
sp.AppendPointerSlice(mp)
return out, err
}

View File

@ -94,7 +94,7 @@ func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalO
return 0 return 0
} }
n := 0 n := 0
iter := mapRange(mapv) iter := mapv.MapRange()
for iter.Next() { for iter.Next() {
key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey() key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey()
keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts) keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
@ -281,7 +281,7 @@ func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, o
if opts.Deterministic() { if opts.Deterministic() {
return appendMapDeterministic(b, mapv, mapi, f, opts) return appendMapDeterministic(b, mapv, mapi, f, opts)
} }
iter := mapRange(mapv) iter := mapv.MapRange()
for iter.Next() { for iter.Next() {
var err error var err error
b = protowire.AppendVarint(b, f.wiretag) b = protowire.AppendVarint(b, f.wiretag)
@ -328,7 +328,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error {
if !mi.needsInitCheck { if !mi.needsInitCheck {
return nil return nil
} }
iter := mapRange(mapv) iter := mapv.MapRange()
for iter.Next() { for iter.Next() {
val := pointerOfValue(iter.Value()) val := pointerOfValue(iter.Value())
if err := mi.checkInitializedPointer(val); err != nil { if err := mi.checkInitializedPointer(val); err != nil {
@ -336,7 +336,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error {
} }
} }
} else { } else {
iter := mapRange(mapv) iter := mapv.MapRange()
for iter.Next() { for iter.Next() {
val := mapi.conv.valConv.PBValueOf(iter.Value()) val := mapi.conv.valConv.PBValueOf(iter.Value())
if err := mapi.valFuncs.isInit(val); err != nil { if err := mapi.valFuncs.isInit(val); err != nil {
@ -356,7 +356,7 @@ func mergeMap(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
if dstm.IsNil() { if dstm.IsNil() {
dstm.Set(reflect.MakeMap(f.ft)) dstm.Set(reflect.MakeMap(f.ft))
} }
iter := mapRange(srcm) iter := srcm.MapRange()
for iter.Next() { for iter.Next() {
dstm.SetMapIndex(iter.Key(), iter.Value()) dstm.SetMapIndex(iter.Key(), iter.Value())
} }
@ -371,7 +371,7 @@ func mergeMapOfBytes(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
if dstm.IsNil() { if dstm.IsNil() {
dstm.Set(reflect.MakeMap(f.ft)) dstm.Set(reflect.MakeMap(f.ft))
} }
iter := mapRange(srcm) iter := srcm.MapRange()
for iter.Next() { for iter.Next() {
dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...))) dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...)))
} }
@ -386,7 +386,7 @@ func mergeMapOfMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
if dstm.IsNil() { if dstm.IsNil() {
dstm.Set(reflect.MakeMap(f.ft)) dstm.Set(reflect.MakeMap(f.ft))
} }
iter := mapRange(srcm) iter := srcm.MapRange()
for iter.Next() { for iter.Next() {
val := reflect.New(f.ft.Elem().Elem()) val := reflect.New(f.ft.Elem().Elem())
if f.mi != nil { if f.mi != nil {

View File

@ -1,38 +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 !go1.12
// +build !go1.12
package impl
import "reflect"
type mapIter struct {
v reflect.Value
keys []reflect.Value
}
// mapRange provides a less-efficient equivalent to
// the Go 1.12 reflect.Value.MapRange method.
func mapRange(v reflect.Value) *mapIter {
return &mapIter{v: v}
}
func (i *mapIter) Next() bool {
if i.keys == nil {
i.keys = i.v.MapKeys()
} else {
i.keys = i.keys[1:]
}
return len(i.keys) > 0
}
func (i *mapIter) Key() reflect.Value {
return i.keys[0]
}
func (i *mapIter) Value() reflect.Value {
return i.v.MapIndex(i.keys[0])
}

View File

@ -1,12 +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 go1.12
// +build go1.12
package impl
import "reflect"
func mapRange(v reflect.Value) *reflect.MapIter { return v.MapRange() }

View File

@ -32,6 +32,10 @@ type coderMessageInfo struct {
needsInitCheck bool needsInitCheck bool
isMessageSet bool isMessageSet bool
numRequiredFields uint8 numRequiredFields uint8
lazyOffset offset
presenceOffset offset
presenceSize presenceSize
} }
type coderFieldInfo struct { type coderFieldInfo struct {
@ -45,12 +49,19 @@ type coderFieldInfo struct {
tagsize int // size of the varint-encoded tag tagsize int // size of the varint-encoded tag
isPointer bool // true if IsNil may be called on the struct field isPointer bool // true if IsNil may be called on the struct field
isRequired bool // true if field is required isRequired bool // true if field is required
isLazy bool
presenceIndex uint32
} }
const noPresence = 0xffffffff
func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
mi.sizecacheOffset = invalidOffset mi.sizecacheOffset = invalidOffset
mi.unknownOffset = invalidOffset mi.unknownOffset = invalidOffset
mi.extensionOffset = invalidOffset mi.extensionOffset = invalidOffset
mi.lazyOffset = invalidOffset
mi.presenceOffset = si.presenceOffset
if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType { if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType {
mi.sizecacheOffset = si.sizecacheOffset mi.sizecacheOffset = si.sizecacheOffset
@ -107,12 +118,9 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
}, },
} }
case isOneof: case isOneof:
fieldOffset = offsetOf(fs, mi.Exporter) fieldOffset = offsetOf(fs)
case fd.IsWeak():
fieldOffset = si.weakOffset
funcs = makeWeakMessageFieldCoder(fd)
default: default:
fieldOffset = offsetOf(fs, mi.Exporter) fieldOffset = offsetOf(fs)
childMessage, funcs = fieldCoder(fd, ft) childMessage, funcs = fieldCoder(fd, ft)
} }
cf := &preallocFields[i] cf := &preallocFields[i]
@ -127,6 +135,8 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
validation: newFieldValidationInfo(mi, si, fd, ft), validation: newFieldValidationInfo(mi, si, fd, ft),
isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(), isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(),
isRequired: fd.Cardinality() == protoreflect.Required, isRequired: fd.Cardinality() == protoreflect.Required,
presenceIndex: noPresence,
} }
mi.orderedCoderFields = append(mi.orderedCoderFields, cf) mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
mi.coderFields[cf.num] = cf mi.coderFields[cf.num] = cf

View File

@ -0,0 +1,153 @@
// 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 (
"fmt"
"reflect"
"sort"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface"
)
func (mi *MessageInfo) makeOpaqueCoderMethods(t reflect.Type, si opaqueStructInfo) {
mi.sizecacheOffset = si.sizecacheOffset
mi.unknownOffset = si.unknownOffset
mi.unknownPtrKind = si.unknownType.Kind() == reflect.Ptr
mi.extensionOffset = si.extensionOffset
mi.lazyOffset = si.lazyOffset
mi.presenceOffset = si.presenceOffset
mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
fields := mi.Desc.Fields()
for i := 0; i < fields.Len(); i++ {
fd := fields.Get(i)
fs := si.fieldsByNumber[fd.Number()]
if fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic() {
fs = si.oneofsByName[fd.ContainingOneof().Name()]
}
ft := fs.Type
var wiretag uint64
if !fd.IsPacked() {
wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
} else {
wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType)
}
var fieldOffset offset
var funcs pointerCoderFuncs
var childMessage *MessageInfo
switch {
case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
fieldOffset = offsetOf(fs)
case fd.Message() != nil && !fd.IsMap():
fieldOffset = offsetOf(fs)
if fd.IsList() {
childMessage, funcs = makeOpaqueRepeatedMessageFieldCoder(fd, ft)
} else {
childMessage, funcs = makeOpaqueMessageFieldCoder(fd, ft)
}
default:
fieldOffset = offsetOf(fs)
childMessage, funcs = fieldCoder(fd, ft)
}
cf := &coderFieldInfo{
num: fd.Number(),
offset: fieldOffset,
wiretag: wiretag,
ft: ft,
tagsize: protowire.SizeVarint(wiretag),
funcs: funcs,
mi: childMessage,
validation: newFieldValidationInfo(mi, si.structInfo, fd, ft),
isPointer: (fd.Cardinality() == protoreflect.Repeated ||
fd.Kind() == protoreflect.MessageKind ||
fd.Kind() == protoreflect.GroupKind),
isRequired: fd.Cardinality() == protoreflect.Required,
presenceIndex: noPresence,
}
// TODO: Use presence for all fields.
//
// In some cases, such as maps, presence means only "might be set" rather
// than "is definitely set", but every field should have a presence bit to
// permit us to skip over definitely-unset fields at marshal time.
var hasPresence bool
hasPresence, cf.isLazy = usePresenceForField(si, fd)
if hasPresence {
cf.presenceIndex, mi.presenceSize = presenceIndex(mi.Desc, fd)
}
mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
mi.coderFields[cf.num] = cf
}
for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
if od := oneofs.Get(i); !od.IsSynthetic() {
mi.initOneofFieldCoders(od, si.structInfo)
}
}
if messageset.IsMessageSet(mi.Desc) {
if !mi.extensionOffset.IsValid() {
panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
}
if !mi.unknownOffset.IsValid() {
panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
}
mi.isMessageSet = true
}
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
})
var maxDense protoreflect.FieldNumber
for _, cf := range mi.orderedCoderFields {
if cf.num >= 16 && cf.num >= 2*maxDense {
break
}
maxDense = cf.num
}
mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
for _, cf := range mi.orderedCoderFields {
if int(cf.num) > len(mi.denseCoderFields) {
break
}
mi.denseCoderFields[cf.num] = cf
}
// To preserve compatibility with historic wire output, marshal oneofs last.
if mi.Desc.Oneofs().Len() > 0 {
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
fi := fields.ByNumber(mi.orderedCoderFields[i].num)
fj := fields.ByNumber(mi.orderedCoderFields[j].num)
return order.LegacyFieldOrder(fi, fj)
})
}
mi.needsInitCheck = needsInitCheck(mi.Desc)
if mi.methods.Marshal == nil && mi.methods.Size == nil {
mi.methods.Flags |= piface.SupportMarshalDeterministic
mi.methods.Marshal = mi.marshal
mi.methods.Size = mi.size
}
if mi.methods.Unmarshal == nil {
mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
mi.methods.Unmarshal = mi.unmarshal
}
if mi.methods.CheckInitialized == nil {
mi.methods.CheckInitialized = mi.checkInitialized
}
if mi.methods.Merge == nil {
mi.methods.Merge = mi.merge
}
if mi.methods.Equal == nil {
mi.methods.Equal = equal
}
}

View File

@ -101,7 +101,7 @@ func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value {
return v return v
} }
func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) {
iter := mapRange(ms.v) iter := ms.v.MapRange()
for iter.Next() { for iter.Next() {
k := ms.keyConv.PBValueOf(iter.Key()).MapKey() k := ms.keyConv.PBValueOf(iter.Key()).MapKey()
v := ms.valConv.PBValueOf(iter.Value()) v := ms.valConv.PBValueOf(iter.Value())

View File

@ -34,6 +34,8 @@ func (o unmarshalOptions) Options() proto.UnmarshalOptions {
AllowPartial: true, AllowPartial: true,
DiscardUnknown: o.DiscardUnknown(), DiscardUnknown: o.DiscardUnknown(),
Resolver: o.resolver, Resolver: o.resolver,
NoLazyDecoding: o.NoLazyDecoding(),
} }
} }
@ -41,13 +43,26 @@ func (o unmarshalOptions) DiscardUnknown() bool {
return o.flags&protoiface.UnmarshalDiscardUnknown != 0 return o.flags&protoiface.UnmarshalDiscardUnknown != 0
} }
func (o unmarshalOptions) IsDefault() bool { func (o unmarshalOptions) AliasBuffer() bool { return o.flags&protoiface.UnmarshalAliasBuffer != 0 }
return o.flags == 0 && o.resolver == protoregistry.GlobalTypes func (o unmarshalOptions) Validated() bool { return o.flags&protoiface.UnmarshalValidated != 0 }
func (o unmarshalOptions) NoLazyDecoding() bool {
return o.flags&protoiface.UnmarshalNoLazyDecoding != 0
}
func (o unmarshalOptions) CanBeLazy() bool {
if o.resolver != protoregistry.GlobalTypes {
return false
}
// We ignore the UnmarshalInvalidateSizeCache even though it's not in the default set
return (o.flags & ^(protoiface.UnmarshalAliasBuffer | protoiface.UnmarshalValidated | protoiface.UnmarshalCheckRequired)) == 0
} }
var lazyUnmarshalOptions = unmarshalOptions{ var lazyUnmarshalOptions = unmarshalOptions{
resolver: protoregistry.GlobalTypes, resolver: protoregistry.GlobalTypes,
depth: protowire.DefaultRecursionLimit,
flags: protoiface.UnmarshalAliasBuffer | protoiface.UnmarshalValidated,
depth: protowire.DefaultRecursionLimit,
} }
type unmarshalOutput struct { type unmarshalOutput struct {
@ -94,9 +109,30 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
if flags.ProtoLegacy && mi.isMessageSet { if flags.ProtoLegacy && mi.isMessageSet {
return unmarshalMessageSet(mi, b, p, opts) return unmarshalMessageSet(mi, b, p, opts)
} }
lazyDecoding := LazyEnabled() // default
if opts.NoLazyDecoding() {
lazyDecoding = false // explicitly disabled
}
if mi.lazyOffset.IsValid() && lazyDecoding {
return mi.unmarshalPointerLazy(b, p, groupTag, opts)
}
return mi.unmarshalPointerEager(b, p, groupTag, opts)
}
// unmarshalPointerEager is the message unmarshalling function for all messages that are not lazy.
// The corresponding function for Lazy is in google_lazy.go.
func (mi *MessageInfo) unmarshalPointerEager(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
initialized := true initialized := true
var requiredMask uint64 var requiredMask uint64
var exts *map[int32]ExtensionField var exts *map[int32]ExtensionField
var presence presence
if mi.presenceOffset.IsValid() {
presence = p.Apply(mi.presenceOffset).PresenceInfo()
}
start := len(b) start := len(b)
for len(b) > 0 { for len(b) > 0 {
// Parse the tag (field number and wire type). // Parse the tag (field number and wire type).
@ -154,6 +190,11 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
if f.funcs.isInit != nil && !o.initialized { if f.funcs.isInit != nil && !o.initialized {
initialized = false initialized = false
} }
if f.presenceIndex != noPresence {
presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
}
default: default:
// Possible extension. // Possible extension.
if exts == nil && mi.extensionOffset.IsValid() { if exts == nil && mi.extensionOffset.IsValid() {
@ -222,7 +263,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp p
return out, errUnknown return out, errUnknown
} }
if flags.LazyUnmarshalExtensions { if flags.LazyUnmarshalExtensions {
if opts.IsDefault() && x.canLazy(xt) { if opts.CanBeLazy() && x.canLazy(xt) {
out, valid := skipExtension(b, xi, num, wtyp, opts) out, valid := skipExtension(b, xi, num, wtyp, opts)
switch valid { switch valid {
case ValidationValid: case ValidationValid:
@ -270,6 +311,13 @@ func skipExtension(b []byte, xi *extensionFieldInfo, num protowire.Number, wtyp
if n < 0 { if n < 0 {
return out, ValidationUnknown return out, ValidationUnknown
} }
if opts.Validated() {
out.initialized = true
out.n = n
return out, ValidationValid
}
out, st := xi.validation.mi.validate(v, 0, opts) out, st := xi.validation.mi.validate(v, 0, opts)
out.n = n out.n = n
return out, st return out, st

View File

@ -10,6 +10,7 @@ import (
"sync/atomic" "sync/atomic"
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/protolazy"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
piface "google.golang.org/protobuf/runtime/protoiface" piface "google.golang.org/protobuf/runtime/protoiface"
) )
@ -71,11 +72,39 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int
e := p.Apply(mi.extensionOffset).Extensions() e := p.Apply(mi.extensionOffset).Extensions()
size += mi.sizeExtensions(e, opts) size += mi.sizeExtensions(e, opts)
} }
var lazy **protolazy.XXX_lazyUnmarshalInfo
var presence presence
if mi.presenceOffset.IsValid() {
presence = p.Apply(mi.presenceOffset).PresenceInfo()
if mi.lazyOffset.IsValid() {
lazy = p.Apply(mi.lazyOffset).LazyInfoPtr()
}
}
for _, f := range mi.orderedCoderFields { for _, f := range mi.orderedCoderFields {
if f.funcs.size == nil { if f.funcs.size == nil {
continue continue
} }
fptr := p.Apply(f.offset) fptr := p.Apply(f.offset)
if f.presenceIndex != noPresence {
if !presence.Present(f.presenceIndex) {
continue
}
if f.isLazy && fptr.AtomicGetPointer().IsNil() {
if lazyFields(opts) {
size += (*lazy).SizeField(uint32(f.num))
continue
} else {
mi.lazyUnmarshal(p, f.num)
}
}
size += f.funcs.size(fptr, f, opts)
continue
}
if f.isPointer && fptr.Elem().IsNil() { if f.isPointer && fptr.Elem().IsNil() {
continue continue
} }
@ -134,11 +163,52 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
return b, err return b, err
} }
} }
var lazy **protolazy.XXX_lazyUnmarshalInfo
var presence presence
if mi.presenceOffset.IsValid() {
presence = p.Apply(mi.presenceOffset).PresenceInfo()
if mi.lazyOffset.IsValid() {
lazy = p.Apply(mi.lazyOffset).LazyInfoPtr()
}
}
for _, f := range mi.orderedCoderFields { for _, f := range mi.orderedCoderFields {
if f.funcs.marshal == nil { if f.funcs.marshal == nil {
continue continue
} }
fptr := p.Apply(f.offset) fptr := p.Apply(f.offset)
if f.presenceIndex != noPresence {
if !presence.Present(f.presenceIndex) {
continue
}
if f.isLazy {
// Be careful, this field needs to be read atomically, like for a get
if f.isPointer && fptr.AtomicGetPointer().IsNil() {
if lazyFields(opts) {
b, _ = (*lazy).AppendField(b, uint32(f.num))
continue
} else {
mi.lazyUnmarshal(p, f.num)
}
}
b, err = f.funcs.marshal(b, fptr, f, opts)
if err != nil {
return b, err
}
continue
} else if f.isPointer && fptr.Elem().IsNil() {
continue
}
b, err = f.funcs.marshal(b, fptr, f, opts)
if err != nil {
return b, err
}
continue
}
if f.isPointer && fptr.Elem().IsNil() { if f.isPointer && fptr.Elem().IsNil() {
continue continue
} }
@ -163,6 +233,14 @@ func fullyLazyExtensions(opts marshalOptions) bool {
return opts.flags&piface.MarshalDeterministic == 0 return opts.flags&piface.MarshalDeterministic == 0
} }
// lazyFields returns true if we should attempt to keep fields lazy over size and marshal.
func lazyFields(opts marshalOptions) bool {
// When deterministic marshaling is requested, force an unmarshal for lazy
// fields 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) { func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
if ext == nil { if ext == nil {
return 0 return 0

433
vendor/google.golang.org/protobuf/internal/impl/lazy.go generated vendored Normal file
View File

@ -0,0 +1,433 @@
// 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 (
"fmt"
"math/bits"
"os"
"reflect"
"sort"
"sync/atomic"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/protolazy"
"google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry"
piface "google.golang.org/protobuf/runtime/protoiface"
)
var enableLazy int32 = func() int32 {
if os.Getenv("GOPROTODEBUG") == "nolazy" {
return 0
}
return 1
}()
// EnableLazyUnmarshal enables lazy unmarshaling.
func EnableLazyUnmarshal(enable bool) {
if enable {
atomic.StoreInt32(&enableLazy, 1)
return
}
atomic.StoreInt32(&enableLazy, 0)
}
// LazyEnabled reports whether lazy unmarshalling is currently enabled.
func LazyEnabled() bool {
return atomic.LoadInt32(&enableLazy) != 0
}
// UnmarshalField unmarshals a field in a message.
func UnmarshalField(m interface{}, num protowire.Number) {
switch m := m.(type) {
case *messageState:
m.messageInfo().lazyUnmarshal(m.pointer(), num)
case *messageReflectWrapper:
m.messageInfo().lazyUnmarshal(m.pointer(), num)
default:
panic(fmt.Sprintf("unsupported wrapper type %T", m))
}
}
func (mi *MessageInfo) lazyUnmarshal(p pointer, num protoreflect.FieldNumber) {
var f *coderFieldInfo
if int(num) < len(mi.denseCoderFields) {
f = mi.denseCoderFields[num]
} else {
f = mi.coderFields[num]
}
if f == nil {
panic(fmt.Sprintf("lazyUnmarshal: field info for %v.%v", mi.Desc.FullName(), num))
}
lazy := *p.Apply(mi.lazyOffset).LazyInfoPtr()
start, end, found, _, multipleEntries := lazy.FindFieldInProto(uint32(num))
if !found && multipleEntries == nil {
panic(fmt.Sprintf("lazyUnmarshal: can't find field data for %v.%v", mi.Desc.FullName(), num))
}
// The actual pointer in the message can not be set until the whole struct is filled in, otherwise we will have races.
// Create another pointer and set it atomically, if we won the race and the pointer in the original message is still nil.
fp := pointerOfValue(reflect.New(f.ft))
if multipleEntries != nil {
for _, entry := range multipleEntries {
mi.unmarshalField(lazy.Buffer()[entry.Start:entry.End], fp, f, lazy, lazy.UnmarshalFlags())
}
} else {
mi.unmarshalField(lazy.Buffer()[start:end], fp, f, lazy, lazy.UnmarshalFlags())
}
p.Apply(f.offset).AtomicSetPointerIfNil(fp.Elem())
}
func (mi *MessageInfo) unmarshalField(b []byte, p pointer, f *coderFieldInfo, lazyInfo *protolazy.XXX_lazyUnmarshalInfo, flags piface.UnmarshalInputFlags) error {
opts := lazyUnmarshalOptions
opts.flags |= flags
for len(b) > 0 {
// Parse the tag (field number and wire type).
var tag uint64
if b[0] < 0x80 {
tag = uint64(b[0])
b = b[1:]
} else if len(b) >= 2 && b[1] < 128 {
tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
b = b[2:]
} else {
var n int
tag, n = protowire.ConsumeVarint(b)
if n < 0 {
return errors.New("invalid wire data")
}
b = b[n:]
}
var num protowire.Number
if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
return errors.New("invalid wire data")
} else {
num = protowire.Number(n)
}
wtyp := protowire.Type(tag & 7)
if num == f.num {
o, err := f.funcs.unmarshal(b, p, wtyp, f, opts)
if err == nil {
b = b[o.n:]
continue
}
if err != errUnknown {
return err
}
}
n := protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 {
return errors.New("invalid wire data")
}
b = b[n:]
}
return nil
}
func (mi *MessageInfo) skipField(b []byte, f *coderFieldInfo, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, _ ValidationStatus) {
fmi := f.validation.mi
if fmi == nil {
fd := mi.Desc.Fields().ByNumber(f.num)
if fd == nil {
return out, ValidationUnknown
}
messageName := fd.Message().FullName()
messageType, err := preg.GlobalTypes.FindMessageByName(messageName)
if err != nil {
return out, ValidationUnknown
}
var ok bool
fmi, ok = messageType.(*MessageInfo)
if !ok {
return out, ValidationUnknown
}
}
fmi.init()
switch f.validation.typ {
case validationTypeMessage:
if wtyp != protowire.BytesType {
return out, ValidationWrongWireType
}
v, n := protowire.ConsumeBytes(b)
if n < 0 {
return out, ValidationInvalid
}
out, st := fmi.validate(v, 0, opts)
out.n = n
return out, st
case validationTypeGroup:
if wtyp != protowire.StartGroupType {
return out, ValidationWrongWireType
}
out, st := fmi.validate(b, f.num, opts)
return out, st
default:
return out, ValidationUnknown
}
}
// unmarshalPointerLazy is similar to unmarshalPointerEager, but it
// specifically handles lazy unmarshalling. it expects lazyOffset and
// presenceOffset to both be valid.
func (mi *MessageInfo) unmarshalPointerLazy(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
initialized := true
var requiredMask uint64
var lazy **protolazy.XXX_lazyUnmarshalInfo
var presence presence
var lazyIndex []protolazy.IndexEntry
var lastNum protowire.Number
outOfOrder := false
lazyDecode := false
presence = p.Apply(mi.presenceOffset).PresenceInfo()
lazy = p.Apply(mi.lazyOffset).LazyInfoPtr()
if !presence.AnyPresent(mi.presenceSize) {
if opts.CanBeLazy() {
// If the message contains existing data, we need to merge into it.
// Lazy unmarshaling doesn't merge, so only enable it when the
// message is empty (has no presence bitmap).
lazyDecode = true
if *lazy == nil {
*lazy = &protolazy.XXX_lazyUnmarshalInfo{}
}
(*lazy).SetUnmarshalFlags(opts.flags)
if !opts.AliasBuffer() {
// Make a copy of the buffer for lazy unmarshaling.
// Set the AliasBuffer flag so recursive unmarshal
// operations reuse the copy.
b = append([]byte{}, b...)
opts.flags |= piface.UnmarshalAliasBuffer
}
(*lazy).SetBuffer(b)
}
}
// Track special handling of lazy fields.
//
// In the common case, all fields are lazyValidateOnly (and lazyFields remains nil).
// In the event that validation for a field fails, this map tracks handling of the field.
type lazyAction uint8
const (
lazyValidateOnly lazyAction = iota // validate the field only
lazyUnmarshalNow // eagerly unmarshal the field
lazyUnmarshalLater // unmarshal the field after the message is fully processed
)
var lazyFields map[*coderFieldInfo]lazyAction
var exts *map[int32]ExtensionField
start := len(b)
pos := 0
for len(b) > 0 {
// Parse the tag (field number and wire type).
var tag uint64
if b[0] < 0x80 {
tag = uint64(b[0])
b = b[1:]
} else if len(b) >= 2 && b[1] < 128 {
tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
b = b[2:]
} else {
var n int
tag, n = protowire.ConsumeVarint(b)
if n < 0 {
return out, errDecode
}
b = b[n:]
}
var num protowire.Number
if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
return out, errors.New("invalid field number")
} else {
num = protowire.Number(n)
}
wtyp := protowire.Type(tag & 7)
if wtyp == protowire.EndGroupType {
if num != groupTag {
return out, errors.New("mismatching end group marker")
}
groupTag = 0
break
}
var f *coderFieldInfo
if int(num) < len(mi.denseCoderFields) {
f = mi.denseCoderFields[num]
} else {
f = mi.coderFields[num]
}
var n int
err := errUnknown
discardUnknown := false
Field:
switch {
case f != nil:
if f.funcs.unmarshal == nil {
break
}
if f.isLazy && lazyDecode {
switch {
case lazyFields == nil || lazyFields[f] == lazyValidateOnly:
// Attempt to validate this field and leave it for later lazy unmarshaling.
o, valid := mi.skipField(b, f, wtyp, opts)
switch valid {
case ValidationValid:
// Skip over the valid field and continue.
err = nil
presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
requiredMask |= f.validation.requiredBit
if !o.initialized {
initialized = false
}
n = o.n
break Field
case ValidationInvalid:
return out, errors.New("invalid proto wire format")
case ValidationWrongWireType:
break Field
case ValidationUnknown:
if lazyFields == nil {
lazyFields = make(map[*coderFieldInfo]lazyAction)
}
if presence.Present(f.presenceIndex) {
// We were unable to determine if the field is valid or not,
// and we've already skipped over at least one instance of this
// field. Clear the presence bit (so if we stop decoding early,
// we don't leave a partially-initialized field around) and flag
// the field for unmarshaling before we return.
presence.ClearPresent(f.presenceIndex)
lazyFields[f] = lazyUnmarshalLater
discardUnknown = true
break Field
} else {
// We were unable to determine if the field is valid or not,
// but this is the first time we've seen it. Flag it as needing
// eager unmarshaling and fall through to the eager unmarshal case below.
lazyFields[f] = lazyUnmarshalNow
}
}
case lazyFields[f] == lazyUnmarshalLater:
// This field will be unmarshaled in a separate pass below.
// Skip over it here.
discardUnknown = true
break Field
default:
// Eagerly unmarshal the field.
}
}
if f.isLazy && !lazyDecode && presence.Present(f.presenceIndex) {
if p.Apply(f.offset).AtomicGetPointer().IsNil() {
mi.lazyUnmarshal(p, f.num)
}
}
var o unmarshalOutput
o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, f, opts)
n = o.n
if err != nil {
break
}
requiredMask |= f.validation.requiredBit
if f.funcs.isInit != nil && !o.initialized {
initialized = false
}
if f.presenceIndex != noPresence {
presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
}
default:
// Possible extension.
if exts == nil && mi.extensionOffset.IsValid() {
exts = p.Apply(mi.extensionOffset).Extensions()
if *exts == nil {
*exts = make(map[int32]ExtensionField)
}
}
if exts == nil {
break
}
var o unmarshalOutput
o, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
if err != nil {
break
}
n = o.n
if !o.initialized {
initialized = false
}
}
if err != nil {
if err != errUnknown {
return out, err
}
n = protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 {
return out, errDecode
}
if !discardUnknown && !opts.DiscardUnknown() && mi.unknownOffset.IsValid() {
u := mi.mutableUnknownBytes(p)
*u = protowire.AppendTag(*u, num, wtyp)
*u = append(*u, b[:n]...)
}
}
b = b[n:]
end := start - len(b)
if lazyDecode && f != nil && f.isLazy {
if num != lastNum {
lazyIndex = append(lazyIndex, protolazy.IndexEntry{
FieldNum: uint32(num),
Start: uint32(pos),
End: uint32(end),
})
} else {
i := len(lazyIndex) - 1
lazyIndex[i].End = uint32(end)
lazyIndex[i].MultipleContiguous = true
}
}
if num < lastNum {
outOfOrder = true
}
pos = end
lastNum = num
}
if groupTag != 0 {
return out, errors.New("missing end group marker")
}
if lazyFields != nil {
// Some fields failed validation, and now need to be unmarshaled.
for f, action := range lazyFields {
if action != lazyUnmarshalLater {
continue
}
initialized = false
if *lazy == nil {
*lazy = &protolazy.XXX_lazyUnmarshalInfo{}
}
if err := mi.unmarshalField((*lazy).Buffer(), p.Apply(f.offset), f, *lazy, opts.flags); err != nil {
return out, err
}
presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
}
}
if lazyDecode {
if outOfOrder {
sort.Slice(lazyIndex, func(i, j int) bool {
return lazyIndex[i].FieldNum < lazyIndex[j].FieldNum ||
(lazyIndex[i].FieldNum == lazyIndex[j].FieldNum &&
lazyIndex[i].Start < lazyIndex[j].Start)
})
}
if *lazy == nil {
*lazy = &protolazy.XXX_lazyUnmarshalInfo{}
}
(*lazy).SetIndex(lazyIndex)
}
if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) {
initialized = false
}
if initialized {
out.initialized = true
}
out.n = start - len(b)
return out, nil
}

View File

@ -310,12 +310,9 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
fd.L0.Parent = md fd.L0.Parent = md
fd.L0.Index = n fd.L0.Index = n
if fd.L1.IsWeak || fd.L1.EditionFeatures.IsPacked { if fd.L1.EditionFeatures.IsPacked {
fd.L1.Options = func() protoreflect.ProtoMessage { fd.L1.Options = func() protoreflect.ProtoMessage {
opts := descopts.Field.ProtoReflect().New() opts := descopts.Field.ProtoReflect().New()
if fd.L1.IsWeak {
opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
}
if fd.L1.EditionFeatures.IsPacked { if fd.L1.EditionFeatures.IsPacked {
opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.EditionFeatures.IsPacked)) opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.EditionFeatures.IsPacked))
} }

View File

@ -41,11 +41,38 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
if src.IsNil() { if src.IsNil() {
return return
} }
var presenceSrc presence
var presenceDst presence
if mi.presenceOffset.IsValid() {
presenceSrc = src.Apply(mi.presenceOffset).PresenceInfo()
presenceDst = dst.Apply(mi.presenceOffset).PresenceInfo()
}
for _, f := range mi.orderedCoderFields { for _, f := range mi.orderedCoderFields {
if f.funcs.merge == nil { if f.funcs.merge == nil {
continue continue
} }
sfptr := src.Apply(f.offset) sfptr := src.Apply(f.offset)
if f.presenceIndex != noPresence {
if !presenceSrc.Present(f.presenceIndex) {
continue
}
dfptr := dst.Apply(f.offset)
if f.isLazy {
if sfptr.AtomicGetPointer().IsNil() {
mi.lazyUnmarshal(src, f.num)
}
if presenceDst.Present(f.presenceIndex) && dfptr.AtomicGetPointer().IsNil() {
mi.lazyUnmarshal(dst, f.num)
}
}
f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
presenceDst.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
continue
}
if f.isPointer && sfptr.Elem().IsNil() { if f.isPointer && sfptr.Elem().IsNil() {
continue continue
} }

View File

@ -14,7 +14,6 @@ import (
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
) )
// MessageInfo provides protobuf related functionality for a given Go type // MessageInfo provides protobuf related functionality for a given Go type
@ -79,6 +78,9 @@ func (mi *MessageInfo) initOnce() {
if mi.initDone == 1 { if mi.initDone == 1 {
return return
} }
if opaqueInitHook(mi) {
return
}
t := mi.GoReflectType t := mi.GoReflectType
if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct { if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct {
@ -117,7 +119,6 @@ type (
var ( var (
sizecacheType = reflect.TypeOf(SizeCache(0)) sizecacheType = reflect.TypeOf(SizeCache(0))
weakFieldsType = reflect.TypeOf(WeakFields(nil))
unknownFieldsAType = reflect.TypeOf(unknownFieldsA(nil)) unknownFieldsAType = reflect.TypeOf(unknownFieldsA(nil))
unknownFieldsBType = reflect.TypeOf(unknownFieldsB(nil)) unknownFieldsBType = reflect.TypeOf(unknownFieldsB(nil))
extensionFieldsType = reflect.TypeOf(ExtensionFields(nil)) extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
@ -126,13 +127,14 @@ var (
type structInfo struct { type structInfo struct {
sizecacheOffset offset sizecacheOffset offset
sizecacheType reflect.Type sizecacheType reflect.Type
weakOffset offset
weakType reflect.Type
unknownOffset offset unknownOffset offset
unknownType reflect.Type unknownType reflect.Type
extensionOffset offset extensionOffset offset
extensionType reflect.Type extensionType reflect.Type
lazyOffset offset
presenceOffset offset
fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField
oneofsByName map[protoreflect.Name]reflect.StructField oneofsByName map[protoreflect.Name]reflect.StructField
oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber
@ -142,9 +144,10 @@ type structInfo struct {
func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
si := structInfo{ si := structInfo{
sizecacheOffset: invalidOffset, sizecacheOffset: invalidOffset,
weakOffset: invalidOffset,
unknownOffset: invalidOffset, unknownOffset: invalidOffset,
extensionOffset: invalidOffset, extensionOffset: invalidOffset,
lazyOffset: invalidOffset,
presenceOffset: invalidOffset,
fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{}, fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{},
oneofsByName: map[protoreflect.Name]reflect.StructField{}, oneofsByName: map[protoreflect.Name]reflect.StructField{},
@ -157,24 +160,23 @@ fieldLoop:
switch f := t.Field(i); f.Name { switch f := t.Field(i); f.Name {
case genid.SizeCache_goname, genid.SizeCacheA_goname: case genid.SizeCache_goname, genid.SizeCacheA_goname:
if f.Type == sizecacheType { if f.Type == sizecacheType {
si.sizecacheOffset = offsetOf(f, mi.Exporter) si.sizecacheOffset = offsetOf(f)
si.sizecacheType = f.Type si.sizecacheType = f.Type
} }
case genid.WeakFields_goname, genid.WeakFieldsA_goname:
if f.Type == weakFieldsType {
si.weakOffset = offsetOf(f, mi.Exporter)
si.weakType = f.Type
}
case genid.UnknownFields_goname, genid.UnknownFieldsA_goname: case genid.UnknownFields_goname, genid.UnknownFieldsA_goname:
if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType { if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType {
si.unknownOffset = offsetOf(f, mi.Exporter) si.unknownOffset = offsetOf(f)
si.unknownType = f.Type si.unknownType = f.Type
} }
case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname: case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname:
if f.Type == extensionFieldsType { if f.Type == extensionFieldsType {
si.extensionOffset = offsetOf(f, mi.Exporter) si.extensionOffset = offsetOf(f)
si.extensionType = f.Type si.extensionType = f.Type
} }
case "lazyFields", "XXX_lazyUnmarshalInfo":
si.lazyOffset = offsetOf(f)
case "XXX_presence":
si.presenceOffset = offsetOf(f)
default: default:
for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
if len(s) > 0 && strings.Trim(s, "0123456789") == "" { if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
@ -244,9 +246,6 @@ func (mi *MessageInfo) Message(i int) protoreflect.MessageType {
mi.init() mi.init()
fd := mi.Desc.Fields().Get(i) fd := mi.Desc.Fields().Get(i)
switch { switch {
case fd.IsWeak():
mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName())
return mt
case fd.IsMap(): case fd.IsMap():
return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]} return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]}
default: default:

View File

@ -0,0 +1,627 @@
// 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 (
"fmt"
"math"
"reflect"
"strings"
"sync/atomic"
"google.golang.org/protobuf/reflect/protoreflect"
)
type opaqueStructInfo struct {
structInfo
}
// isOpaque determines whether a protobuf message type is on the Opaque API. It
// checks whether the type is a Go struct that protoc-gen-go would generate.
//
// This function only detects newly generated messages from the v2
// implementation of protoc-gen-go. It is unable to classify generated messages
// that are too old or those that are generated by a different generator
// such as protoc-gen-gogo.
func isOpaque(t reflect.Type) bool {
// The current detection mechanism is to simply check the first field
// for a struct tag with the "protogen" key.
if t.Kind() == reflect.Struct && t.NumField() > 0 {
pgt := t.Field(0).Tag.Get("protogen")
return strings.HasPrefix(pgt, "opaque.")
}
return false
}
func opaqueInitHook(mi *MessageInfo) bool {
mt := mi.GoReflectType.Elem()
si := opaqueStructInfo{
structInfo: mi.makeStructInfo(mt),
}
if !isOpaque(mt) {
return false
}
defer atomic.StoreUint32(&mi.initDone, 1)
mi.fields = map[protoreflect.FieldNumber]*fieldInfo{}
fds := mi.Desc.Fields()
for i := 0; i < fds.Len(); i++ {
fd := fds.Get(i)
fs := si.fieldsByNumber[fd.Number()]
var fi fieldInfo
usePresence, _ := usePresenceForField(si, fd)
switch {
case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
// Oneofs are no different for opaque.
fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
case fd.IsMap():
fi = mi.fieldInfoForMapOpaque(si, fd, fs)
case fd.IsList() && fd.Message() == nil && usePresence:
fi = mi.fieldInfoForScalarListOpaque(si, fd, fs)
case fd.IsList() && fd.Message() == nil:
// Proto3 lists without presence can use same access methods as open
fi = fieldInfoForList(fd, fs, mi.Exporter)
case fd.IsList() && usePresence:
fi = mi.fieldInfoForMessageListOpaque(si, fd, fs)
case fd.IsList():
// Proto3 opaque messages that does not need presence bitmap.
// Different representation than open struct, but same logic
fi = mi.fieldInfoForMessageListOpaqueNoPresence(si, fd, fs)
case fd.Message() != nil && usePresence:
fi = mi.fieldInfoForMessageOpaque(si, fd, fs)
case fd.Message() != nil:
// Proto3 messages without presence can use same access methods as open
fi = fieldInfoForMessage(fd, fs, mi.Exporter)
default:
fi = mi.fieldInfoForScalarOpaque(si, fd, fs)
}
mi.fields[fd.Number()] = &fi
}
mi.oneofs = map[protoreflect.Name]*oneofInfo{}
for i := 0; i < mi.Desc.Oneofs().Len(); i++ {
od := mi.Desc.Oneofs().Get(i)
mi.oneofs[od.Name()] = makeOneofInfoOpaque(mi, od, si.structInfo, mi.Exporter)
}
mi.denseFields = make([]*fieldInfo, fds.Len()*2)
for i := 0; i < fds.Len(); i++ {
if fd := fds.Get(i); int(fd.Number()) < len(mi.denseFields) {
mi.denseFields[fd.Number()] = mi.fields[fd.Number()]
}
}
for i := 0; i < fds.Len(); {
fd := fds.Get(i)
if od := fd.ContainingOneof(); od != nil && !fd.ContainingOneof().IsSynthetic() {
mi.rangeInfos = append(mi.rangeInfos, mi.oneofs[od.Name()])
i += od.Fields().Len()
} else {
mi.rangeInfos = append(mi.rangeInfos, mi.fields[fd.Number()])
i++
}
}
mi.makeExtensionFieldsFunc(mt, si.structInfo)
mi.makeUnknownFieldsFunc(mt, si.structInfo)
mi.makeOpaqueCoderMethods(mt, si)
mi.makeFieldTypes(si.structInfo)
return true
}
func makeOneofInfoOpaque(mi *MessageInfo, od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
oi := &oneofInfo{oneofDesc: od}
if od.IsSynthetic() {
fd := od.Fields().Get(0)
index, _ := presenceIndex(mi.Desc, fd)
oi.which = func(p pointer) protoreflect.FieldNumber {
if p.IsNil() {
return 0
}
if !mi.present(p, index) {
return 0
}
return od.Fields().Get(0).Number()
}
return oi
}
// Dispatch to non-opaque oneof implementation for non-synthetic oneofs.
return makeOneofInfo(od, si, x)
}
func (mi *MessageInfo) fieldInfoForMapOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
if ft.Kind() != reflect.Map {
panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
}
fieldOffset := offsetOf(fs)
conv := NewConverter(ft, fd)
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
// Don't bother checking presence bits, since we need to
// look at the map length even if the presence bit is set.
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
return rv.Len() > 0
},
clear: func(p pointer) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type()))
},
get: func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if rv.Len() == 0 {
return conv.Zero()
}
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) {
pv := conv.GoValueOf(v)
if pv.IsNil() {
panic(fmt.Sprintf("invalid value: setting map field to read-only value"))
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(pv)
},
mutable: func(p pointer) protoreflect.Value {
v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if v.IsNil() {
v.Set(reflect.MakeMap(fs.Type))
}
return conv.PBValueOf(v)
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
func (mi *MessageInfo) fieldInfoForScalarListOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
if ft.Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
}
conv := NewConverter(reflect.PtrTo(ft), fd)
fieldOffset := offsetOf(fs)
index, _ := presenceIndex(mi.Desc, fd)
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
return rv.Len() > 0
},
clear: func(p pointer) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type()))
},
get: func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
if rv.Elem().Len() == 0 {
return conv.Zero()
}
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) {
pv := conv.GoValueOf(v)
if pv.IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
}
mi.setPresent(p, index)
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(pv.Elem())
},
mutable: func(p pointer) protoreflect.Value {
mi.setPresent(p, index)
return conv.PBValueOf(p.Apply(fieldOffset).AsValueOf(fs.Type))
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
func (mi *MessageInfo) fieldInfoForMessageListOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
}
conv := NewConverter(ft, fd)
fieldOffset := offsetOf(fs)
index, _ := presenceIndex(mi.Desc, fd)
fieldNumber := fd.Number()
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
if !mi.present(p, index) {
return false
}
sp := p.Apply(fieldOffset).AtomicGetPointer()
if sp.IsNil() {
// Lazily unmarshal this field.
mi.lazyUnmarshal(p, fieldNumber)
sp = p.Apply(fieldOffset).AtomicGetPointer()
}
rv := sp.AsValueOf(fs.Type.Elem())
return rv.Elem().Len() > 0
},
clear: func(p pointer) {
fp := p.Apply(fieldOffset)
sp := fp.AtomicGetPointer()
if sp.IsNil() {
sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem())))
mi.setPresent(p, index)
}
rv := sp.AsValueOf(fs.Type.Elem())
rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
},
get: func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
if !mi.present(p, index) {
return conv.Zero()
}
sp := p.Apply(fieldOffset).AtomicGetPointer()
if sp.IsNil() {
// Lazily unmarshal this field.
mi.lazyUnmarshal(p, fieldNumber)
sp = p.Apply(fieldOffset).AtomicGetPointer()
}
rv := sp.AsValueOf(fs.Type.Elem())
if rv.Elem().Len() == 0 {
return conv.Zero()
}
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) {
fp := p.Apply(fieldOffset)
sp := fp.AtomicGetPointer()
if sp.IsNil() {
sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem())))
mi.setPresent(p, index)
}
rv := sp.AsValueOf(fs.Type.Elem())
val := conv.GoValueOf(v)
if val.IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
} else {
rv.Elem().Set(val.Elem())
}
},
mutable: func(p pointer) protoreflect.Value {
fp := p.Apply(fieldOffset)
sp := fp.AtomicGetPointer()
if sp.IsNil() {
if mi.present(p, index) {
// Lazily unmarshal this field.
mi.lazyUnmarshal(p, fieldNumber)
sp = p.Apply(fieldOffset).AtomicGetPointer()
} else {
sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem())))
mi.setPresent(p, index)
}
}
rv := sp.AsValueOf(fs.Type.Elem())
return conv.PBValueOf(rv)
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
}
conv := NewConverter(ft, fd)
fieldOffset := offsetOf(fs)
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
sp := p.Apply(fieldOffset).AtomicGetPointer()
if sp.IsNil() {
return false
}
rv := sp.AsValueOf(fs.Type.Elem())
return rv.Elem().Len() > 0
},
clear: func(p pointer) {
sp := p.Apply(fieldOffset).AtomicGetPointer()
if !sp.IsNil() {
rv := sp.AsValueOf(fs.Type.Elem())
rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
}
},
get: func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
sp := p.Apply(fieldOffset).AtomicGetPointer()
if sp.IsNil() {
return conv.Zero()
}
rv := sp.AsValueOf(fs.Type.Elem())
if rv.Elem().Len() == 0 {
return conv.Zero()
}
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if rv.IsNil() {
rv.Set(reflect.New(fs.Type.Elem()))
}
val := conv.GoValueOf(v)
if val.IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
} else {
rv.Elem().Set(val.Elem())
}
},
mutable: func(p pointer) protoreflect.Value {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if rv.IsNil() {
rv.Set(reflect.New(fs.Type.Elem()))
}
return conv.PBValueOf(rv)
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
func (mi *MessageInfo) fieldInfoForScalarOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
nullable := fd.HasPresence()
if oneof := fd.ContainingOneof(); oneof != nil && oneof.IsSynthetic() {
nullable = true
}
deref := false
if nullable && ft.Kind() == reflect.Ptr {
ft = ft.Elem()
deref = true
}
conv := NewConverter(ft, fd)
fieldOffset := offsetOf(fs)
index, _ := presenceIndex(mi.Desc, fd)
var getter func(p pointer) protoreflect.Value
if !nullable {
getter = getterForDirectScalar(fd, fs, conv, fieldOffset)
} else {
getter = getterForOpaqueNullableScalar(mi, index, fd, fs, conv, fieldOffset)
}
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
if nullable {
return mi.present(p, index)
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
switch rv.Kind() {
case reflect.Bool:
return rv.Bool()
case reflect.Int32, reflect.Int64:
return rv.Int() != 0
case reflect.Uint32, reflect.Uint64:
return rv.Uint() != 0
case reflect.Float32, reflect.Float64:
return rv.Float() != 0 || math.Signbit(rv.Float())
case reflect.String, reflect.Slice:
return rv.Len() > 0
default:
panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
}
},
clear: func(p pointer) {
if nullable {
mi.clearPresent(p, index)
}
// This is only valuable for bytes and strings, but we do it unconditionally.
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type()))
},
get: getter,
// TODO: Implement unsafe fast path for set?
set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if deref {
if rv.IsNil() {
rv.Set(reflect.New(ft))
}
rv = rv.Elem()
}
rv.Set(conv.GoValueOf(v))
if nullable && rv.Kind() == reflect.Slice && rv.IsNil() {
rv.Set(emptyBytes)
}
if nullable {
mi.setPresent(p, index)
}
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
func (mi *MessageInfo) fieldInfoForMessageOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo {
ft := fs.Type
conv := NewConverter(ft, fd)
fieldOffset := offsetOf(fs)
index, _ := presenceIndex(mi.Desc, fd)
fieldNumber := fd.Number()
elemType := fs.Type.Elem()
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
return mi.present(p, index)
},
clear: func(p pointer) {
mi.clearPresent(p, index)
p.Apply(fieldOffset).AtomicSetNilPointer()
},
get: func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
fp := p.Apply(fieldOffset)
mp := fp.AtomicGetPointer()
if mp.IsNil() {
// Lazily unmarshal this field.
mi.lazyUnmarshal(p, fieldNumber)
mp = fp.AtomicGetPointer()
}
rv := mp.AsValueOf(elemType)
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) {
val := pointerOfValue(conv.GoValueOf(v))
if val.IsNil() {
panic("invalid nil pointer")
}
p.Apply(fieldOffset).AtomicSetPointer(val)
mi.setPresent(p, index)
},
mutable: func(p pointer) protoreflect.Value {
fp := p.Apply(fieldOffset)
mp := fp.AtomicGetPointer()
if mp.IsNil() {
if mi.present(p, index) {
// Lazily unmarshal this field.
mi.lazyUnmarshal(p, fieldNumber)
mp = fp.AtomicGetPointer()
} else {
mp = pointerOfValue(conv.GoValueOf(conv.New()))
fp.AtomicSetPointer(mp)
mi.setPresent(p, index)
}
}
return conv.PBValueOf(mp.AsValueOf(fs.Type.Elem()))
},
newMessage: func() protoreflect.Message {
return conv.New().Message()
},
newField: func() protoreflect.Value {
return conv.New()
},
}
}
// A presenceList wraps a List, updating presence bits as necessary when the
// list contents change.
type presenceList struct {
pvalueList
setPresence func(bool)
}
type pvalueList interface {
protoreflect.List
//Unwrapper
}
func (list presenceList) Append(v protoreflect.Value) {
list.pvalueList.Append(v)
list.setPresence(true)
}
func (list presenceList) Truncate(i int) {
list.pvalueList.Truncate(i)
list.setPresence(i > 0)
}
// presenceIndex returns the index to pass to presence functions.
//
// TODO: field.Desc.Index() would be simpler, and would give space to record the presence of oneof fields.
func presenceIndex(md protoreflect.MessageDescriptor, fd protoreflect.FieldDescriptor) (uint32, presenceSize) {
found := false
var index, numIndices uint32
for i := 0; i < md.Fields().Len(); i++ {
f := md.Fields().Get(i)
if f == fd {
found = true
index = numIndices
}
if f.ContainingOneof() == nil || isLastOneofField(f) {
numIndices++
}
}
if !found {
panic(fmt.Sprintf("BUG: %v not in %v", fd.Name(), md.FullName()))
}
return index, presenceSize(numIndices)
}
func isLastOneofField(fd protoreflect.FieldDescriptor) bool {
fields := fd.ContainingOneof().Fields()
return fields.Get(fields.Len()-1) == fd
}
func (mi *MessageInfo) setPresent(p pointer, index uint32) {
p.Apply(mi.presenceOffset).PresenceInfo().SetPresent(index, mi.presenceSize)
}
func (mi *MessageInfo) clearPresent(p pointer, index uint32) {
p.Apply(mi.presenceOffset).PresenceInfo().ClearPresent(index)
}
func (mi *MessageInfo) present(p pointer, index uint32) bool {
return p.Apply(mi.presenceOffset).PresenceInfo().Present(index)
}
// usePresenceForField implements the somewhat intricate logic of when
// the presence bitmap is used for a field. The main logic is that a
// field that is optional or that can be lazy will use the presence
// bit, but for proto2, also maps have a presence bit. It also records
// if the field can ever be lazy, which is true if we have a
// lazyOffset and the field is a message or a slice of messages. A
// field that is lazy will always need a presence bit. Oneofs are not
// lazy and do not use presence, unless they are a synthetic oneof,
// which is a proto3 optional field. For proto3 optionals, we use the
// presence and they can also be lazy when applicable (a message).
func usePresenceForField(si opaqueStructInfo, fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) {
hasLazyField := fd.(interface{ IsLazy() bool }).IsLazy()
// Non-oneof scalar fields with explicit field presence use the presence array.
usesPresenceArray := fd.HasPresence() && fd.Message() == nil && (fd.ContainingOneof() == nil || fd.ContainingOneof().IsSynthetic())
switch {
case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
return false, false
case fd.IsMap():
return false, false
case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind:
return hasLazyField, hasLazyField
default:
return usesPresenceArray || (hasLazyField && fd.HasPresence()), false
}
}

View File

@ -0,0 +1,132 @@
// 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.
// Code generated by generate-types. DO NOT EDIT.
package impl
import (
"reflect"
"google.golang.org/protobuf/reflect/protoreflect"
)
func getterForOpaqueNullableScalar(mi *MessageInfo, index uint32, fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value {
ft := fs.Type
if ft.Kind() == reflect.Ptr {
ft = ft.Elem()
}
if fd.Kind() == protoreflect.EnumKind {
// Enums for nullable opaque types.
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
return conv.PBValueOf(rv)
}
}
switch ft.Kind() {
case reflect.Bool:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bool()
return protoreflect.ValueOfBool(*x)
}
case reflect.Int32:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int32()
return protoreflect.ValueOfInt32(*x)
}
case reflect.Uint32:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint32()
return protoreflect.ValueOfUint32(*x)
}
case reflect.Int64:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int64()
return protoreflect.ValueOfInt64(*x)
}
case reflect.Uint64:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint64()
return protoreflect.ValueOfUint64(*x)
}
case reflect.Float32:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float32()
return protoreflect.ValueOfFloat32(*x)
}
case reflect.Float64:
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float64()
return protoreflect.ValueOfFloat64(*x)
}
case reflect.String:
if fd.Kind() == protoreflect.BytesKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).StringPtr()
if *x == nil {
return conv.Zero()
}
if len(**x) == 0 {
return protoreflect.ValueOfBytes(nil)
}
return protoreflect.ValueOfBytes([]byte(**x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).StringPtr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfString(**x)
}
case reflect.Slice:
if fd.Kind() == protoreflect.StringKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
return protoreflect.ValueOfString(string(*x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() || !mi.present(p, index) {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
return protoreflect.ValueOfBytes(*x)
}
}
panic("unexpected protobuf kind: " + ft.Kind().String())
}

View File

@ -72,8 +72,6 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
fi = fieldInfoForMap(fd, fs, mi.Exporter) fi = fieldInfoForMap(fd, fs, mi.Exporter)
case fd.IsList(): case fd.IsList():
fi = fieldInfoForList(fd, fs, mi.Exporter) fi = fieldInfoForList(fd, fs, mi.Exporter)
case fd.IsWeak():
fi = fieldInfoForWeakMessage(fd, si.weakOffset)
case fd.Message() != nil: case fd.Message() != nil:
fi = fieldInfoForMessage(fd, fs, mi.Exporter) fi = fieldInfoForMessage(fd, fs, mi.Exporter)
default: default:
@ -205,6 +203,11 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) {
case fd.IsList(): case fd.IsList():
if fd.Enum() != nil || fd.Message() != nil { if fd.Enum() != nil || fd.Message() != nil {
ft = fs.Type.Elem() ft = fs.Type.Elem()
if ft.Kind() == reflect.Slice {
ft = ft.Elem()
}
} }
isMessage = fd.Message() != nil isMessage = fd.Message() != nil
case fd.Enum() != nil: case fd.Enum() != nil:
@ -214,9 +217,6 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) {
} }
case fd.Message() != nil: case fd.Message() != nil:
ft = fs.Type ft = fs.Type
if fd.IsWeak() {
ft = nil
}
isMessage = true isMessage = true
} }
if isMessage && ft != nil && ft.Kind() != reflect.Ptr { if isMessage && ft != nil && ft.Kind() != reflect.Ptr {

View File

@ -8,11 +8,8 @@ import (
"fmt" "fmt"
"math" "math"
"reflect" "reflect"
"sync"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
) )
type fieldInfo struct { type fieldInfo struct {
@ -76,7 +73,7 @@ func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField,
isMessage := fd.Message() != nil isMessage := fd.Message() != nil
// TODO: Implement unsafe fast path? // TODO: Implement unsafe fast path?
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
return fieldInfo{ return fieldInfo{
// NOTE: The logic below intentionally assumes that oneof fields are // NOTE: The logic below intentionally assumes that oneof fields are
// well-formatted. That is, the oneof interface never contains a // well-formatted. That is, the oneof interface never contains a
@ -152,7 +149,7 @@ func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x
conv := NewConverter(ft, fd) conv := NewConverter(ft, fd)
// TODO: Implement unsafe fast path? // TODO: Implement unsafe fast path?
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
return fieldInfo{ return fieldInfo{
fieldDesc: fd, fieldDesc: fd,
has: func(p pointer) bool { has: func(p pointer) bool {
@ -205,7 +202,7 @@ func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x
conv := NewConverter(reflect.PtrTo(ft), fd) conv := NewConverter(reflect.PtrTo(ft), fd)
// TODO: Implement unsafe fast path? // TODO: Implement unsafe fast path?
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
return fieldInfo{ return fieldInfo{
fieldDesc: fd, fieldDesc: fd,
has: func(p pointer) bool { has: func(p pointer) bool {
@ -256,6 +253,7 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField,
ft := fs.Type ft := fs.Type
nullable := fd.HasPresence() nullable := fd.HasPresence()
isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
var getter func(p pointer) protoreflect.Value
if nullable { if nullable {
if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice { if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
// This never occurs for generated message types. // This never occurs for generated message types.
@ -268,19 +266,25 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField,
} }
} }
conv := NewConverter(ft, fd) conv := NewConverter(ft, fd)
fieldOffset := offsetOf(fs)
// Generate specialized getter functions to avoid going through reflect.Value
if nullable {
getter = getterForNullableScalar(fd, fs, conv, fieldOffset)
} else {
getter = getterForDirectScalar(fd, fs, conv, fieldOffset)
}
// TODO: Implement unsafe fast path?
fieldOffset := offsetOf(fs, x)
return fieldInfo{ return fieldInfo{
fieldDesc: fd, fieldDesc: fd,
has: func(p pointer) bool { has: func(p pointer) bool {
if p.IsNil() { if p.IsNil() {
return false return false
} }
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if nullable { if nullable {
return !rv.IsNil() return !p.Apply(fieldOffset).Elem().IsNil()
} }
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
switch rv.Kind() { switch rv.Kind() {
case reflect.Bool: case reflect.Bool:
return rv.Bool() return rv.Bool()
@ -300,21 +304,8 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField,
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) protoreflect.Value { get: getter,
if p.IsNil() { // TODO: Implement unsafe fast path for set?
return conv.Zero()
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if nullable {
if rv.IsNil() {
return conv.Zero()
}
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
}
return conv.PBValueOf(rv)
},
set: func(p pointer, v protoreflect.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if nullable && rv.Kind() == reflect.Ptr { if nullable && rv.Kind() == reflect.Ptr {
@ -338,85 +329,12 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField,
} }
} }
func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo {
if !flags.ProtoLegacy {
panic("no support for proto1 weak fields")
}
var once sync.Once
var messageType protoreflect.MessageType
lazyInit := func() {
once.Do(func() {
messageName := fd.Message().FullName()
messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
if messageType == nil {
panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
}
})
}
num := fd.Number()
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
if p.IsNil() {
return false
}
_, ok := p.Apply(weakOffset).WeakFields().get(num)
return ok
},
clear: func(p pointer) {
p.Apply(weakOffset).WeakFields().clear(num)
},
get: func(p pointer) protoreflect.Value {
lazyInit()
if p.IsNil() {
return protoreflect.ValueOfMessage(messageType.Zero())
}
m, ok := p.Apply(weakOffset).WeakFields().get(num)
if !ok {
return protoreflect.ValueOfMessage(messageType.Zero())
}
return protoreflect.ValueOfMessage(m.ProtoReflect())
},
set: func(p pointer, v protoreflect.Value) {
lazyInit()
m := v.Message()
if m.Descriptor() != messageType.Descriptor() {
if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want {
panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want))
}
panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName()))
}
p.Apply(weakOffset).WeakFields().set(num, m.Interface())
},
mutable: func(p pointer) protoreflect.Value {
lazyInit()
fs := p.Apply(weakOffset).WeakFields()
m, ok := fs.get(num)
if !ok {
m = messageType.New().Interface()
fs.set(num, m)
}
return protoreflect.ValueOfMessage(m.ProtoReflect())
},
newMessage: func() protoreflect.Message {
lazyInit()
return messageType.New()
},
newField: func() protoreflect.Value {
lazyInit()
return protoreflect.ValueOfMessage(messageType.New())
},
}
}
func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
ft := fs.Type ft := fs.Type
conv := NewConverter(ft, fd) conv := NewConverter(ft, fd)
// TODO: Implement unsafe fast path? // TODO: Implement unsafe fast path?
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
return fieldInfo{ return fieldInfo{
fieldDesc: fd, fieldDesc: fd,
has: func(p pointer) bool { has: func(p pointer) bool {
@ -425,7 +343,7 @@ func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField
} }
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if fs.Type.Kind() != reflect.Ptr { if fs.Type.Kind() != reflect.Ptr {
return !isZero(rv) return !rv.IsZero()
} }
return !rv.IsNil() return !rv.IsNil()
}, },
@ -472,7 +390,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *
oi := &oneofInfo{oneofDesc: od} oi := &oneofInfo{oneofDesc: od}
if od.IsSynthetic() { if od.IsSynthetic() {
fs := si.fieldsByNumber[od.Fields().Get(0).Number()] fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
oi.which = func(p pointer) protoreflect.FieldNumber { oi.which = func(p pointer) protoreflect.FieldNumber {
if p.IsNil() { if p.IsNil() {
return 0 return 0
@ -485,7 +403,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *
} }
} else { } else {
fs := si.oneofsByName[od.Name()] fs := si.oneofsByName[od.Name()]
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs)
oi.which = func(p pointer) protoreflect.FieldNumber { oi.which = func(p pointer) protoreflect.FieldNumber {
if p.IsNil() { if p.IsNil() {
return 0 return 0
@ -503,41 +421,3 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *
} }
return oi return oi
} }
// isZero is identical to reflect.Value.IsZero.
// TODO: Remove this when Go1.13 is the minimally supported Go version.
func isZero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return math.Float64bits(v.Float()) == 0
case reflect.Complex64, reflect.Complex128:
c := v.Complex()
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
case reflect.Array:
for i := 0; i < v.Len(); i++ {
if !isZero(v.Index(i)) {
return false
}
}
return true
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
return v.IsNil()
case reflect.String:
return v.Len() == 0
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
if !isZero(v.Field(i)) {
return false
}
}
return true
default:
panic(&reflect.ValueError{Method: "reflect.Value.IsZero", Kind: v.Kind()})
}
}

View File

@ -0,0 +1,273 @@
// 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.
// Code generated by generate-types. DO NOT EDIT.
package impl
import (
"reflect"
"google.golang.org/protobuf/reflect/protoreflect"
)
func getterForNullableScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value {
ft := fs.Type
if ft.Kind() == reflect.Ptr {
ft = ft.Elem()
}
if fd.Kind() == protoreflect.EnumKind {
elemType := fs.Type.Elem()
// Enums for nullable types.
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
rv := p.Apply(fieldOffset).Elem().AsValueOf(elemType)
if rv.IsNil() {
return conv.Zero()
}
return conv.PBValueOf(rv.Elem())
}
}
switch ft.Kind() {
case reflect.Bool:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).BoolPtr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfBool(**x)
}
case reflect.Int32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int32Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfInt32(**x)
}
case reflect.Uint32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint32Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfUint32(**x)
}
case reflect.Int64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int64Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfInt64(**x)
}
case reflect.Uint64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint64Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfUint64(**x)
}
case reflect.Float32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float32Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfFloat32(**x)
}
case reflect.Float64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float64Ptr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfFloat64(**x)
}
case reflect.String:
if fd.Kind() == protoreflect.BytesKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).StringPtr()
if *x == nil {
return conv.Zero()
}
if len(**x) == 0 {
return protoreflect.ValueOfBytes(nil)
}
return protoreflect.ValueOfBytes([]byte(**x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).StringPtr()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfString(**x)
}
case reflect.Slice:
if fd.Kind() == protoreflect.StringKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
if len(*x) == 0 {
return conv.Zero()
}
return protoreflect.ValueOfString(string(*x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
if *x == nil {
return conv.Zero()
}
return protoreflect.ValueOfBytes(*x)
}
}
panic("unexpected protobuf kind: " + ft.Kind().String())
}
func getterForDirectScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value {
ft := fs.Type
if fd.Kind() == protoreflect.EnumKind {
// Enums for non nullable types.
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
return conv.PBValueOf(rv)
}
}
switch ft.Kind() {
case reflect.Bool:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bool()
return protoreflect.ValueOfBool(*x)
}
case reflect.Int32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int32()
return protoreflect.ValueOfInt32(*x)
}
case reflect.Uint32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint32()
return protoreflect.ValueOfUint32(*x)
}
case reflect.Int64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Int64()
return protoreflect.ValueOfInt64(*x)
}
case reflect.Uint64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Uint64()
return protoreflect.ValueOfUint64(*x)
}
case reflect.Float32:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float32()
return protoreflect.ValueOfFloat32(*x)
}
case reflect.Float64:
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Float64()
return protoreflect.ValueOfFloat64(*x)
}
case reflect.String:
if fd.Kind() == protoreflect.BytesKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).String()
if len(*x) == 0 {
return protoreflect.ValueOfBytes(nil)
}
return protoreflect.ValueOfBytes([]byte(*x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).String()
return protoreflect.ValueOfString(*x)
}
case reflect.Slice:
if fd.Kind() == protoreflect.StringKind {
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
return protoreflect.ValueOfString(string(*x))
}
}
return func(p pointer) protoreflect.Value {
if p.IsNil() {
return conv.Zero()
}
x := p.Apply(fieldOffset).Bytes()
return protoreflect.ValueOfBytes(*x)
}
}
panic("unexpected protobuf kind: " + ft.Kind().String())
}

View File

@ -8,6 +8,8 @@ import (
"reflect" "reflect"
"sync/atomic" "sync/atomic"
"unsafe" "unsafe"
"google.golang.org/protobuf/internal/protolazy"
) )
const UnsafeEnabled = true const UnsafeEnabled = true
@ -20,7 +22,7 @@ type Pointer unsafe.Pointer
type offset uintptr type offset uintptr
// offsetOf returns a field offset for the struct field. // offsetOf returns a field offset for the struct field.
func offsetOf(f reflect.StructField, x exporter) offset { func offsetOf(f reflect.StructField) offset {
return offset(f.Offset) return offset(f.Offset)
} }
@ -109,8 +111,14 @@ func (p pointer) StringSlice() *[]string { return (*[]string)(p.p
func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) } func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) }
func (p pointer) BytesPtr() **[]byte { return (**[]byte)(p.p) } func (p pointer) BytesPtr() **[]byte { return (**[]byte)(p.p) }
func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) } func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) }
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.p) }
func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) } func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) }
func (p pointer) LazyInfoPtr() **protolazy.XXX_lazyUnmarshalInfo {
return (**protolazy.XXX_lazyUnmarshalInfo)(p.p)
}
func (p pointer) PresenceInfo() presence {
return presence{P: p.p}
}
func (p pointer) Elem() pointer { func (p pointer) Elem() pointer {
return pointer{p: *(*unsafe.Pointer)(p.p)} return pointer{p: *(*unsafe.Pointer)(p.p)}

View File

@ -0,0 +1,42 @@
// 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 (
"sync/atomic"
"unsafe"
)
func (p pointer) AtomicGetPointer() pointer {
return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))}
}
func (p pointer) AtomicSetPointer(v pointer) {
atomic.StorePointer((*unsafe.Pointer)(p.p), v.p)
}
func (p pointer) AtomicSetNilPointer() {
atomic.StorePointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil))
}
func (p pointer) AtomicSetPointerIfNil(v pointer) pointer {
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil), v.p) {
return v
}
return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))}
}
type atomicV1MessageInfo struct{ p Pointer }
func (mi *atomicV1MessageInfo) Get() Pointer {
return Pointer(atomic.LoadPointer((*unsafe.Pointer)(&mi.p)))
}
func (mi *atomicV1MessageInfo) SetIfNil(p Pointer) Pointer {
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(&mi.p), nil, unsafe.Pointer(p)) {
return p
}
return mi.Get()
}

View File

@ -0,0 +1,142 @@
// 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 (
"sync/atomic"
"unsafe"
)
// presenceSize represents the size of a presence set, which should be the largest index of the set+1
type presenceSize uint32
// presence is the internal representation of the bitmap array in a generated protobuf
type presence struct {
// This is a pointer to the beginning of an array of uint32
P unsafe.Pointer
}
func (p presence) toElem(num uint32) (ret *uint32) {
const (
bitsPerByte = 8
siz = unsafe.Sizeof(*ret)
)
// p.P points to an array of uint32, num is the bit in this array that the
// caller wants to check/manipulate. Calculate the index in the array that
// contains this specific bit. E.g.: 76 / 32 = 2 (integer division).
offset := uintptr(num) / (siz * bitsPerByte) * siz
return (*uint32)(unsafe.Pointer(uintptr(p.P) + offset))
}
// Present checks for the presence of a specific field number in a presence set.
func (p presence) Present(num uint32) bool {
if p.P == nil {
return false
}
return Export{}.Present(p.toElem(num), num)
}
// SetPresent adds presence for a specific field number in a presence set.
func (p presence) SetPresent(num uint32, size presenceSize) {
Export{}.SetPresent(p.toElem(num), num, uint32(size))
}
// SetPresentUnatomic adds presence for a specific field number in a presence set without using
// atomic operations. Only to be called during unmarshaling.
func (p presence) SetPresentUnatomic(num uint32, size presenceSize) {
Export{}.SetPresentNonAtomic(p.toElem(num), num, uint32(size))
}
// ClearPresent removes presence for a specific field number in a presence set.
func (p presence) ClearPresent(num uint32) {
Export{}.ClearPresent(p.toElem(num), num)
}
// LoadPresenceCache (together with PresentInCache) allows for a
// cached version of checking for presence without re-reading the word
// for every field. It is optimized for efficiency and assumes no
// simltaneous mutation of the presence set (or at least does not have
// a problem with simultaneous mutation giving inconsistent results).
func (p presence) LoadPresenceCache() (current uint32) {
if p.P == nil {
return 0
}
return atomic.LoadUint32((*uint32)(p.P))
}
// PresentInCache reads presence from a cached word in the presence
// bitmap. It caches up a new word if the bit is outside the
// word. This is for really fast iteration through bitmaps in cases
// where we either know that the bitmap will not be altered, or we
// don't care about inconsistencies caused by simultaneous writes.
func (p presence) PresentInCache(num uint32, cachedElement *uint32, current *uint32) bool {
if num/32 != *cachedElement {
o := uintptr(num/32) * unsafe.Sizeof(uint32(0))
q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o))
*current = atomic.LoadUint32(q)
*cachedElement = num / 32
}
return (*current & (1 << (num % 32))) > 0
}
// AnyPresent checks if any field is marked as present in the bitmap.
func (p presence) AnyPresent(size presenceSize) bool {
n := uintptr((size + 31) / 32)
for j := uintptr(0); j < n; j++ {
o := j * unsafe.Sizeof(uint32(0))
q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o))
b := atomic.LoadUint32(q)
if b > 0 {
return true
}
}
return false
}
// toRaceDetectData finds the preceding RaceDetectHookData in a
// message by using pointer arithmetic. As the type of the presence
// set (bitmap) varies with the number of fields in the protobuf, we
// can not have a struct type containing the array and the
// RaceDetectHookData. instead the RaceDetectHookData is placed
// immediately before the bitmap array, and we find it by walking
// backwards in the struct.
//
// This method is only called from the race-detect version of the code,
// so RaceDetectHookData is never an empty struct.
func (p presence) toRaceDetectData() *RaceDetectHookData {
var template struct {
d RaceDetectHookData
a [1]uint32
}
o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d)))
return (*RaceDetectHookData)(unsafe.Pointer(uintptr(p.P) - o))
}
func atomicLoadShadowPresence(p **[]byte) *[]byte {
return (*[]byte)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
}
func atomicStoreShadowPresence(p **[]byte, v *[]byte) {
atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(p)), nil, unsafe.Pointer(v))
}
// findPointerToRaceDetectData finds the preceding RaceDetectHookData
// in a message by using pointer arithmetic. For the methods called
// directy from generated code, we don't have a pointer to the
// beginning of the presence set, but a pointer inside the array. As
// we know the index of the bit we're manipulating (num), we can
// calculate which element of the array ptr is pointing to. With that
// information we find the preceding RaceDetectHookData and can
// manipulate the shadow bitmap.
//
// This method is only called from the race-detect version of the
// code, so RaceDetectHookData is never an empty struct.
func findPointerToRaceDetectData(ptr *uint32, num uint32) *RaceDetectHookData {
var template struct {
d RaceDetectHookData
a [1]uint32
}
o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d))) + uintptr(num/32)*unsafe.Sizeof(uint32(0))
return (*RaceDetectHookData)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - o))
}

View File

@ -37,6 +37,10 @@ const (
// ValidationValid indicates that unmarshaling the message will succeed. // ValidationValid indicates that unmarshaling the message will succeed.
ValidationValid ValidationValid
// ValidationWrongWireType indicates that a validated field does not have
// the expected wire type.
ValidationWrongWireType
) )
func (v ValidationStatus) String() string { func (v ValidationStatus) String() string {
@ -149,11 +153,23 @@ func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validat
switch fd.Kind() { switch fd.Kind() {
case protoreflect.MessageKind: case protoreflect.MessageKind:
vi.typ = validationTypeMessage vi.typ = validationTypeMessage
if ft.Kind() == reflect.Ptr {
// Repeated opaque message fields are *[]*T.
ft = ft.Elem()
}
if ft.Kind() == reflect.Slice { if ft.Kind() == reflect.Slice {
vi.mi = getMessageInfo(ft.Elem()) vi.mi = getMessageInfo(ft.Elem())
} }
case protoreflect.GroupKind: case protoreflect.GroupKind:
vi.typ = validationTypeGroup vi.typ = validationTypeGroup
if ft.Kind() == reflect.Ptr {
// Repeated opaque message fields are *[]*T.
ft = ft.Elem()
}
if ft.Kind() == reflect.Slice { if ft.Kind() == reflect.Slice {
vi.mi = getMessageInfo(ft.Elem()) vi.mi = getMessageInfo(ft.Elem())
} }
@ -195,9 +211,7 @@ func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validat
switch fd.Kind() { switch fd.Kind() {
case protoreflect.MessageKind: case protoreflect.MessageKind:
vi.typ = validationTypeMessage vi.typ = validationTypeMessage
if !fd.IsWeak() { vi.mi = getMessageInfo(ft)
vi.mi = getMessageInfo(ft)
}
case protoreflect.GroupKind: case protoreflect.GroupKind:
vi.typ = validationTypeGroup vi.typ = validationTypeGroup
vi.mi = getMessageInfo(ft) vi.mi = getMessageInfo(ft)
@ -304,26 +318,6 @@ State:
} }
if f != nil { if f != nil {
vi = f.validation vi = f.validation
if vi.typ == validationTypeMessage && vi.mi == nil {
// Probable weak field.
//
// TODO: Consider storing the results of this lookup somewhere
// rather than recomputing it on every validation.
fd := st.mi.Desc.Fields().ByNumber(num)
if fd == nil || !fd.IsWeak() {
break
}
messageName := fd.Message().FullName()
messageType, err := protoregistry.GlobalTypes.FindMessageByName(messageName)
switch err {
case nil:
vi.mi, _ = messageType.(*MessageInfo)
case protoregistry.NotFound:
vi.typ = validationTypeBytes
default:
return out, ValidationUnknown
}
}
break break
} }
// Possible extension field. // Possible extension field.

View File

@ -1,74 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package impl
import (
"fmt"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
)
// weakFields adds methods to the exported WeakFields type for internal use.
//
// The exported type is an alias to an unnamed type, so methods can't be
// defined directly on it.
type weakFields WeakFields
func (w weakFields) get(num protoreflect.FieldNumber) (protoreflect.ProtoMessage, bool) {
m, ok := w[int32(num)]
return m, ok
}
func (w *weakFields) set(num protoreflect.FieldNumber, m protoreflect.ProtoMessage) {
if *w == nil {
*w = make(weakFields)
}
(*w)[int32(num)] = m
}
func (w *weakFields) clear(num protoreflect.FieldNumber) {
delete(*w, int32(num))
}
func (Export) HasWeak(w WeakFields, num protoreflect.FieldNumber) bool {
_, ok := w[int32(num)]
return ok
}
func (Export) ClearWeak(w *WeakFields, num protoreflect.FieldNumber) {
delete(*w, int32(num))
}
func (Export) GetWeak(w WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName) protoreflect.ProtoMessage {
if m, ok := w[int32(num)]; ok {
return m
}
mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
if mt == nil {
panic(fmt.Sprintf("message %v for weak field is not linked in", name))
}
return mt.Zero().Interface()
}
func (Export) SetWeak(w *WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName, m protoreflect.ProtoMessage) {
if m != nil {
mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
if mt == nil {
panic(fmt.Sprintf("message %v for weak field is not linked in", name))
}
if mt != m.ProtoReflect().Type() {
panic(fmt.Sprintf("invalid message type for weak field: got %T, want %T", m, mt.Zero().Interface()))
}
}
if m == nil || !m.ProtoReflect().IsValid() {
delete(*w, int32(num))
return
}
if *w == nil {
*w = make(weakFields)
}
(*w)[int32(num)] = m
}

View File

@ -0,0 +1,364 @@
// 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.
// Helper code for parsing a protocol buffer
package protolazy
import (
"errors"
"fmt"
"io"
"google.golang.org/protobuf/encoding/protowire"
)
// BufferReader is a structure encapsulating a protobuf and a current position
type BufferReader struct {
Buf []byte
Pos int
}
// NewBufferReader creates a new BufferRead from a protobuf
func NewBufferReader(buf []byte) BufferReader {
return BufferReader{Buf: buf, Pos: 0}
}
var errOutOfBounds = errors.New("protobuf decoding: out of bounds")
var errOverflow = errors.New("proto: integer overflow")
func (b *BufferReader) DecodeVarintSlow() (x uint64, err error) {
i := b.Pos
l := len(b.Buf)
for shift := uint(0); shift < 64; shift += 7 {
if i >= l {
err = io.ErrUnexpectedEOF
return
}
v := b.Buf[i]
i++
x |= (uint64(v) & 0x7F) << shift
if v < 0x80 {
b.Pos = i
return
}
}
// The number is too large to represent in a 64-bit value.
err = errOverflow
return
}
// decodeVarint decodes a varint at the current position
func (b *BufferReader) DecodeVarint() (x uint64, err error) {
i := b.Pos
buf := b.Buf
if i >= len(buf) {
return 0, io.ErrUnexpectedEOF
} else if buf[i] < 0x80 {
b.Pos++
return uint64(buf[i]), nil
} else if len(buf)-i < 10 {
return b.DecodeVarintSlow()
}
var v uint64
// we already checked the first byte
x = uint64(buf[i]) & 127
i++
v = uint64(buf[i])
i++
x |= (v & 127) << 7
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 14
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 21
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 28
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 35
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 42
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 49
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 56
if v < 128 {
goto done
}
v = uint64(buf[i])
i++
x |= (v & 127) << 63
if v < 128 {
goto done
}
return 0, errOverflow
done:
b.Pos = i
return
}
// decodeVarint32 decodes a varint32 at the current position
func (b *BufferReader) DecodeVarint32() (x uint32, err error) {
i := b.Pos
buf := b.Buf
if i >= len(buf) {
return 0, io.ErrUnexpectedEOF
} else if buf[i] < 0x80 {
b.Pos++
return uint32(buf[i]), nil
} else if len(buf)-i < 5 {
v, err := b.DecodeVarintSlow()
return uint32(v), err
}
var v uint32
// we already checked the first byte
x = uint32(buf[i]) & 127
i++
v = uint32(buf[i])
i++
x |= (v & 127) << 7
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
x |= (v & 127) << 14
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
x |= (v & 127) << 21
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
x |= (v & 127) << 28
if v < 128 {
goto done
}
return 0, errOverflow
done:
b.Pos = i
return
}
// skipValue skips a value in the protobuf, based on the specified tag
func (b *BufferReader) SkipValue(tag uint32) (err error) {
wireType := tag & 0x7
switch protowire.Type(wireType) {
case protowire.VarintType:
err = b.SkipVarint()
case protowire.Fixed64Type:
err = b.SkipFixed64()
case protowire.BytesType:
var n uint32
n, err = b.DecodeVarint32()
if err == nil {
err = b.Skip(int(n))
}
case protowire.StartGroupType:
err = b.SkipGroup(tag)
case protowire.Fixed32Type:
err = b.SkipFixed32()
default:
err = fmt.Errorf("Unexpected wire type (%d)", wireType)
}
return
}
// skipGroup skips a group with the specified tag. It executes efficiently using a tag stack
func (b *BufferReader) SkipGroup(tag uint32) (err error) {
tagStack := make([]uint32, 0, 16)
tagStack = append(tagStack, tag)
var n uint32
for len(tagStack) > 0 {
tag, err = b.DecodeVarint32()
if err != nil {
return err
}
switch protowire.Type(tag & 0x7) {
case protowire.VarintType:
err = b.SkipVarint()
case protowire.Fixed64Type:
err = b.Skip(8)
case protowire.BytesType:
n, err = b.DecodeVarint32()
if err == nil {
err = b.Skip(int(n))
}
case protowire.StartGroupType:
tagStack = append(tagStack, tag)
case protowire.Fixed32Type:
err = b.SkipFixed32()
case protowire.EndGroupType:
if protoFieldNumber(tagStack[len(tagStack)-1]) == protoFieldNumber(tag) {
tagStack = tagStack[:len(tagStack)-1]
} else {
err = fmt.Errorf("end group tag %d does not match begin group tag %d at pos %d",
protoFieldNumber(tag), protoFieldNumber(tagStack[len(tagStack)-1]), b.Pos)
}
}
if err != nil {
return err
}
}
return nil
}
// skipVarint effiently skips a varint
func (b *BufferReader) SkipVarint() (err error) {
i := b.Pos
if len(b.Buf)-i < 10 {
// Use DecodeVarintSlow() to check for buffer overflow, but ignore result
if _, err := b.DecodeVarintSlow(); err != nil {
return err
}
return nil
}
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
i++
if b.Buf[i] < 0x80 {
goto out
}
return errOverflow
out:
b.Pos = i + 1
return nil
}
// skip skips the specified number of bytes
func (b *BufferReader) Skip(n int) (err error) {
if len(b.Buf) < b.Pos+n {
return io.ErrUnexpectedEOF
}
b.Pos += n
return
}
// skipFixed64 skips a fixed64
func (b *BufferReader) SkipFixed64() (err error) {
return b.Skip(8)
}
// skipFixed32 skips a fixed32
func (b *BufferReader) SkipFixed32() (err error) {
return b.Skip(4)
}
// skipBytes skips a set of bytes
func (b *BufferReader) SkipBytes() (err error) {
n, err := b.DecodeVarint32()
if err != nil {
return err
}
return b.Skip(int(n))
}
// Done returns whether we are at the end of the protobuf
func (b *BufferReader) Done() bool {
return b.Pos == len(b.Buf)
}
// Remaining returns how many bytes remain
func (b *BufferReader) Remaining() int {
return len(b.Buf) - b.Pos
}

View File

@ -0,0 +1,359 @@
// 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 protolazy contains internal data structures for lazy message decoding.
package protolazy
import (
"fmt"
"sort"
"google.golang.org/protobuf/encoding/protowire"
piface "google.golang.org/protobuf/runtime/protoiface"
)
// IndexEntry is the structure for an index of the fields in a message of a
// proto (not descending to sub-messages)
type IndexEntry struct {
FieldNum uint32
// first byte of this tag/field
Start uint32
// first byte after a contiguous sequence of bytes for this tag/field, which could
// include a single encoding of the field, or multiple encodings for the field
End uint32
// True if this protobuf segment includes multiple encodings of the field
MultipleContiguous bool
}
// XXX_lazyUnmarshalInfo has information about a particular lazily decoded message
//
// Deprecated: Do not use. This will be deleted in the near future.
type XXX_lazyUnmarshalInfo struct {
// Index of fields and their positions in the protobuf for this
// message. Make index be a pointer to a slice so it can be updated
// atomically. The index pointer is only set once (lazily when/if
// the index is first needed), and must always be SET and LOADED
// ATOMICALLY.
index *[]IndexEntry
// The protobuf associated with this lazily decoded message. It is
// only set during proto.Unmarshal(). It doesn't need to be set and
// loaded atomically, since any simultaneous set (Unmarshal) and read
// (during a get) would already be a race in the app code.
Protobuf []byte
// The flags present when Unmarshal was originally called for this particular message
unmarshalFlags piface.UnmarshalInputFlags
}
// The Buffer and SetBuffer methods let v2/internal/impl interact with
// XXX_lazyUnmarshalInfo via an interface, to avoid an import cycle.
// Buffer returns the lazy unmarshal buffer.
//
// Deprecated: Do not use. This will be deleted in the near future.
func (lazy *XXX_lazyUnmarshalInfo) Buffer() []byte {
return lazy.Protobuf
}
// SetBuffer sets the lazy unmarshal buffer.
//
// Deprecated: Do not use. This will be deleted in the near future.
func (lazy *XXX_lazyUnmarshalInfo) SetBuffer(b []byte) {
lazy.Protobuf = b
}
// SetUnmarshalFlags is called to set a copy of the original unmarshalInputFlags.
// The flags should reflect how Unmarshal was called.
func (lazy *XXX_lazyUnmarshalInfo) SetUnmarshalFlags(f piface.UnmarshalInputFlags) {
lazy.unmarshalFlags = f
}
// UnmarshalFlags returns the original unmarshalInputFlags.
func (lazy *XXX_lazyUnmarshalInfo) UnmarshalFlags() piface.UnmarshalInputFlags {
return lazy.unmarshalFlags
}
// AllowedPartial returns true if the user originally unmarshalled this message with
// AllowPartial set to true
func (lazy *XXX_lazyUnmarshalInfo) AllowedPartial() bool {
return (lazy.unmarshalFlags & piface.UnmarshalCheckRequired) == 0
}
func protoFieldNumber(tag uint32) uint32 {
return tag >> 3
}
// buildIndex builds an index of the specified protobuf, return the index
// array and an error.
func buildIndex(buf []byte) ([]IndexEntry, error) {
index := make([]IndexEntry, 0, 16)
var lastProtoFieldNum uint32
var outOfOrder bool
var r BufferReader = NewBufferReader(buf)
for !r.Done() {
var tag uint32
var err error
var curPos = r.Pos
// INLINED: tag, err = r.DecodeVarint32()
{
i := r.Pos
buf := r.Buf
if i >= len(buf) {
return nil, errOutOfBounds
} else if buf[i] < 0x80 {
r.Pos++
tag = uint32(buf[i])
} else if r.Remaining() < 5 {
var v uint64
v, err = r.DecodeVarintSlow()
tag = uint32(v)
} else {
var v uint32
// we already checked the first byte
tag = uint32(buf[i]) & 127
i++
v = uint32(buf[i])
i++
tag |= (v & 127) << 7
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
tag |= (v & 127) << 14
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
tag |= (v & 127) << 21
if v < 128 {
goto done
}
v = uint32(buf[i])
i++
tag |= (v & 127) << 28
if v < 128 {
goto done
}
return nil, errOutOfBounds
done:
r.Pos = i
}
}
// DONE: tag, err = r.DecodeVarint32()
fieldNum := protoFieldNumber(tag)
if fieldNum < lastProtoFieldNum {
outOfOrder = true
}
// Skip the current value -- will skip over an entire group as well.
// INLINED: err = r.SkipValue(tag)
wireType := tag & 0x7
switch protowire.Type(wireType) {
case protowire.VarintType:
// INLINED: err = r.SkipVarint()
i := r.Pos
if len(r.Buf)-i < 10 {
// Use DecodeVarintSlow() to skip while
// checking for buffer overflow, but ignore result
_, err = r.DecodeVarintSlow()
goto out2
}
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
i++
if r.Buf[i] < 0x80 {
goto out
}
return nil, errOverflow
out:
r.Pos = i + 1
// DONE: err = r.SkipVarint()
case protowire.Fixed64Type:
err = r.SkipFixed64()
case protowire.BytesType:
var n uint32
n, err = r.DecodeVarint32()
if err == nil {
err = r.Skip(int(n))
}
case protowire.StartGroupType:
err = r.SkipGroup(tag)
case protowire.Fixed32Type:
err = r.SkipFixed32()
default:
err = fmt.Errorf("Unexpected wire type (%d)", wireType)
}
// DONE: err = r.SkipValue(tag)
out2:
if err != nil {
return nil, err
}
if fieldNum != lastProtoFieldNum {
index = append(index, IndexEntry{FieldNum: fieldNum,
Start: uint32(curPos),
End: uint32(r.Pos)},
)
} else {
index[len(index)-1].End = uint32(r.Pos)
index[len(index)-1].MultipleContiguous = true
}
lastProtoFieldNum = fieldNum
}
if outOfOrder {
sort.Slice(index, func(i, j int) bool {
return index[i].FieldNum < index[j].FieldNum ||
(index[i].FieldNum == index[j].FieldNum &&
index[i].Start < index[j].Start)
})
}
return index, nil
}
func (lazy *XXX_lazyUnmarshalInfo) SizeField(num uint32) (size int) {
start, end, found, _, multipleEntries := lazy.FindFieldInProto(num)
if multipleEntries != nil {
for _, entry := range multipleEntries {
size += int(entry.End - entry.Start)
}
return size
}
if !found {
return 0
}
return int(end - start)
}
func (lazy *XXX_lazyUnmarshalInfo) AppendField(b []byte, num uint32) ([]byte, bool) {
start, end, found, _, multipleEntries := lazy.FindFieldInProto(num)
if multipleEntries != nil {
for _, entry := range multipleEntries {
b = append(b, lazy.Protobuf[entry.Start:entry.End]...)
}
return b, true
}
if !found {
return nil, false
}
b = append(b, lazy.Protobuf[start:end]...)
return b, true
}
func (lazy *XXX_lazyUnmarshalInfo) SetIndex(index []IndexEntry) {
atomicStoreIndex(&lazy.index, &index)
}
// FindFieldInProto looks for field fieldNum in lazyUnmarshalInfo information
// (including protobuf), returns startOffset/endOffset/found.
func (lazy *XXX_lazyUnmarshalInfo) FindFieldInProto(fieldNum uint32) (start, end uint32, found, multipleContiguous bool, multipleEntries []IndexEntry) {
if lazy.Protobuf == nil {
// There is no backing protobuf for this message -- it was made from a builder
return 0, 0, false, false, nil
}
index := atomicLoadIndex(&lazy.index)
if index == nil {
r, err := buildIndex(lazy.Protobuf)
if err != nil {
panic(fmt.Sprintf("findFieldInfo: error building index when looking for field %d: %v", fieldNum, err))
}
// lazy.index is a pointer to the slice returned by BuildIndex
index = &r
atomicStoreIndex(&lazy.index, index)
}
return lookupField(index, fieldNum)
}
// lookupField returns the offset at which the indicated field starts using
// the index, offset immediately after field ends (including all instances of
// a repeated field), and bools indicating if field was found and if there
// are multiple encodings of the field in the byte range.
//
// To hande the uncommon case where there are repeated encodings for the same
// field which are not consecutive in the protobuf (so we need to returns
// multiple start/end offsets), we also return a slice multipleEntries. If
// multipleEntries is non-nil, then multiple entries were found, and the
// values in the slice should be used, rather than start/end/found.
func lookupField(indexp *[]IndexEntry, fieldNum uint32) (start, end uint32, found bool, multipleContiguous bool, multipleEntries []IndexEntry) {
// The pointer indexp to the index was already loaded atomically.
// The slice is uniquely associated with the pointer, so it doesn't
// need to be loaded atomically.
index := *indexp
for i, entry := range index {
if fieldNum == entry.FieldNum {
if i < len(index)-1 && entry.FieldNum == index[i+1].FieldNum {
// Handle the uncommon case where there are
// repeated entries for the same field which
// are not contiguous in the protobuf.
multiple := make([]IndexEntry, 1, 2)
multiple[0] = IndexEntry{fieldNum, entry.Start, entry.End, entry.MultipleContiguous}
i++
for i < len(index) && index[i].FieldNum == fieldNum {
multiple = append(multiple, IndexEntry{fieldNum, index[i].Start, index[i].End, index[i].MultipleContiguous})
i++
}
return 0, 0, false, false, multiple
}
return entry.Start, entry.End, true, entry.MultipleContiguous, nil
}
if fieldNum < entry.FieldNum {
return 0, 0, false, false, nil
}
}
return 0, 0, false, false, nil
}

View File

@ -0,0 +1,17 @@
// 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 protolazy
import (
"sync/atomic"
"unsafe"
)
func atomicLoadIndex(p **[]IndexEntry) *[]IndexEntry {
return (*[]IndexEntry)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
}
func atomicStoreIndex(p **[]IndexEntry, v *[]IndexEntry) {
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
}

View File

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

View File

@ -1,94 +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 !go1.21
package strs
import (
"unsafe"
"google.golang.org/protobuf/reflect/protoreflect"
)
type (
stringHeader struct {
Data unsafe.Pointer
Len int
}
sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
)
// UnsafeString returns an unsafe string reference of b.
// The caller must treat the input slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user
// unless the input slice is provably immutable.
func UnsafeString(b []byte) (s string) {
src := (*sliceHeader)(unsafe.Pointer(&b))
dst := (*stringHeader)(unsafe.Pointer(&s))
dst.Data = src.Data
dst.Len = src.Len
return s
}
// UnsafeBytes returns an unsafe bytes slice reference of s.
// The caller must treat returned slice as immutable.
//
// WARNING: Use carefully. The returned result must not leak to the end user.
func UnsafeBytes(s string) (b []byte) {
src := (*stringHeader)(unsafe.Pointer(&s))
dst := (*sliceHeader)(unsafe.Pointer(&b))
dst.Data = src.Data
dst.Len = src.Len
dst.Cap = src.Len
return b
}
// Builder builds a set of strings with shared lifetime.
// This differs from strings.Builder, which is for building a single string.
type Builder struct {
buf []byte
}
// AppendFullName is equivalent to protoreflect.FullName.Append,
// but optimized for large batches where each name has a shared lifetime.
func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
n := len(prefix) + len(".") + len(name)
if len(prefix) == 0 {
n -= len(".")
}
sb.grow(n)
sb.buf = append(sb.buf, prefix...)
sb.buf = append(sb.buf, '.')
sb.buf = append(sb.buf, name...)
return protoreflect.FullName(sb.last(n))
}
// MakeString is equivalent to string(b), but optimized for large batches
// with a shared lifetime.
func (sb *Builder) MakeString(b []byte) string {
sb.grow(len(b))
sb.buf = append(sb.buf, b...)
return sb.last(len(b))
}
func (sb *Builder) grow(n int) {
if cap(sb.buf)-len(sb.buf) >= n {
return
}
// Unlike strings.Builder, we do not need to copy over the contents
// of the old buffer since our builder provides no API for
// retrieving previously created strings.
sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n))
}
func (sb *Builder) last(n int) string {
return UnsafeString(sb.buf[len(sb.buf)-n:])
}

View File

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

View File

@ -8,7 +8,6 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
@ -47,6 +46,12 @@ type UnmarshalOptions struct {
// RecursionLimit limits how deeply messages may be nested. // RecursionLimit limits how deeply messages may be nested.
// If zero, a default limit is applied. // If zero, a default limit is applied.
RecursionLimit int RecursionLimit int
//
// NoLazyDecoding turns off lazy decoding, which otherwise is enabled by
// default. Lazy decoding only affects submessages (annotated with [lazy =
// true] in the .proto file) within messages that use the Opaque API.
NoLazyDecoding bool
} }
// Unmarshal parses the wire-format message in b and places the result in m. // Unmarshal parses the wire-format message in b and places the result in m.
@ -104,6 +109,16 @@ func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out proto
if o.DiscardUnknown { if o.DiscardUnknown {
in.Flags |= protoiface.UnmarshalDiscardUnknown in.Flags |= protoiface.UnmarshalDiscardUnknown
} }
if !allowPartial {
// This does not affect how current unmarshal functions work, it just allows them
// to record this for lazy the decoding case.
in.Flags |= protoiface.UnmarshalCheckRequired
}
if o.NoLazyDecoding {
in.Flags |= protoiface.UnmarshalNoLazyDecoding
}
out, err = methods.Unmarshal(in) out, err = methods.Unmarshal(in)
} else { } else {
o.RecursionLimit-- o.RecursionLimit--
@ -156,10 +171,6 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message)
var err error var err error
if fd == nil { if fd == nil {
err = errUnknown err = errUnknown
} else if flags.ProtoLegacy {
if fd.IsWeak() && fd.Message().IsPlaceholder() {
err = errUnknown // weak referent is not linked in
}
} }
// Parse the field value. // Parse the field value.

View File

@ -63,7 +63,8 @@ type MarshalOptions struct {
// options (except for UseCachedSize itself). // options (except for UseCachedSize itself).
// //
// 2. The message and all its submessages have not changed in any // 2. The message and all its submessages have not changed in any
// way since the Size call. // way since the Size call. For lazily decoded messages, accessing
// a message results in decoding the message, which is a change.
// //
// If either of these invariants is violated, // If either of these invariants is violated,
// the results are undefined and may include panics or corrupted output. // the results are undefined and may include panics or corrupted output.

View File

@ -59,6 +59,12 @@ func Clone(m Message) Message {
return dst.Interface() return dst.Interface()
} }
// CloneOf returns a deep copy of m. If the top-level message is invalid,
// it returns an invalid message as well.
func CloneOf[M Message](m M) M {
return Clone(m).(M)
}
// mergeOptions provides a namespace for merge functions, and can be // mergeOptions provides a namespace for merge functions, and can be
// exported in the future if we add user-visible merge options. // exported in the future if we add user-visible merge options.
type mergeOptions struct{} type mergeOptions struct{}

View File

@ -12,11 +12,19 @@ import (
) )
// Size returns the size in bytes of the wire-format encoding of m. // Size returns the size in bytes of the wire-format encoding of m.
//
// Note that Size might return more bytes than Marshal will write in the case of
// lazily decoded messages that arrive in non-minimal wire format: see
// https://protobuf.dev/reference/go/size/ for more details.
func Size(m Message) int { func Size(m Message) int {
return MarshalOptions{}.Size(m) return MarshalOptions{}.Size(m)
} }
// Size returns the size in bytes of the wire-format encoding of m. // Size returns the size in bytes of the wire-format encoding of m.
//
// Note that Size might return more bytes than Marshal will write in the case of
// lazily decoded messages that arrive in non-minimal wire format: see
// https://protobuf.dev/reference/go/size/ for more details.
func (o MarshalOptions) Size(m Message) int { func (o MarshalOptions) Size(m Message) int {
// Treat a nil message interface as an empty message; nothing to output. // Treat a nil message interface as an empty message; nothing to output.
if m == nil { if m == nil {

View File

@ -0,0 +1,80 @@
// 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 proto
// ValueOrNil returns nil if has is false, or a pointer to a new variable
// containing the value returned by the specified getter.
//
// This function is similar to the wrappers (proto.Int32(), proto.String(),
// etc.), but is generic (works for any field type) and works with the hasser
// and getter of a field, as opposed to a value.
//
// This is convenient when populating builder fields.
//
// Example:
//
// hop := attr.GetDirectHop()
// injectedRoute := ripb.InjectedRoute_builder{
// Prefixes: route.GetPrefixes(),
// NextHop: proto.ValueOrNil(hop.HasAddress(), hop.GetAddress),
// }
func ValueOrNil[T any](has bool, getter func() T) *T {
if !has {
return nil
}
v := getter()
return &v
}
// ValueOrDefault returns the protobuf message val if val is not nil, otherwise
// it returns a pointer to an empty val message.
//
// This function allows for translating code from the old Open Struct API to the
// new Opaque API.
//
// The old Open Struct API represented oneof fields with a wrapper struct:
//
// var signedImg *accountpb.SignedImage
// profile := &accountpb.Profile{
// // The Avatar oneof will be set, with an empty SignedImage.
// Avatar: &accountpb.Profile_SignedImage{signedImg},
// }
//
// The new Opaque API treats oneof fields like regular fields, there are no more
// wrapper structs:
//
// var signedImg *accountpb.SignedImage
// profile := &accountpb.Profile{}
// profile.SetSignedImage(signedImg)
//
// For convenience, the Opaque API also offers Builders, which allow for a
// direct translation of struct initialization. However, because Builders use
// nilness to represent field presence (but there is no non-nil wrapper struct
// anymore), Builders cannot distinguish between an unset oneof and a set oneof
// with nil message. The above code would need to be translated with help of the
// ValueOrDefault function to retain the same behavior:
//
// var signedImg *accountpb.SignedImage
// return &accountpb.Profile_builder{
// SignedImage: proto.ValueOrDefault(signedImg),
// }.Build()
func ValueOrDefault[T interface {
*P
Message
}, P any](val T) T {
if val == nil {
return T(new(P))
}
return val
}
// ValueOrDefaultBytes is like ValueOrDefault but for working with fields of
// type []byte.
func ValueOrDefaultBytes(val []byte) []byte {
if val == nil {
return []byte{}
}
return val
}

View File

@ -132,17 +132,11 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot
} }
f.L2.Imports[i].IsPublic = true f.L2.Imports[i].IsPublic = true
} }
for _, i := range fd.GetWeakDependency() {
if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak {
return nil, errors.New("invalid or duplicate weak import index: %d", i)
}
f.L2.Imports[i].IsWeak = true
}
imps := importSet{f.Path(): true} imps := importSet{f.Path(): true}
for i, path := range fd.GetDependency() { for i, path := range fd.GetDependency() {
imp := &f.L2.Imports[i] imp := &f.L2.Imports[i]
f, err := r.FindFileByPath(path) f, err := r.FindFileByPath(path)
if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) { if err == protoregistry.NotFound && o.AllowUnresolvable {
f = filedesc.PlaceholderFile(path) f = filedesc.PlaceholderFile(path)
} else if err != nil { } else if err != nil {
return nil, errors.New("could not resolve import %q: %v", path, err) return nil, errors.New("could not resolve import %q: %v", path, err)

View File

@ -149,7 +149,6 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc
if opts := fd.GetOptions(); opts != nil { if opts := fd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FieldOptions) opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
f.L1.Options = func() protoreflect.ProtoMessage { return opts } f.L1.Options = func() protoreflect.ProtoMessage { return opts }
f.L1.IsWeak = opts.GetWeak()
f.L1.IsLazy = opts.GetLazy() f.L1.IsLazy = opts.GetLazy()
if opts.Packed != nil { if opts.Packed != nil {
f.L1.EditionFeatures.IsPacked = opts.GetPacked() f.L1.EditionFeatures.IsPacked = opts.GetPacked()

View File

@ -43,7 +43,7 @@ func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*desc
o.L1.Fields.List = append(o.L1.Fields.List, f) o.L1.Fields.List = append(o.L1.Fields.List, f)
} }
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 { if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName())); err != nil {
return errors.New("message field %q cannot resolve type: %v", f.FullName(), err) return errors.New("message field %q cannot resolve type: %v", f.FullName(), err)
} }
if f.L1.Kind == protoreflect.GroupKind && (f.IsMap() || f.IsMapEntry()) { if f.L1.Kind == protoreflect.GroupKind && (f.IsMap() || f.IsMapEntry()) {
@ -73,10 +73,10 @@ func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*desc
func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) { func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) {
for i, xd := range xds { for i, xd := range xds {
x := &xs[i] x := &xs[i]
if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee()), false); err != nil { if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee())); err != nil {
return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err) return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err)
} }
if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName()), false); err != nil { if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName())); err != nil {
return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err) return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err)
} }
if xd.DefaultValue != nil { if xd.DefaultValue != nil {
@ -95,11 +95,11 @@ func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*desc
s := &ss[i] s := &ss[i]
for j, md := range sd.GetMethod() { for j, md := range sd.GetMethod() {
m := &s.L2.Methods.List[j] m := &s.L2.Methods.List[j]
m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()), false) m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()))
if err != nil { if err != nil {
return errors.New("service method %q cannot resolve input: %v", m.FullName(), err) return errors.New("service method %q cannot resolve input: %v", m.FullName(), err)
} }
m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()), false) m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()))
if err != nil { if err != nil {
return errors.New("service method %q cannot resolve output: %v", m.FullName(), err) return errors.New("service method %q cannot resolve output: %v", m.FullName(), err)
} }
@ -111,16 +111,16 @@ func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*desc
// findTarget finds an enum or message descriptor if k is an enum, message, // findTarget finds an enum or message descriptor if k is an enum, message,
// group, or unknown. If unknown, and the name could be resolved, the kind // group, or unknown. If unknown, and the name could be resolved, the kind
// returned kind is set based on the type of the resolved descriptor. // returned kind is set based on the type of the resolved descriptor.
func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) { func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) {
switch k { switch k {
case protoreflect.EnumKind: case protoreflect.EnumKind:
ed, err := r.findEnumDescriptor(scope, ref, isWeak) ed, err := r.findEnumDescriptor(scope, ref)
if err != nil { if err != nil {
return 0, nil, nil, err return 0, nil, nil, err
} }
return k, ed, nil, nil return k, ed, nil, nil
case protoreflect.MessageKind, protoreflect.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
md, err := r.findMessageDescriptor(scope, ref, isWeak) md, err := r.findMessageDescriptor(scope, ref)
if err != nil { if err != nil {
return 0, nil, nil, err return 0, nil, nil, err
} }
@ -129,7 +129,7 @@ func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName,
// Handle unspecified kinds (possible with parsers that operate // Handle unspecified kinds (possible with parsers that operate
// on a per-file basis without knowledge of dependencies). // on a per-file basis without knowledge of dependencies).
d, err := r.findDescriptor(scope, ref) d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { if err == protoregistry.NotFound && r.allowUnresolvable {
return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil
} else if err == protoregistry.NotFound { } else if err == protoregistry.NotFound {
return 0, nil, nil, errors.New("%q not found", ref.FullName()) return 0, nil, nil, errors.New("%q not found", ref.FullName())
@ -206,9 +206,9 @@ func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName)
} }
} }
func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.EnumDescriptor, error) { func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.EnumDescriptor, error) {
d, err := r.findDescriptor(scope, ref) d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { if err == protoregistry.NotFound && r.allowUnresolvable {
return filedesc.PlaceholderEnum(ref.FullName()), nil return filedesc.PlaceholderEnum(ref.FullName()), nil
} else if err == protoregistry.NotFound { } else if err == protoregistry.NotFound {
return nil, errors.New("%q not found", ref.FullName()) return nil, errors.New("%q not found", ref.FullName())
@ -222,9 +222,9 @@ func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialNa
return ed, nil return ed, nil
} }
func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.MessageDescriptor, error) { func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.MessageDescriptor, error) {
d, err := r.findDescriptor(scope, ref) d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { if err == protoregistry.NotFound && r.allowUnresolvable {
return filedesc.PlaceholderMessage(ref.FullName()), nil return filedesc.PlaceholderMessage(ref.FullName()), nil
} else if err == protoregistry.NotFound { } else if err == protoregistry.NotFound {
return nil, errors.New("%q not found", ref.FullName()) return nil, errors.New("%q not found", ref.FullName())

View File

@ -149,12 +149,6 @@ func validateMessageDeclarations(file *filedesc.File, ms []filedesc.Message, mds
return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName()) return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName())
} }
} }
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.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) { if f.IsPacked() && !isPackable(f) {
return errors.New("message field %q is not packable", f.FullName()) return errors.New("message field %q is not packable", f.FullName())
} }
@ -199,9 +193,6 @@ func validateMessageDeclarations(file *filedesc.File, ms []filedesc.Message, mds
if f.Cardinality() != protoreflect.Optional { if f.Cardinality() != protoreflect.Optional {
return errors.New("message field %q belongs in a oneof and must be optional", f.FullName()) return errors.New("message field %q belongs in a oneof and must be optional", f.FullName())
} }
if f.IsWeak() {
return errors.New("message field %q belongs in a oneof and must not be a weak reference", f.FullName())
}
} }
} }
@ -254,9 +245,6 @@ func validateExtensionDeclarations(f *filedesc.File, xs []filedesc.Extension, xd
return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number()) return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
} }
} }
if xd.GetOptions().GetWeak() {
return errors.New("extension field %q cannot be a weak reference", x.FullName())
}
if x.IsPacked() && !isPackable(x) { if x.IsPacked() && !isPackable(x) {
return errors.New("extension field %q is not packable", x.FullName()) return errors.New("extension field %q is not packable", x.FullName())
} }

View File

@ -11,6 +11,7 @@ import (
"google.golang.org/protobuf/internal/editiondefaults" "google.golang.org/protobuf/internal/editiondefaults"
"google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/descriptorpb"
@ -125,13 +126,43 @@ func mergeEditionFeatures(parentDesc protoreflect.Descriptor, child *descriptorp
parentFS.IsJSONCompliant = *jf == descriptorpb.FeatureSet_ALLOW parentFS.IsJSONCompliant = *jf == descriptorpb.FeatureSet_ALLOW
} }
if goFeatures, ok := proto.GetExtension(child, gofeaturespb.E_Go).(*gofeaturespb.GoFeatures); ok && goFeatures != nil { // We must not use proto.GetExtension(child, gofeaturespb.E_Go)
if luje := goFeatures.LegacyUnmarshalJsonEnum; luje != nil { // because that only works for messages we generated, but not for
parentFS.GenerateLegacyUnmarshalJSON = *luje // dynamicpb messages. See golang/protobuf#1669.
} //
if sep := goFeatures.StripEnumPrefix; sep != nil { // Further, we harden this code against adversarial inputs: a
parentFS.StripEnumPrefix = int(*sep) // service which accepts descriptors from a possibly malicious
} // source shouldn't crash.
goFeatures := child.ProtoReflect().Get(gofeaturespb.E_Go.TypeDescriptor())
if !goFeatures.IsValid() {
return parentFS
}
gf, ok := goFeatures.Interface().(protoreflect.Message)
if !ok {
return parentFS
}
// gf.Interface() could be *dynamicpb.Message or *gofeaturespb.GoFeatures.
fields := gf.Descriptor().Fields()
if fd := fields.ByNumber(genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number); fd != nil &&
!fd.IsList() &&
fd.Kind() == protoreflect.BoolKind &&
gf.Has(fd) {
parentFS.GenerateLegacyUnmarshalJSON = gf.Get(fd).Bool()
}
if fd := fields.ByNumber(genid.GoFeatures_StripEnumPrefix_field_number); fd != nil &&
!fd.IsList() &&
fd.Kind() == protoreflect.EnumKind &&
gf.Has(fd) {
parentFS.StripEnumPrefix = int(gf.Get(fd).Enum())
}
if fd := fields.ByNumber(genid.GoFeatures_ApiLevel_field_number); fd != nil &&
!fd.IsList() &&
fd.Kind() == protoreflect.EnumKind &&
gf.Has(fd) {
parentFS.APILevel = int(gf.Get(fd).Enum())
} }
return parentFS return parentFS

View File

@ -32,9 +32,6 @@ func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileD
if imp.IsPublic { if imp.IsPublic {
p.PublicDependency = append(p.PublicDependency, int32(i)) p.PublicDependency = append(p.PublicDependency, int32(i))
} }
if imp.IsWeak {
p.WeakDependency = append(p.WeakDependency, int32(i))
}
} }
for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ { for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ {
loc := locs.Get(i) loc := locs.Get(i)

View File

@ -398,6 +398,8 @@ func (p *SourcePath) appendFeatureSet(b []byte) []byte {
b = p.appendSingularField(b, "message_encoding", nil) b = p.appendSingularField(b, "message_encoding", nil)
case 6: case 6:
b = p.appendSingularField(b, "json_format", nil) b = p.appendSingularField(b, "json_format", nil)
case 7:
b = p.appendSingularField(b, "enforce_naming_style", nil)
} }
return b return b
} }

View File

@ -68,7 +68,7 @@ type Descriptor interface {
// dependency is not resolved, in which case only name information is known. // dependency is not resolved, in which case only name information is known.
// //
// Placeholder types may only be returned by the following accessors // Placeholder types may only be returned by the following accessors
// as a result of unresolved dependencies or weak imports: // as a result of unresolved dependencies:
// //
// ╔═══════════════════════════════════╤═════════════════════╗ // ╔═══════════════════════════════════╤═════════════════════╗
// ║ Accessor │ Descriptor ║ // ║ Accessor │ Descriptor ║
@ -168,11 +168,7 @@ type FileImport struct {
// The current file and the imported file must be within proto package. // The current file and the imported file must be within proto package.
IsPublic bool IsPublic bool
// IsWeak reports whether this is a weak import, which does not impose // Deprecated: support for weak fields has been removed.
// a direct dependency on the target file.
//
// Weak imports are a legacy proto1 feature. Equivalent behavior is
// achieved using proto2 extension fields or proto3 Any messages.
IsWeak bool IsWeak bool
} }
@ -325,9 +321,7 @@ type FieldDescriptor interface {
// specified in the source .proto file. // specified in the source .proto file.
HasOptionalKeyword() bool HasOptionalKeyword() bool
// IsWeak reports whether this is a weak field, which does not impose a // Deprecated: support for weak fields has been removed.
// direct dependency on the target type.
// If true, then Message returns a placeholder type.
IsWeak() bool IsWeak() bool
// IsPacked reports whether repeated primitive numeric kinds should be // IsPacked reports whether repeated primitive numeric kinds should be

View File

@ -152,7 +152,7 @@ type Message interface {
// This method may return nil. // This method may return nil.
// //
// The returned methods type is identical to // The returned methods type is identical to
// google.golang.org/protobuf/runtime/protoiface.Methods. // [google.golang.org/protobuf/runtime/protoiface.Methods].
// Consult the protoiface package documentation for details. // Consult the protoiface package documentation for details.
ProtoMethods() *methods ProtoMethods() *methods
} }

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.21
package protoreflect package protoreflect
import ( import (

View File

@ -1,98 +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 !go1.21
package protoreflect
import (
"unsafe"
"google.golang.org/protobuf/internal/pragma"
)
type (
stringHeader struct {
Data unsafe.Pointer
Len int
}
sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
ifaceHeader struct {
Type unsafe.Pointer
Data unsafe.Pointer
}
)
var (
nilType = typeOf(nil)
boolType = typeOf(*new(bool))
int32Type = typeOf(*new(int32))
int64Type = typeOf(*new(int64))
uint32Type = typeOf(*new(uint32))
uint64Type = typeOf(*new(uint64))
float32Type = typeOf(*new(float32))
float64Type = typeOf(*new(float64))
stringType = typeOf(*new(string))
bytesType = typeOf(*new([]byte))
enumType = typeOf(*new(EnumNumber))
)
// 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 any) unsafe.Pointer {
return (*ifaceHeader)(unsafe.Pointer(&t)).Type
}
// value is a union where only one type can be represented at a time.
// The struct is 24B large on 64-bit systems and requires the minimum storage
// necessary to represent each possible type.
//
// The Go GC needs to be able to scan variables containing pointers.
// As such, pointers and non-pointers cannot be intermixed.
type value struct {
pragma.DoNotCompare // 0B
// typ stores the type of the value as a pointer to the Go type.
typ unsafe.Pointer // 8B
// ptr stores the data pointer for a String, Bytes, or interface value.
ptr unsafe.Pointer // 8B
// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
// Enum value as a raw uint64.
//
// It is also used to store the length of a String or Bytes value;
// the capacity is ignored.
num uint64 // 8B
}
func valueOfString(v string) Value {
p := (*stringHeader)(unsafe.Pointer(&v))
return Value{typ: stringType, ptr: p.Data, num: uint64(len(v))}
}
func valueOfBytes(v []byte) Value {
p := (*sliceHeader)(unsafe.Pointer(&v))
return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))}
}
func valueOfIface(v any) Value {
p := (*ifaceHeader)(unsafe.Pointer(&v))
return Value{typ: p.Type, ptr: p.Data}
}
func (v Value) getString() (x string) {
*(*stringHeader)(unsafe.Pointer(&x)) = stringHeader{Data: v.ptr, Len: int(v.num)}
return x
}
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 any) {
*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
return x
}

View File

@ -122,6 +122,22 @@ type UnmarshalInputFlags = uint8
const ( const (
UnmarshalDiscardUnknown UnmarshalInputFlags = 1 << iota UnmarshalDiscardUnknown UnmarshalInputFlags = 1 << iota
// UnmarshalAliasBuffer permits unmarshal operations to alias the input buffer.
// The unmarshaller must not modify the contents of the buffer.
UnmarshalAliasBuffer
// UnmarshalValidated indicates that validation has already been
// performed on the input buffer.
UnmarshalValidated
// UnmarshalCheckRequired is set if this unmarshal operation ultimately will care if required fields are
// initialized.
UnmarshalCheckRequired
// UnmarshalNoLazyDecoding is set if this unmarshal operation should not use
// lazy decoding, even when otherwise available.
UnmarshalNoLazyDecoding
) )
// UnmarshalOutputFlags are output from the Unmarshal method. // UnmarshalOutputFlags are output from the Unmarshal method.

View File

@ -15,6 +15,7 @@ import (
"google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/filetype" "google.golang.org/protobuf/internal/filetype"
"google.golang.org/protobuf/internal/impl" "google.golang.org/protobuf/internal/impl"
"google.golang.org/protobuf/internal/protolazy"
) )
// UnsafeEnabled specifies whether package unsafe can be used. // UnsafeEnabled specifies whether package unsafe can be used.
@ -39,6 +40,9 @@ type (
ExtensionFieldV1 = impl.ExtensionField ExtensionFieldV1 = impl.ExtensionField
Pointer = impl.Pointer Pointer = impl.Pointer
LazyUnmarshalInfo = *protolazy.XXX_lazyUnmarshalInfo
RaceDetectHookData = impl.RaceDetectHookData
) )
var X impl.Export var X impl.Export

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,74 @@ import (
descriptorpb "google.golang.org/protobuf/types/descriptorpb" descriptorpb "google.golang.org/protobuf/types/descriptorpb"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
unsafe "unsafe"
) )
type GoFeatures_APILevel int32
const (
// API_LEVEL_UNSPECIFIED results in selecting the OPEN API,
// but needs to be a separate value to distinguish between
// an explicitly set api level or a missing api level.
GoFeatures_API_LEVEL_UNSPECIFIED GoFeatures_APILevel = 0
GoFeatures_API_OPEN GoFeatures_APILevel = 1
GoFeatures_API_HYBRID GoFeatures_APILevel = 2
GoFeatures_API_OPAQUE GoFeatures_APILevel = 3
)
// Enum value maps for GoFeatures_APILevel.
var (
GoFeatures_APILevel_name = map[int32]string{
0: "API_LEVEL_UNSPECIFIED",
1: "API_OPEN",
2: "API_HYBRID",
3: "API_OPAQUE",
}
GoFeatures_APILevel_value = map[string]int32{
"API_LEVEL_UNSPECIFIED": 0,
"API_OPEN": 1,
"API_HYBRID": 2,
"API_OPAQUE": 3,
}
)
func (x GoFeatures_APILevel) Enum() *GoFeatures_APILevel {
p := new(GoFeatures_APILevel)
*p = x
return p
}
func (x GoFeatures_APILevel) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (GoFeatures_APILevel) Descriptor() protoreflect.EnumDescriptor {
return file_google_protobuf_go_features_proto_enumTypes[0].Descriptor()
}
func (GoFeatures_APILevel) Type() protoreflect.EnumType {
return &file_google_protobuf_go_features_proto_enumTypes[0]
}
func (x GoFeatures_APILevel) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Do not use.
func (x *GoFeatures_APILevel) UnmarshalJSON(b []byte) error {
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
*x = GoFeatures_APILevel(num)
return nil
}
// Deprecated: Use GoFeatures_APILevel.Descriptor instead.
func (GoFeatures_APILevel) EnumDescriptor() ([]byte, []int) {
return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0, 0}
}
type GoFeatures_StripEnumPrefix int32 type GoFeatures_StripEnumPrefix int32
const ( const (
@ -54,11 +120,11 @@ func (x GoFeatures_StripEnumPrefix) String() string {
} }
func (GoFeatures_StripEnumPrefix) Descriptor() protoreflect.EnumDescriptor { func (GoFeatures_StripEnumPrefix) Descriptor() protoreflect.EnumDescriptor {
return file_google_protobuf_go_features_proto_enumTypes[0].Descriptor() return file_google_protobuf_go_features_proto_enumTypes[1].Descriptor()
} }
func (GoFeatures_StripEnumPrefix) Type() protoreflect.EnumType { func (GoFeatures_StripEnumPrefix) Type() protoreflect.EnumType {
return &file_google_protobuf_go_features_proto_enumTypes[0] return &file_google_protobuf_go_features_proto_enumTypes[1]
} }
func (x GoFeatures_StripEnumPrefix) Number() protoreflect.EnumNumber { func (x GoFeatures_StripEnumPrefix) Number() protoreflect.EnumNumber {
@ -77,17 +143,19 @@ func (x *GoFeatures_StripEnumPrefix) UnmarshalJSON(b []byte) error {
// Deprecated: Use GoFeatures_StripEnumPrefix.Descriptor instead. // Deprecated: Use GoFeatures_StripEnumPrefix.Descriptor instead.
func (GoFeatures_StripEnumPrefix) EnumDescriptor() ([]byte, []int) { func (GoFeatures_StripEnumPrefix) EnumDescriptor() ([]byte, []int) {
return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0, 0} return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0, 1}
} }
type GoFeatures struct { type GoFeatures struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Whether or not to generate the deprecated UnmarshalJSON method for enums. // 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"` // Can only be true for proto using the Open Struct api.
StripEnumPrefix *GoFeatures_StripEnumPrefix `protobuf:"varint,3,opt,name=strip_enum_prefix,json=stripEnumPrefix,enum=pb.GoFeatures_StripEnumPrefix" json:"strip_enum_prefix,omitempty"` LegacyUnmarshalJsonEnum *bool `protobuf:"varint,1,opt,name=legacy_unmarshal_json_enum,json=legacyUnmarshalJsonEnum" json:"legacy_unmarshal_json_enum,omitempty"`
// One of OPEN, HYBRID or OPAQUE.
ApiLevel *GoFeatures_APILevel `protobuf:"varint,2,opt,name=api_level,json=apiLevel,enum=pb.GoFeatures_APILevel" json:"api_level,omitempty"`
StripEnumPrefix *GoFeatures_StripEnumPrefix `protobuf:"varint,3,opt,name=strip_enum_prefix,json=stripEnumPrefix,enum=pb.GoFeatures_StripEnumPrefix" json:"strip_enum_prefix,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
func (x *GoFeatures) Reset() { func (x *GoFeatures) Reset() {
@ -127,6 +195,13 @@ func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool {
return false return false
} }
func (x *GoFeatures) GetApiLevel() GoFeatures_APILevel {
if x != nil && x.ApiLevel != nil {
return *x.ApiLevel
}
return GoFeatures_API_LEVEL_UNSPECIFIED
}
func (x *GoFeatures) GetStripEnumPrefix() GoFeatures_StripEnumPrefix { func (x *GoFeatures) GetStripEnumPrefix() GoFeatures_StripEnumPrefix {
if x != nil && x.StripEnumPrefix != nil { if x != nil && x.StripEnumPrefix != nil {
return *x.StripEnumPrefix return *x.StripEnumPrefix
@ -153,79 +228,60 @@ var (
var File_google_protobuf_go_features_proto protoreflect.FileDescriptor var File_google_protobuf_go_features_proto protoreflect.FileDescriptor
var file_google_protobuf_go_features_proto_rawDesc = []byte{ const file_google_protobuf_go_features_proto_rawDesc = "" +
0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, "!google/protobuf/go_features.proto\x12\x02pb\x1a google/protobuf/descriptor.proto\"\xab\x05\n" +
0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, "\n" +
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, "GoFeatures\x12\xbe\x01\n" +
0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x03, 0x0a, 0x0a, 0x47, 0x6f, "\x1alegacy_unmarshal_json_enum\x18\x01 \x01(\bB\x80\x01\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\t\x12\x04true\x18\x84\a\xa2\x01\n" +
0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x1a, 0x6c, 0x65, 0x67, "\x12\x05false\x18\xe7\a\xb2\x01[\b\xe8\a\x10\xe8\a\x1aSThe legacy UnmarshalJSON API is deprecated and will be removed in a future edition.R\x17legacyUnmarshalJsonEnum\x12t\n" +
0x61, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x5f, 0x6a, 0x73, "\tapi_level\x18\x02 \x01(\x0e2\x17.pb.GoFeatures.APILevelB>\x88\x01\x01\x98\x01\x03\x98\x01\x01\xa2\x01\x1a\x12\x15API_LEVEL_UNSPECIFIED\x18\x84\a\xa2\x01\x0f\x12\n" +
0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x80, 0x01, "API_OPAQUE\x18\xe9\a\xb2\x01\x03\b\xe8\aR\bapiLevel\x12|\n" +
0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72, "\x11strip_enum_prefix\x18\x03 \x01(\x0e2\x1e.pb.GoFeatures.StripEnumPrefixB0\x88\x01\x01\x98\x01\x06\x98\x01\a\x98\x01\x01\xa2\x01\x1b\x12\x16STRIP_ENUM_PREFIX_KEEP\x18\x84\a\xb2\x01\x03\b\xe9\aR\x0fstripEnumPrefix\"S\n" +
0x75, 0x65, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18, "\bAPILevel\x12\x19\n" +
0xe7, 0x07, 0xb2, 0x01, 0x5b, 0x08, 0xe8, 0x07, 0x10, 0xe8, 0x07, 0x1a, 0x53, 0x54, 0x68, 0x65, "\x15API_LEVEL_UNSPECIFIED\x10\x00\x12\f\n" +
0x20, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x20, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, "\bAPI_OPEN\x10\x01\x12\x0e\n" +
0x6c, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x41, 0x50, 0x49, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, "\n" +
0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c, "API_HYBRID\x10\x02\x12\x0e\n" +
0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, "\n" +
0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x20, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, "API_OPAQUE\x10\x03\"\x92\x01\n" +
0x52, 0x17, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, "\x0fStripEnumPrefix\x12!\n" +
0x6c, 0x4a, 0x73, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x7c, 0x0a, 0x11, 0x73, 0x74, 0x72, "\x1dSTRIP_ENUM_PREFIX_UNSPECIFIED\x10\x00\x12\x1a\n" +
0x69, 0x70, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, "\x16STRIP_ENUM_PREFIX_KEEP\x10\x01\x12#\n" +
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, "\x1fSTRIP_ENUM_PREFIX_GENERATE_BOTH\x10\x02\x12\x1b\n" +
0x75, 0x72, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x70, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, "\x17STRIP_ENUM_PREFIX_STRIP\x10\x03:<\n" +
0x65, 0x66, 0x69, 0x78, 0x42, 0x30, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x07, 0x98, "\x02go\x12\x1b.google.protobuf.FeatureSet\x18\xea\a \x01(\v2\x0e.pb.GoFeaturesR\x02goB/Z-google.golang.org/protobuf/types/gofeaturespb"
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 ( var (
file_google_protobuf_go_features_proto_rawDescOnce sync.Once file_google_protobuf_go_features_proto_rawDescOnce sync.Once
file_google_protobuf_go_features_proto_rawDescData = file_google_protobuf_go_features_proto_rawDesc file_google_protobuf_go_features_proto_rawDescData []byte
) )
func file_google_protobuf_go_features_proto_rawDescGZIP() []byte { func file_google_protobuf_go_features_proto_rawDescGZIP() []byte {
file_google_protobuf_go_features_proto_rawDescOnce.Do(func() { 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) file_google_protobuf_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_go_features_proto_rawDesc), len(file_google_protobuf_go_features_proto_rawDesc)))
}) })
return file_google_protobuf_go_features_proto_rawDescData return file_google_protobuf_go_features_proto_rawDescData
} }
var file_google_protobuf_go_features_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_google_protobuf_go_features_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_google_protobuf_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_google_protobuf_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_protobuf_go_features_proto_goTypes = []any{ var file_google_protobuf_go_features_proto_goTypes = []any{
(GoFeatures_StripEnumPrefix)(0), // 0: pb.GoFeatures.StripEnumPrefix (GoFeatures_APILevel)(0), // 0: pb.GoFeatures.APILevel
(*GoFeatures)(nil), // 1: pb.GoFeatures (GoFeatures_StripEnumPrefix)(0), // 1: pb.GoFeatures.StripEnumPrefix
(*descriptorpb.FeatureSet)(nil), // 2: google.protobuf.FeatureSet (*GoFeatures)(nil), // 2: pb.GoFeatures
(*descriptorpb.FeatureSet)(nil), // 3: google.protobuf.FeatureSet
} }
var file_google_protobuf_go_features_proto_depIdxs = []int32{ var file_google_protobuf_go_features_proto_depIdxs = []int32{
0, // 0: pb.GoFeatures.strip_enum_prefix:type_name -> pb.GoFeatures.StripEnumPrefix 0, // 0: pb.GoFeatures.api_level:type_name -> pb.GoFeatures.APILevel
2, // 1: pb.go:extendee -> google.protobuf.FeatureSet 1, // 1: pb.GoFeatures.strip_enum_prefix:type_name -> pb.GoFeatures.StripEnumPrefix
1, // 2: pb.go:type_name -> pb.GoFeatures 3, // 2: pb.go:extendee -> google.protobuf.FeatureSet
3, // [3:3] is the sub-list for method output_type 2, // 3: pb.go:type_name -> pb.GoFeatures
3, // [3:3] is the sub-list for method input_type 4, // [4:4] is the sub-list for method output_type
2, // [2:3] is the sub-list for extension type_name 4, // [4:4] is the sub-list for method input_type
1, // [1:2] is the sub-list for extension extendee 3, // [3:4] is the sub-list for extension type_name
0, // [0:1] is the sub-list for field type_name 2, // [2:3] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
} }
func init() { file_google_protobuf_go_features_proto_init() } func init() { file_google_protobuf_go_features_proto_init() }
@ -237,8 +293,8 @@ func file_google_protobuf_go_features_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_go_features_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_go_features_proto_rawDesc), len(file_google_protobuf_go_features_proto_rawDesc)),
NumEnums: 1, NumEnums: 2,
NumMessages: 1, NumMessages: 1,
NumExtensions: 1, NumExtensions: 1,
NumServices: 0, NumServices: 0,
@ -250,7 +306,6 @@ func file_google_protobuf_go_features_proto_init() {
ExtensionInfos: file_google_protobuf_go_features_proto_extTypes, ExtensionInfos: file_google_protobuf_go_features_proto_extTypes,
}.Build() }.Build()
File_google_protobuf_go_features_proto = out.File 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_goTypes = nil
file_google_protobuf_go_features_proto_depIdxs = nil file_google_protobuf_go_features_proto_depIdxs = nil
} }

View File

@ -122,6 +122,7 @@ import (
reflect "reflect" reflect "reflect"
strings "strings" strings "strings"
sync "sync" sync "sync"
unsafe "unsafe"
) )
// `Any` contains an arbitrary serialized protocol buffer message along with a // `Any` contains an arbitrary serialized protocol buffer message along with a
@ -210,10 +211,7 @@ import (
// "value": "1.212s" // "value": "1.212s"
// } // }
type Any struct { type Any struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// A URL/resource name that uniquely identifies the type of the serialized // A URL/resource name that uniquely identifies the type of the serialized
// protocol buffer message. This string must contain at least // protocol buffer message. This string must contain at least
// one "/" character. The last segment of the URL's path must represent // one "/" character. The last segment of the URL's path must represent
@ -244,7 +242,9 @@ type Any struct {
// used with implementation specific semantics. // used with implementation specific semantics.
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type. // Must be a valid serialized protocol buffer of the above specified type.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// New marshals src into a new Any instance. // New marshals src into a new Any instance.
@ -412,32 +412,22 @@ func (x *Any) GetValue() []byte {
var File_google_protobuf_any_proto protoreflect.FileDescriptor var File_google_protobuf_any_proto protoreflect.FileDescriptor
var file_google_protobuf_any_proto_rawDesc = []byte{ const file_google_protobuf_any_proto_rawDesc = "" +
0x0a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, "\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"6\n" +
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x36, 0x0a, 0x03, "\x03Any\x12\x19\n" +
0x41, 0x6e, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, "\btype_url\x18\x01 \x01(\tR\atypeUrl\x12\x14\n" +
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x14, "\x05value\x18\x02 \x01(\fR\x05valueBv\n" +
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, "\x13com.google.protobufB\bAnyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x61, 0x6c, 0x75, 0x65, 0x42, 0x76, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x08, 0x41, 0x6e, 0x79,
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 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, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f,
0x61, 0x6e, 0x79, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65,
0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var ( var (
file_google_protobuf_any_proto_rawDescOnce sync.Once file_google_protobuf_any_proto_rawDescOnce sync.Once
file_google_protobuf_any_proto_rawDescData = file_google_protobuf_any_proto_rawDesc file_google_protobuf_any_proto_rawDescData []byte
) )
func file_google_protobuf_any_proto_rawDescGZIP() []byte { func file_google_protobuf_any_proto_rawDescGZIP() []byte {
file_google_protobuf_any_proto_rawDescOnce.Do(func() { file_google_protobuf_any_proto_rawDescOnce.Do(func() {
file_google_protobuf_any_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_any_proto_rawDescData) file_google_protobuf_any_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_any_proto_rawDesc), len(file_google_protobuf_any_proto_rawDesc)))
}) })
return file_google_protobuf_any_proto_rawDescData return file_google_protobuf_any_proto_rawDescData
} }
@ -463,7 +453,7 @@ func file_google_protobuf_any_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_any_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_any_proto_rawDesc), len(file_google_protobuf_any_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 1, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
@ -474,7 +464,6 @@ func file_google_protobuf_any_proto_init() {
MessageInfos: file_google_protobuf_any_proto_msgTypes, MessageInfos: file_google_protobuf_any_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_any_proto = out.File File_google_protobuf_any_proto = out.File
file_google_protobuf_any_proto_rawDesc = nil
file_google_protobuf_any_proto_goTypes = nil file_google_protobuf_any_proto_goTypes = nil
file_google_protobuf_any_proto_depIdxs = nil file_google_protobuf_any_proto_depIdxs = nil
} }

View File

@ -80,6 +80,7 @@ import (
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
time "time" time "time"
unsafe "unsafe"
) )
// A Duration represents a signed, fixed-length span of time represented // A Duration represents a signed, fixed-length span of time represented
@ -141,10 +142,7 @@ import (
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 // be expressed in JSON format as "3.000000001s", and 3 seconds and 1
// microsecond should be expressed in JSON format as "3.000001s". // microsecond should be expressed in JSON format as "3.000001s".
type Duration struct { type Duration struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Signed seconds of the span of time. Must be from -315,576,000,000 // Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from: // to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
@ -155,7 +153,9 @@ type Duration struct {
// of one second or more, a non-zero value for the `nanos` field must be // of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999 // of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive. // to +999,999,999 inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// New constructs a new Duration from the provided time.Duration. // New constructs a new Duration from the provided time.Duration.
@ -289,33 +289,22 @@ func (x *Duration) GetNanos() int32 {
var File_google_protobuf_duration_proto protoreflect.FileDescriptor var File_google_protobuf_duration_proto protoreflect.FileDescriptor
var file_google_protobuf_duration_proto_rawDesc = []byte{ const file_google_protobuf_duration_proto_rawDesc = "" +
0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, "\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\":\n" +
0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\bDuration\x12\x18\n" +
0x66, 0x22, 0x3a, 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, "\aseconds\x18\x01 \x01(\x03R\aseconds\x12\x14\n" +
0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, "\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x83\x01\n" +
0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, "\x13com.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x42, 0x83, 0x01,
0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0d, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50,
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 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, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x64,
0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47,
0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79,
0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var ( var (
file_google_protobuf_duration_proto_rawDescOnce sync.Once file_google_protobuf_duration_proto_rawDescOnce sync.Once
file_google_protobuf_duration_proto_rawDescData = file_google_protobuf_duration_proto_rawDesc file_google_protobuf_duration_proto_rawDescData []byte
) )
func file_google_protobuf_duration_proto_rawDescGZIP() []byte { func file_google_protobuf_duration_proto_rawDescGZIP() []byte {
file_google_protobuf_duration_proto_rawDescOnce.Do(func() { file_google_protobuf_duration_proto_rawDescOnce.Do(func() {
file_google_protobuf_duration_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_duration_proto_rawDescData) file_google_protobuf_duration_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_duration_proto_rawDesc), len(file_google_protobuf_duration_proto_rawDesc)))
}) })
return file_google_protobuf_duration_proto_rawDescData return file_google_protobuf_duration_proto_rawDescData
} }
@ -341,7 +330,7 @@ func file_google_protobuf_duration_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_duration_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_duration_proto_rawDesc), len(file_google_protobuf_duration_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 1, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
@ -352,7 +341,6 @@ func file_google_protobuf_duration_proto_init() {
MessageInfos: file_google_protobuf_duration_proto_msgTypes, MessageInfos: file_google_protobuf_duration_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_duration_proto = out.File File_google_protobuf_duration_proto = out.File
file_google_protobuf_duration_proto_rawDesc = nil
file_google_protobuf_duration_proto_goTypes = nil file_google_protobuf_duration_proto_goTypes = nil
file_google_protobuf_duration_proto_depIdxs = nil file_google_protobuf_duration_proto_depIdxs = nil
} }

View File

@ -83,6 +83,7 @@ import (
sort "sort" sort "sort"
strings "strings" strings "strings"
sync "sync" sync "sync"
unsafe "unsafe"
) )
// `FieldMask` represents a set of symbolic field paths, for example: // `FieldMask` represents a set of symbolic field paths, for example:
@ -284,12 +285,11 @@ import (
// request should verify the included field paths, and return an // request should verify the included field paths, and return an
// `INVALID_ARGUMENT` error if any path is unmappable. // `INVALID_ARGUMENT` error if any path is unmappable.
type FieldMask struct { type FieldMask struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The set of field mask paths. // The set of field mask paths.
Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// New constructs a field mask from a list of paths and verifies that // New constructs a field mask from a list of paths and verifies that
@ -504,32 +504,21 @@ func (x *FieldMask) GetPaths() []string {
var File_google_protobuf_field_mask_proto protoreflect.FileDescriptor var File_google_protobuf_field_mask_proto protoreflect.FileDescriptor
var file_google_protobuf_field_mask_proto_rawDesc = []byte{ const file_google_protobuf_field_mask_proto_rawDesc = "" +
0x0a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, " google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"!\n" +
0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, "\tFieldMask\x12\x14\n" +
0x62, 0x75, 0x66, 0x22, 0x21, 0x0a, 0x09, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, "\x05paths\x18\x01 \x03(\tR\x05pathsB\x85\x01\n" +
0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, "\x13com.google.protobufB\x0eFieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x42, 0x85, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0e,
0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
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, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6d, 0x61,
0x73, 0x6b, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e,
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var ( var (
file_google_protobuf_field_mask_proto_rawDescOnce sync.Once file_google_protobuf_field_mask_proto_rawDescOnce sync.Once
file_google_protobuf_field_mask_proto_rawDescData = file_google_protobuf_field_mask_proto_rawDesc file_google_protobuf_field_mask_proto_rawDescData []byte
) )
func file_google_protobuf_field_mask_proto_rawDescGZIP() []byte { func file_google_protobuf_field_mask_proto_rawDescGZIP() []byte {
file_google_protobuf_field_mask_proto_rawDescOnce.Do(func() { file_google_protobuf_field_mask_proto_rawDescOnce.Do(func() {
file_google_protobuf_field_mask_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_field_mask_proto_rawDescData) file_google_protobuf_field_mask_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_field_mask_proto_rawDesc), len(file_google_protobuf_field_mask_proto_rawDesc)))
}) })
return file_google_protobuf_field_mask_proto_rawDescData return file_google_protobuf_field_mask_proto_rawDescData
} }
@ -555,7 +544,7 @@ func file_google_protobuf_field_mask_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_field_mask_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_field_mask_proto_rawDesc), len(file_google_protobuf_field_mask_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 1, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
@ -566,7 +555,6 @@ func file_google_protobuf_field_mask_proto_init() {
MessageInfos: file_google_protobuf_field_mask_proto_msgTypes, MessageInfos: file_google_protobuf_field_mask_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_field_mask_proto = out.File File_google_protobuf_field_mask_proto = out.File
file_google_protobuf_field_mask_proto_rawDesc = nil
file_google_protobuf_field_mask_proto_goTypes = nil file_google_protobuf_field_mask_proto_goTypes = nil
file_google_protobuf_field_mask_proto_depIdxs = nil file_google_protobuf_field_mask_proto_depIdxs = nil
} }

View File

@ -128,6 +128,7 @@ import (
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
utf8 "unicode/utf8" utf8 "unicode/utf8"
unsafe "unsafe"
) )
// `NullValue` is a singleton enumeration to represent the null value for the // `NullValue` is a singleton enumeration to represent the null value for the
@ -187,12 +188,11 @@ func (NullValue) EnumDescriptor() ([]byte, []int) {
// //
// The JSON representation for `Struct` is JSON object. // The JSON representation for `Struct` is JSON object.
type Struct struct { type Struct struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Unordered map of dynamically typed values. // Unordered map of dynamically typed values.
Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// NewStruct constructs a Struct from a general-purpose Go map. // NewStruct constructs a Struct from a general-purpose Go map.
@ -276,13 +276,10 @@ func (x *Struct) GetFields() map[string]*Value {
// //
// The JSON representation for `Value` is JSON value. // The JSON representation for `Value` is JSON value.
type Value struct { type Value struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The kind of value. // The kind of value.
// //
// Types that are assignable to Kind: // Types that are valid to be assigned to Kind:
// //
// *Value_NullValue // *Value_NullValue
// *Value_NumberValue // *Value_NumberValue
@ -290,7 +287,9 @@ type Value struct {
// *Value_BoolValue // *Value_BoolValue
// *Value_StructValue // *Value_StructValue
// *Value_ListValue // *Value_ListValue
Kind isValue_Kind `protobuf_oneof:"kind"` Kind isValue_Kind `protobuf_oneof:"kind"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// NewValue constructs a Value from a general-purpose Go interface. // NewValue constructs a Value from a general-purpose Go interface.
@ -483,51 +482,63 @@ func (*Value) Descriptor() ([]byte, []int) {
return file_google_protobuf_struct_proto_rawDescGZIP(), []int{1} return file_google_protobuf_struct_proto_rawDescGZIP(), []int{1}
} }
func (m *Value) GetKind() isValue_Kind { func (x *Value) GetKind() isValue_Kind {
if m != nil { if x != nil {
return m.Kind return x.Kind
} }
return nil return nil
} }
func (x *Value) GetNullValue() NullValue { func (x *Value) GetNullValue() NullValue {
if x, ok := x.GetKind().(*Value_NullValue); ok { if x != nil {
return x.NullValue if x, ok := x.Kind.(*Value_NullValue); ok {
return x.NullValue
}
} }
return NullValue_NULL_VALUE return NullValue_NULL_VALUE
} }
func (x *Value) GetNumberValue() float64 { func (x *Value) GetNumberValue() float64 {
if x, ok := x.GetKind().(*Value_NumberValue); ok { if x != nil {
return x.NumberValue if x, ok := x.Kind.(*Value_NumberValue); ok {
return x.NumberValue
}
} }
return 0 return 0
} }
func (x *Value) GetStringValue() string { func (x *Value) GetStringValue() string {
if x, ok := x.GetKind().(*Value_StringValue); ok { if x != nil {
return x.StringValue if x, ok := x.Kind.(*Value_StringValue); ok {
return x.StringValue
}
} }
return "" return ""
} }
func (x *Value) GetBoolValue() bool { func (x *Value) GetBoolValue() bool {
if x, ok := x.GetKind().(*Value_BoolValue); ok { if x != nil {
return x.BoolValue if x, ok := x.Kind.(*Value_BoolValue); ok {
return x.BoolValue
}
} }
return false return false
} }
func (x *Value) GetStructValue() *Struct { func (x *Value) GetStructValue() *Struct {
if x, ok := x.GetKind().(*Value_StructValue); ok { if x != nil {
return x.StructValue if x, ok := x.Kind.(*Value_StructValue); ok {
return x.StructValue
}
} }
return nil return nil
} }
func (x *Value) GetListValue() *ListValue { func (x *Value) GetListValue() *ListValue {
if x, ok := x.GetKind().(*Value_ListValue); ok { if x != nil {
return x.ListValue if x, ok := x.Kind.(*Value_ListValue); ok {
return x.ListValue
}
} }
return nil return nil
} }
@ -582,12 +593,11 @@ func (*Value_ListValue) isValue_Kind() {}
// //
// The JSON representation for `ListValue` is JSON array. // The JSON representation for `ListValue` is JSON array.
type ListValue struct { type ListValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Repeated field of dynamically typed values. // Repeated field of dynamically typed values.
Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// NewList constructs a ListValue from a general-purpose Go slice. // NewList constructs a ListValue from a general-purpose Go slice.
@ -662,64 +672,40 @@ func (x *ListValue) GetValues() []*Value {
var File_google_protobuf_struct_proto protoreflect.FileDescriptor var File_google_protobuf_struct_proto protoreflect.FileDescriptor
var file_google_protobuf_struct_proto_rawDesc = []byte{ const file_google_protobuf_struct_proto_rawDesc = "" +
0x0a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, "\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x98\x01\n" +
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, "\x06Struct\x12;\n" +
0x98, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, "\x06fields\x18\x01 \x03(\v2#.google.protobuf.Struct.FieldsEntryR\x06fields\x1aQ\n" +
0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, "\vFieldsEntry\x12\x10\n" +
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, "\x03key\x18\x01 \x01(\tR\x03key\x12,\n" +
0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, "\x05value\x18\x02 \x01(\v2\x16.google.protobuf.ValueR\x05value:\x028\x01\"\xb2\x02\n" +
0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x51, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, "\x05Value\x12;\n" +
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, "\n" +
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, "null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12#\n" +
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, "\fnumber_value\x18\x02 \x01(\x01H\x00R\vnumberValue\x12#\n" +
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, "\fstring_value\x18\x03 \x01(\tH\x00R\vstringValue\x12\x1f\n" +
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb2, 0x02, 0x0a, 0x05, 0x56, "\n" +
0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, "bool_value\x18\x04 \x01(\bH\x00R\tboolValue\x12<\n" +
0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, "\fstruct_value\x18\x05 \x01(\v2\x17.google.protobuf.StructH\x00R\vstructValue\x12;\n" +
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, "\n" +
0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, "list_value\x18\x06 \x01(\v2\x1a.google.protobuf.ListValueH\x00R\tlistValueB\x06\n" +
0x65, 0x12, 0x23, 0x0a, 0x0c, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, "\x04kind\";\n" +
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x62, 0x65, "\tListValue\x12.\n" +
0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, "\x06values\x18\x01 \x03(\v2\x16.google.protobuf.ValueR\x06values*\x1b\n" +
0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, "\tNullValue\x12\x0e\n" +
0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, "\n" +
0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, "NULL_VALUE\x10\x00B\x7f\n" +
0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x0c, "\x13com.google.protobufB\vStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x73,
0x74, 0x72, 0x75, 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6c, 0x69,
0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69,
0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22,
0x3b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x06,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0x1b, 0x0a, 0x09,
0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x55, 0x4c,
0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x00, 0x42, 0x7f, 0x0a, 0x13, 0x63, 0x6f, 0x6d,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x42, 0x0b, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x2f, 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, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x70, 0x62,
0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c,
0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var ( var (
file_google_protobuf_struct_proto_rawDescOnce sync.Once file_google_protobuf_struct_proto_rawDescOnce sync.Once
file_google_protobuf_struct_proto_rawDescData = file_google_protobuf_struct_proto_rawDesc file_google_protobuf_struct_proto_rawDescData []byte
) )
func file_google_protobuf_struct_proto_rawDescGZIP() []byte { func file_google_protobuf_struct_proto_rawDescGZIP() []byte {
file_google_protobuf_struct_proto_rawDescOnce.Do(func() { file_google_protobuf_struct_proto_rawDescOnce.Do(func() {
file_google_protobuf_struct_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_struct_proto_rawDescData) file_google_protobuf_struct_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_struct_proto_rawDesc), len(file_google_protobuf_struct_proto_rawDesc)))
}) })
return file_google_protobuf_struct_proto_rawDescData return file_google_protobuf_struct_proto_rawDescData
} }
@ -764,7 +750,7 @@ func file_google_protobuf_struct_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_struct_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_struct_proto_rawDesc), len(file_google_protobuf_struct_proto_rawDesc)),
NumEnums: 1, NumEnums: 1,
NumMessages: 4, NumMessages: 4,
NumExtensions: 0, NumExtensions: 0,
@ -776,7 +762,6 @@ func file_google_protobuf_struct_proto_init() {
MessageInfos: file_google_protobuf_struct_proto_msgTypes, MessageInfos: file_google_protobuf_struct_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_struct_proto = out.File File_google_protobuf_struct_proto = out.File
file_google_protobuf_struct_proto_rawDesc = nil
file_google_protobuf_struct_proto_goTypes = nil file_google_protobuf_struct_proto_goTypes = nil
file_google_protobuf_struct_proto_depIdxs = nil file_google_protobuf_struct_proto_depIdxs = nil
} }

View File

@ -78,6 +78,7 @@ import (
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
time "time" time "time"
unsafe "unsafe"
) )
// A Timestamp represents a point in time independent of any time zone or local // A Timestamp represents a point in time independent of any time zone or local
@ -170,10 +171,7 @@ import (
// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() // http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
// ) to obtain a formatter capable of generating timestamps in this format. // ) to obtain a formatter capable of generating timestamps in this format.
type Timestamp struct { type Timestamp struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Represents seconds of UTC time since Unix epoch // Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive. // 9999-12-31T23:59:59Z inclusive.
@ -182,7 +180,9 @@ type Timestamp struct {
// second values with fractions must still have non-negative nanos values // second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999 // that count forward in time. Must be from 0 to 999,999,999
// inclusive. // inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Now constructs a new Timestamp from the current time. // Now constructs a new Timestamp from the current time.
@ -298,33 +298,22 @@ func (x *Timestamp) GetNanos() int32 {
var File_google_protobuf_timestamp_proto protoreflect.FileDescriptor var File_google_protobuf_timestamp_proto protoreflect.FileDescriptor
var file_google_protobuf_timestamp_proto_rawDesc = []byte{ const file_google_protobuf_timestamp_proto_rawDesc = "" +
0x0a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, "\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\";\n" +
0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, "\tTimestamp\x12\x18\n" +
0x75, 0x66, 0x22, 0x3b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, "\aseconds\x18\x01 \x01(\x03R\aseconds\x12\x14\n" +
0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, "\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x85\x01\n" +
0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, "\x13com.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x42,
0x85, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 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, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6b, 0x6e, 0x6f, 0x77,
0x6e, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x70, 0x62, 0xf8, 0x01, 0x01,
0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f,
0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var ( var (
file_google_protobuf_timestamp_proto_rawDescOnce sync.Once file_google_protobuf_timestamp_proto_rawDescOnce sync.Once
file_google_protobuf_timestamp_proto_rawDescData = file_google_protobuf_timestamp_proto_rawDesc file_google_protobuf_timestamp_proto_rawDescData []byte
) )
func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte { func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte {
file_google_protobuf_timestamp_proto_rawDescOnce.Do(func() { file_google_protobuf_timestamp_proto_rawDescOnce.Do(func() {
file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_timestamp_proto_rawDescData) file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc)))
}) })
return file_google_protobuf_timestamp_proto_rawDescData return file_google_protobuf_timestamp_proto_rawDescData
} }
@ -350,7 +339,7 @@ func file_google_protobuf_timestamp_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_timestamp_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 1, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
@ -361,7 +350,6 @@ func file_google_protobuf_timestamp_proto_init() {
MessageInfos: file_google_protobuf_timestamp_proto_msgTypes, MessageInfos: file_google_protobuf_timestamp_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_timestamp_proto = out.File File_google_protobuf_timestamp_proto = out.File
file_google_protobuf_timestamp_proto_rawDesc = nil
file_google_protobuf_timestamp_proto_goTypes = nil file_google_protobuf_timestamp_proto_goTypes = nil
file_google_protobuf_timestamp_proto_depIdxs = nil file_google_protobuf_timestamp_proto_depIdxs = nil
} }

View File

@ -28,10 +28,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Wrappers for primitive (non-message) types. These types are useful // Wrappers for primitive (non-message) types. These types were needed
// for embedding primitives in the `google.protobuf.Any` type and for places // for legacy reasons and are not recommended for use in new APIs.
// where we need to distinguish between the absence of a primitive //
// typed field and its default value. // Historically these wrappers were useful to have presence on proto3 primitive
// fields, but proto3 syntax has been updated to support the `optional` keyword.
// Using that keyword is now the strongly preferred way to add presence to
// proto3 primitive fields.
//
// A secondary usecase was to embed primitives in the `google.protobuf.Any`
// type: it is now recommended that you embed your value in your own wrapper
// message which can be specifically documented.
// //
// These wrappers have no meaningful use within repeated fields as they lack // These wrappers have no meaningful use within repeated fields as they lack
// the ability to detect presence on individual elements. // the ability to detect presence on individual elements.
@ -48,18 +55,21 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
unsafe "unsafe"
) )
// Wrapper message for `double`. // Wrapper message for `double`.
// //
// The JSON representation for `DoubleValue` is JSON number. // The JSON representation for `DoubleValue` is JSON number.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type DoubleValue struct { type DoubleValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The double value. // The double value.
Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Double stores v in a new DoubleValue and returns a pointer to it. // Double stores v in a new DoubleValue and returns a pointer to it.
@ -107,13 +117,15 @@ func (x *DoubleValue) GetValue() float64 {
// Wrapper message for `float`. // Wrapper message for `float`.
// //
// The JSON representation for `FloatValue` is JSON number. // The JSON representation for `FloatValue` is JSON number.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type FloatValue struct { type FloatValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The float value. // The float value.
Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Float stores v in a new FloatValue and returns a pointer to it. // Float stores v in a new FloatValue and returns a pointer to it.
@ -161,13 +173,15 @@ func (x *FloatValue) GetValue() float32 {
// Wrapper message for `int64`. // Wrapper message for `int64`.
// //
// The JSON representation for `Int64Value` is JSON string. // The JSON representation for `Int64Value` is JSON string.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type Int64Value struct { type Int64Value struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The int64 value. // The int64 value.
Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Int64 stores v in a new Int64Value and returns a pointer to it. // Int64 stores v in a new Int64Value and returns a pointer to it.
@ -215,13 +229,15 @@ func (x *Int64Value) GetValue() int64 {
// Wrapper message for `uint64`. // Wrapper message for `uint64`.
// //
// The JSON representation for `UInt64Value` is JSON string. // The JSON representation for `UInt64Value` is JSON string.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type UInt64Value struct { type UInt64Value struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The uint64 value. // The uint64 value.
Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// UInt64 stores v in a new UInt64Value and returns a pointer to it. // UInt64 stores v in a new UInt64Value and returns a pointer to it.
@ -269,13 +285,15 @@ func (x *UInt64Value) GetValue() uint64 {
// Wrapper message for `int32`. // Wrapper message for `int32`.
// //
// The JSON representation for `Int32Value` is JSON number. // The JSON representation for `Int32Value` is JSON number.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type Int32Value struct { type Int32Value struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The int32 value. // The int32 value.
Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Int32 stores v in a new Int32Value and returns a pointer to it. // Int32 stores v in a new Int32Value and returns a pointer to it.
@ -323,13 +341,15 @@ func (x *Int32Value) GetValue() int32 {
// Wrapper message for `uint32`. // Wrapper message for `uint32`.
// //
// The JSON representation for `UInt32Value` is JSON number. // The JSON representation for `UInt32Value` is JSON number.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type UInt32Value struct { type UInt32Value struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The uint32 value. // The uint32 value.
Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// UInt32 stores v in a new UInt32Value and returns a pointer to it. // UInt32 stores v in a new UInt32Value and returns a pointer to it.
@ -377,13 +397,15 @@ func (x *UInt32Value) GetValue() uint32 {
// Wrapper message for `bool`. // Wrapper message for `bool`.
// //
// The JSON representation for `BoolValue` is JSON `true` and `false`. // The JSON representation for `BoolValue` is JSON `true` and `false`.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type BoolValue struct { type BoolValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The bool value. // The bool value.
Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Bool stores v in a new BoolValue and returns a pointer to it. // Bool stores v in a new BoolValue and returns a pointer to it.
@ -431,13 +453,15 @@ func (x *BoolValue) GetValue() bool {
// Wrapper message for `string`. // Wrapper message for `string`.
// //
// The JSON representation for `StringValue` is JSON string. // The JSON representation for `StringValue` is JSON string.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type StringValue struct { type StringValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The string value. // The string value.
Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// String stores v in a new StringValue and returns a pointer to it. // String stores v in a new StringValue and returns a pointer to it.
@ -485,13 +509,15 @@ func (x *StringValue) GetValue() string {
// Wrapper message for `bytes`. // Wrapper message for `bytes`.
// //
// The JSON representation for `BytesValue` is JSON string. // The JSON representation for `BytesValue` is JSON string.
//
// Not recommended for use in new APIs, but still useful for legacy APIs and
// has no plan to be removed.
type BytesValue struct { type BytesValue struct {
state protoimpl.MessageState state protoimpl.MessageState `protogen:"open.v1"`
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The bytes value. // The bytes value.
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
// Bytes stores v in a new BytesValue and returns a pointer to it. // Bytes stores v in a new BytesValue and returns a pointer to it.
@ -538,50 +564,41 @@ func (x *BytesValue) GetValue() []byte {
var File_google_protobuf_wrappers_proto protoreflect.FileDescriptor var File_google_protobuf_wrappers_proto protoreflect.FileDescriptor
var file_google_protobuf_wrappers_proto_rawDesc = []byte{ const file_google_protobuf_wrappers_proto_rawDesc = "" +
0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\n" +
0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, "\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"#\n" +
0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, "\vDoubleValue\x12\x14\n" +
0x66, 0x22, 0x23, 0x0a, 0x0b, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, "\x05value\x18\x01 \x01(\x01R\x05value\"\"\n" +
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, "\n" +
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, "FloatValue\x12\x14\n" +
0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, "\x05value\x18\x01 \x01(\x02R\x05value\"\"\n" +
0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e, "\n" +
0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, "Int64Value\x12\x14\n" +
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, "\x05value\x18\x01 \x01(\x03R\x05value\"#\n" +
0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, "\vUInt64Value\x12\x14\n" +
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, "\x05value\x18\x01 \x01(\x04R\x05value\"\"\n" +
0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, "\n" +
0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, "Int32Value\x12\x14\n" +
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x33, "\x05value\x18\x01 \x01(\x05R\x05value\"#\n" +
0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, "\vUInt32Value\x12\x14\n" +
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, 0x09, "\x05value\x18\x01 \x01(\rR\x05value\"!\n" +
0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, "\tBoolValue\x12\x14\n" +
0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, "\x05value\x18\x01 \x01(\bR\x05value\"#\n" +
0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, "\vStringValue\x12\x14\n" +
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, "\x05value\x18\x01 \x01(\tR\x05value\"\"\n" +
0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, "\n" +
0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, "BytesValue\x12\x14\n" +
0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x83, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, "\x05value\x18\x01 \x01(\fR\x05valueB\x83\x01\n" +
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, "\x13com.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3"
0x42, 0x0d, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
0x01, 0x5a, 0x31, 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, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65,
0x72, 0x73, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e,
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var ( var (
file_google_protobuf_wrappers_proto_rawDescOnce sync.Once file_google_protobuf_wrappers_proto_rawDescOnce sync.Once
file_google_protobuf_wrappers_proto_rawDescData = file_google_protobuf_wrappers_proto_rawDesc file_google_protobuf_wrappers_proto_rawDescData []byte
) )
func file_google_protobuf_wrappers_proto_rawDescGZIP() []byte { func file_google_protobuf_wrappers_proto_rawDescGZIP() []byte {
file_google_protobuf_wrappers_proto_rawDescOnce.Do(func() { file_google_protobuf_wrappers_proto_rawDescOnce.Do(func() {
file_google_protobuf_wrappers_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_wrappers_proto_rawDescData) file_google_protobuf_wrappers_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_wrappers_proto_rawDesc), len(file_google_protobuf_wrappers_proto_rawDesc)))
}) })
return file_google_protobuf_wrappers_proto_rawDescData return file_google_protobuf_wrappers_proto_rawDescData
} }
@ -615,7 +632,7 @@ func file_google_protobuf_wrappers_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_protobuf_wrappers_proto_rawDesc, RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_wrappers_proto_rawDesc), len(file_google_protobuf_wrappers_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 9, NumMessages: 9,
NumExtensions: 0, NumExtensions: 0,
@ -626,7 +643,6 @@ func file_google_protobuf_wrappers_proto_init() {
MessageInfos: file_google_protobuf_wrappers_proto_msgTypes, MessageInfos: file_google_protobuf_wrappers_proto_msgTypes,
}.Build() }.Build()
File_google_protobuf_wrappers_proto = out.File File_google_protobuf_wrappers_proto = out.File
file_google_protobuf_wrappers_proto_rawDesc = nil
file_google_protobuf_wrappers_proto_goTypes = nil file_google_protobuf_wrappers_proto_goTypes = nil
file_google_protobuf_wrappers_proto_depIdxs = nil file_google_protobuf_wrappers_proto_depIdxs = nil
} }

5
vendor/modules.txt vendored
View File

@ -506,8 +506,8 @@ google.golang.org/grpc/serviceconfig
google.golang.org/grpc/stats google.golang.org/grpc/stats
google.golang.org/grpc/status google.golang.org/grpc/status
google.golang.org/grpc/tap google.golang.org/grpc/tap
# google.golang.org/protobuf v1.35.2 # google.golang.org/protobuf v1.36.6
## explicit; go 1.21 ## explicit; go 1.22
google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protodelim
google.golang.org/protobuf/encoding/protojson google.golang.org/protobuf/encoding/protojson
google.golang.org/protobuf/encoding/prototext google.golang.org/protobuf/encoding/prototext
@ -530,6 +530,7 @@ google.golang.org/protobuf/internal/genid
google.golang.org/protobuf/internal/impl google.golang.org/protobuf/internal/impl
google.golang.org/protobuf/internal/order google.golang.org/protobuf/internal/order
google.golang.org/protobuf/internal/pragma google.golang.org/protobuf/internal/pragma
google.golang.org/protobuf/internal/protolazy
google.golang.org/protobuf/internal/set google.golang.org/protobuf/internal/set
google.golang.org/protobuf/internal/strs google.golang.org/protobuf/internal/strs
google.golang.org/protobuf/internal/version google.golang.org/protobuf/internal/version