diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-01-31 17:22:33 +0300 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-01-31 17:22:33 +0300 |
commit | 52be5dbdd420165c68e7e90ba8f1d2f00da041f6 (patch) | |
tree | 5d47f5b2ff4e6a7c8e75d33931a1e683949b7229 /vendor/google.golang.org/protobuf/reflect/protodesc | |
parent | ea57c8867ceca391357c3c5ffcc5ba6738b49adc (diff) | |
parent | 809f0cf2fdfddfbeacc2256ffdbaaf5808ce5ed4 (diff) | |
download | ydb-52be5dbdd420165c68e7e90ba8f1d2f00da041f6.tar.gz |
Merge branch 'mergelibs12' into main
Diffstat (limited to 'vendor/google.golang.org/protobuf/reflect/protodesc')
8 files changed, 235 insertions, 1209 deletions
diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go index e4dfb12050..baa0cc6218 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go @@ -3,11 +3,11 @@ // license that can be found in the LICENSE file. // Package protodesc provides functionality for converting -// FileDescriptorProto messages to/from protoreflect.FileDescriptor values. +// FileDescriptorProto messages to/from [protoreflect.FileDescriptor] values. // // The google.protobuf.FileDescriptorProto is a protobuf message that describes // the type information for a .proto file in a form that is easily serializable. -// The protoreflect.FileDescriptor is a more structured representation of +// The [protoreflect.FileDescriptor] is a more structured representation of // the FileDescriptorProto message where references and remote dependencies // can be directly followed. package protodesc @@ -24,11 +24,11 @@ import ( "google.golang.org/protobuf/types/descriptorpb" ) -// Resolver is the resolver used by NewFile to resolve dependencies. +// Resolver is the resolver used by [NewFile] to resolve dependencies. // The enums and messages provided must belong to some parent file, // which is also registered. // -// It is implemented by protoregistry.Files. +// It is implemented by [protoregistry.Files]. type Resolver interface { FindFileByPath(string) (protoreflect.FileDescriptor, error) FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error) @@ -61,19 +61,19 @@ type FileOptions struct { AllowUnresolvable bool } -// NewFile creates a new protoreflect.FileDescriptor from the provided -// file descriptor message. See FileOptions.New for more information. +// NewFile creates a new [protoreflect.FileDescriptor] from the provided +// file descriptor message. See [FileOptions.New] for more information. func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) { return FileOptions{}.New(fd, r) } -// NewFiles creates a new protoregistry.Files from the provided -// FileDescriptorSet message. See FileOptions.NewFiles for more information. +// NewFiles creates a new [protoregistry.Files] from the provided +// FileDescriptorSet message. See [FileOptions.NewFiles] for more information. func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) { return FileOptions{}.NewFiles(fd) } -// New creates a new protoreflect.FileDescriptor from the provided +// New creates a new [protoreflect.FileDescriptor] from the provided // file descriptor message. The file must represent a valid proto file according // to protobuf semantics. The returned descriptor is a deep copy of the input. // @@ -93,9 +93,15 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot f.L1.Syntax = protoreflect.Proto2 case "proto3": f.L1.Syntax = protoreflect.Proto3 + case "editions": + f.L1.Syntax = protoreflect.Editions + f.L1.Edition = fromEditionProto(fd.GetEdition()) default: return nil, errors.New("invalid syntax: %q", fd.GetSyntax()) } + if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < SupportedEditionsMinimum || fd.GetEdition() > SupportedEditionsMaximum) { + return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition()) + } f.L1.Path = fd.GetName() if f.L1.Path == "" { return nil, errors.New("file path must be populated") @@ -108,6 +114,9 @@ func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (prot opts = proto.Clone(opts).(*descriptorpb.FileOptions) f.L2.Options = func() protoreflect.ProtoMessage { return opts } } + if f.L1.Syntax == protoreflect.Editions { + initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures()) + } f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency())) for _, i := range fd.GetPublicDependency() { @@ -231,7 +240,7 @@ func (is importSet) importPublic(imps protoreflect.FileImports) { } } -// NewFiles creates a new protoregistry.Files from the provided +// NewFiles creates a new [protoregistry.Files] from the provided // FileDescriptorSet message. The descriptor set must include only // valid files according to protobuf semantics. The returned descriptors // are a deep copy of the input. diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go index 37efda1afe..aff6fd4900 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go @@ -137,6 +137,30 @@ func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDesc if fd.JsonName != nil { f.L1.StringName.InitJSON(fd.GetJsonName()) } + + if f.Base.L0.ParentFile.Syntax() == protoreflect.Editions { + f.L1.Presence = resolveFeatureHasFieldPresence(f.Base.L0.ParentFile, fd) + // We reuse the existing field because the old option `[packed = + // true]` is mutually exclusive with the editions feature. + if fd.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED { + f.L1.HasPacked = true + f.L1.IsPacked = resolveFeatureRepeatedFieldEncodingPacked(f.Base.L0.ParentFile, fd) + } + + // We pretend this option is always explicitly set because the only + // use of HasEnforceUTF8 is to determine whether to use EnforceUTF8 + // or to return the appropriate default. + // When using editions we either parse the option or resolve the + // appropriate default here (instead of later when this option is + // requested from the descriptor). + // In proto2/proto3 syntax HasEnforceUTF8 might be false. + f.L1.HasEnforceUTF8 = true + f.L1.EnforceUTF8 = resolveFeatureEnforceUTF8(f.Base.L0.ParentFile, fd) + + if f.L1.Kind == protoreflect.MessageKind && resolveFeatureDelimitedEncoding(f.Base.L0.ParentFile, fd) { + f.L1.Kind = protoreflect.GroupKind + } + } } return fs, nil } diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go b/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go new file mode 100644 index 0000000000..7352926cab --- /dev/null +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go @@ -0,0 +1,177 @@ +// 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 protodesc + +import ( + _ "embed" + "fmt" + "os" + "sync" + + "google.golang.org/protobuf/internal/filedesc" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + SupportedEditionsMinimum = descriptorpb.Edition_EDITION_PROTO2 + SupportedEditionsMaximum = descriptorpb.Edition_EDITION_2023 +) + +//go:embed editions_defaults.binpb +var binaryEditionDefaults []byte +var defaults = &descriptorpb.FeatureSetDefaults{} +var defaultsCacheMu sync.Mutex +var defaultsCache = make(map[filedesc.Edition]*descriptorpb.FeatureSet) + +func init() { + err := proto.Unmarshal(binaryEditionDefaults, defaults) + if err != nil { + fmt.Fprintf(os.Stderr, "unmarshal editions defaults: %v\n", err) + os.Exit(1) + } +} + +func fromEditionProto(epb descriptorpb.Edition) filedesc.Edition { + return filedesc.Edition(epb) +} + +func toEditionProto(ed filedesc.Edition) descriptorpb.Edition { + switch ed { + case filedesc.EditionUnknown: + return descriptorpb.Edition_EDITION_UNKNOWN + case filedesc.EditionProto2: + return descriptorpb.Edition_EDITION_PROTO2 + case filedesc.EditionProto3: + return descriptorpb.Edition_EDITION_PROTO3 + case filedesc.Edition2023: + return descriptorpb.Edition_EDITION_2023 + default: + panic(fmt.Sprintf("unknown value for edition: %v", ed)) + } +} + +func getFeatureSetFor(ed filedesc.Edition) *descriptorpb.FeatureSet { + defaultsCacheMu.Lock() + defer defaultsCacheMu.Unlock() + if def, ok := defaultsCache[ed]; ok { + return def + } + edpb := toEditionProto(ed) + if defaults.GetMinimumEdition() > edpb || defaults.GetMaximumEdition() < edpb { + // This should never happen protodesc.(FileOptions).New would fail when + // initializing the file descriptor. + // This most likely means the embedded defaults were not updated. + fmt.Fprintf(os.Stderr, "internal error: unsupported edition %v (did you forget to update the embedded defaults (i.e. the bootstrap descriptor proto)?)\n", edpb) + os.Exit(1) + } + fs := defaults.GetDefaults()[0].GetFeatures() + // Using a linear search for now. + // Editions are guaranteed to be sorted and thus we could use a binary search. + // Given that there are only a handful of editions (with one more per year) + // there is not much reason to use a binary search. + for _, def := range defaults.GetDefaults() { + if def.GetEdition() <= edpb { + fs = def.GetFeatures() + } else { + break + } + } + defaultsCache[ed] = fs + return fs +} + +func resolveFeatureHasFieldPresence(fileDesc *filedesc.File, fieldDesc *descriptorpb.FieldDescriptorProto) bool { + fs := fieldDesc.GetOptions().GetFeatures() + if fs == nil || fs.FieldPresence == nil { + return fileDesc.L1.EditionFeatures.IsFieldPresence + } + return fs.GetFieldPresence() == descriptorpb.FeatureSet_LEGACY_REQUIRED || + fs.GetFieldPresence() == descriptorpb.FeatureSet_EXPLICIT +} + +func resolveFeatureRepeatedFieldEncodingPacked(fileDesc *filedesc.File, fieldDesc *descriptorpb.FieldDescriptorProto) bool { + fs := fieldDesc.GetOptions().GetFeatures() + if fs == nil || fs.RepeatedFieldEncoding == nil { + return fileDesc.L1.EditionFeatures.IsPacked + } + return fs.GetRepeatedFieldEncoding() == descriptorpb.FeatureSet_PACKED +} + +func resolveFeatureEnforceUTF8(fileDesc *filedesc.File, fieldDesc *descriptorpb.FieldDescriptorProto) bool { + fs := fieldDesc.GetOptions().GetFeatures() + if fs == nil || fs.Utf8Validation == nil { + return fileDesc.L1.EditionFeatures.IsUTF8Validated + } + return fs.GetUtf8Validation() == descriptorpb.FeatureSet_VERIFY +} + +func resolveFeatureDelimitedEncoding(fileDesc *filedesc.File, fieldDesc *descriptorpb.FieldDescriptorProto) bool { + fs := fieldDesc.GetOptions().GetFeatures() + if fs == nil || fs.MessageEncoding == nil { + return fileDesc.L1.EditionFeatures.IsDelimitedEncoded + } + return fs.GetMessageEncoding() == descriptorpb.FeatureSet_DELIMITED +} + +// initFileDescFromFeatureSet initializes editions related fields in fd based +// on fs. If fs is nil it is assumed to be an empty featureset and all fields +// will be initialized with the appropriate default. fd.L1.Edition must be set +// before calling this function. +func initFileDescFromFeatureSet(fd *filedesc.File, fs *descriptorpb.FeatureSet) { + dfs := getFeatureSetFor(fd.L1.Edition) + if fs == nil { + fs = &descriptorpb.FeatureSet{} + } + + var fieldPresence descriptorpb.FeatureSet_FieldPresence + if fp := fs.FieldPresence; fp != nil { + fieldPresence = *fp + } else { + fieldPresence = *dfs.FieldPresence + } + fd.L1.EditionFeatures.IsFieldPresence = fieldPresence == descriptorpb.FeatureSet_LEGACY_REQUIRED || + fieldPresence == descriptorpb.FeatureSet_EXPLICIT + + var enumType descriptorpb.FeatureSet_EnumType + if et := fs.EnumType; et != nil { + enumType = *et + } else { + enumType = *dfs.EnumType + } + fd.L1.EditionFeatures.IsOpenEnum = enumType == descriptorpb.FeatureSet_OPEN + + var respeatedFieldEncoding descriptorpb.FeatureSet_RepeatedFieldEncoding + if rfe := fs.RepeatedFieldEncoding; rfe != nil { + respeatedFieldEncoding = *rfe + } else { + respeatedFieldEncoding = *dfs.RepeatedFieldEncoding + } + fd.L1.EditionFeatures.IsPacked = respeatedFieldEncoding == descriptorpb.FeatureSet_PACKED + + var isUTF8Validated descriptorpb.FeatureSet_Utf8Validation + if utf8val := fs.Utf8Validation; utf8val != nil { + isUTF8Validated = *utf8val + } else { + isUTF8Validated = *dfs.Utf8Validation + } + fd.L1.EditionFeatures.IsUTF8Validated = isUTF8Validated == descriptorpb.FeatureSet_VERIFY + + var messageEncoding descriptorpb.FeatureSet_MessageEncoding + if me := fs.MessageEncoding; me != nil { + messageEncoding = *me + } else { + messageEncoding = *dfs.MessageEncoding + } + fd.L1.EditionFeatures.IsDelimitedEncoded = messageEncoding == descriptorpb.FeatureSet_DELIMITED + + var jsonFormat descriptorpb.FeatureSet_JsonFormat + if jf := fs.JsonFormat; jf != nil { + jsonFormat = *jf + } else { + jsonFormat = *dfs.JsonFormat + } + fd.L1.EditionFeatures.IsJSONCompliant = jsonFormat == descriptorpb.FeatureSet_ALLOW +} diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/editions_defaults.binpb b/vendor/google.golang.org/protobuf/reflect/protodesc/editions_defaults.binpb new file mode 100644 index 0000000000..1a8610a843 --- /dev/null +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/editions_defaults.binpb @@ -0,0 +1,4 @@ + + (0æ + (0ç + (0è æ(è
\ No newline at end of file diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/file_test.go b/vendor/google.golang.org/protobuf/reflect/protodesc/file_test.go deleted file mode 100644 index 29b4fa722c..0000000000 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/file_test.go +++ /dev/null @@ -1,1182 +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 protodesc - -import ( - "fmt" - "strings" - "testing" - - "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/internal/flags" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - "google.golang.org/protobuf/types/descriptorpb" -) - -func mustParseFile(s string) *descriptorpb.FileDescriptorProto { - pb := new(descriptorpb.FileDescriptorProto) - if err := prototext.Unmarshal([]byte(s), pb); err != nil { - panic(err) - } - return pb -} - -func cloneFile(in *descriptorpb.FileDescriptorProto) *descriptorpb.FileDescriptorProto { - return proto.Clone(in).(*descriptorpb.FileDescriptorProto) -} - -var ( - proto2Enum = mustParseFile(` - syntax: "proto2" - name: "proto2_enum.proto" - package: "test.proto2" - enum_type: [{name:"Enum" value:[{name:"ONE" number:1}]}] - `) - proto3Message = mustParseFile(` - syntax: "proto3" - name: "proto3_message.proto" - package: "test.proto3" - message_type: [{ - name: "Message" - field: [ - {name:"foo" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"bar" number:2 label:LABEL_OPTIONAL type:TYPE_STRING} - ] - }] - `) - extendableMessage = mustParseFile(` - syntax: "proto2" - name: "extendable_message.proto" - package: "test.proto2" - message_type: [{name:"Message" extension_range:[{start:1 end:1000}]}] - `) - importPublicFile1 = mustParseFile(` - syntax: "proto3" - name: "import_public1.proto" - dependency: ["proto2_enum.proto", "proto3_message.proto", "extendable_message.proto"] - message_type: [{name:"Public1"}] - `) - importPublicFile2 = mustParseFile(` - syntax: "proto3" - name: "import_public2.proto" - dependency: ["import_public1.proto"] - public_dependency: [0] - message_type: [{name:"Public2"}] - `) - importPublicFile3 = mustParseFile(` - syntax: "proto3" - name: "import_public3.proto" - dependency: ["import_public2.proto", "extendable_message.proto"] - public_dependency: [0] - message_type: [{name:"Public3"}] - `) - importPublicFile4 = mustParseFile(` - syntax: "proto3" - name: "import_public4.proto" - dependency: ["import_public2.proto", "import_public3.proto", "proto2_enum.proto"] - public_dependency: [0, 1] - message_type: [{name:"Public4"}] - `) -) - -func TestNewFile(t *testing.T) { - tests := []struct { - label string - inDeps []*descriptorpb.FileDescriptorProto - inDesc *descriptorpb.FileDescriptorProto - inOpts FileOptions - wantDesc *descriptorpb.FileDescriptorProto - wantErr string - }{{ - label: "empty path", - inDesc: mustParseFile(``), - wantErr: `path must be populated`, - }, { - label: "empty package and syntax", - inDesc: mustParseFile(`name:"weird"`), - }, { - label: "invalid syntax", - inDesc: mustParseFile(`name:"weird" syntax:"proto9"`), - wantErr: `invalid syntax: "proto9"`, - }, { - label: "bad package", - inDesc: mustParseFile(`name:"weird" package:"$"`), - wantErr: `invalid package: "$"`, - }, { - label: "unresolvable import", - inDesc: mustParseFile(` - name: "test.proto" - dependency: "dep.proto" - `), - wantErr: `could not resolve import "dep.proto": not found`, - }, { - label: "unresolvable import but allowed", - inDesc: mustParseFile(` - name: "test.proto" - dependency: "dep.proto" - `), - inOpts: FileOptions{AllowUnresolvable: true}, - }, { - label: "duplicate import", - inDesc: mustParseFile(` - name: "test.proto" - dependency: ["dep.proto", "dep.proto"] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - wantErr: `already imported "dep.proto"`, - }, { - label: "invalid weak import", - inDesc: mustParseFile(` - name: "test.proto" - dependency: "dep.proto" - weak_dependency: [-23] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - wantErr: `invalid or duplicate weak import index: -23`, - }, { - label: "normal weak and public import", - inDesc: mustParseFile(` - name: "test.proto" - dependency: "dep.proto" - weak_dependency: [0] - public_dependency: [0] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - }, { - label: "import public indirect dependency duplicate", - inDeps: []*descriptorpb.FileDescriptorProto{ - mustParseFile(`name:"leaf.proto"`), - mustParseFile(`name:"public.proto" dependency:"leaf.proto" public_dependency:0`), - }, - inDesc: mustParseFile(` - name: "test.proto" - dependency: ["public.proto", "leaf.proto"] - `), - }, { - label: "import public graph", - inDeps: []*descriptorpb.FileDescriptorProto{ - cloneFile(proto2Enum), - cloneFile(proto3Message), - cloneFile(extendableMessage), - cloneFile(importPublicFile1), - cloneFile(importPublicFile2), - cloneFile(importPublicFile3), - cloneFile(importPublicFile4), - }, - inDesc: mustParseFile(` - name: "test.proto" - package: "test.graph" - dependency: ["import_public4.proto"], - `), - // TODO: Test import public - }, { - label: "preserve source code locations", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - source_code_info: {location: [{ - span: [39,0,882,1] - }, { - path: [12] - span: [39,0,18] - leading_detached_comments: [" foo\n"," bar\n"] - }, { - path: [8,9] - span: [51,0,28] - leading_comments: " Comment\n" - }]} - `), - }, { - label: "invalid source code span", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - source_code_info: {location: [{ - span: [39] - }]} - `), - wantErr: `invalid span: [39]`, - }, { - label: "resolve relative reference", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "A" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:"B.C"}] - nested_type: [{name: "B"}] - }, { - name: "B" - nested_type: [{name: "C"}] - }] - `), - wantDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "A" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".fizz.buzz.B.C"}] - nested_type: [{name: "B"}] - }, { - name: "B" - nested_type: [{name: "C"}] - }] - `), - }, { - label: "resolve the wrong type", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:"E"}] - enum_type: [{name: "E" value: [{name:"V0" number:0}, {name:"V1" number:1}]}] - }] - `), - wantErr: `message field "M.F" cannot resolve type: resolved "M.E", but it is not an message`, - }, { - label: "auto-resolve unknown kind", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type_name:"E"}] - enum_type: [{name: "E" value: [{name:"V0" number:0}, {name:"V1" number:1}]}] - }] - `), - wantDesc: mustParseFile(` - name: "test.proto" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".M.E"}] - enum_type: [{name: "E" value: [{name:"V0" number:0}, {name:"V1" number:1}]}] - }] - `), - }, { - label: "unresolved import", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - dependency: "remote.proto" - `), - wantErr: `could not resolve import "remote.proto": not found`, - }, { - label: "unresolved message field", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "M" - field: [{name:"F1" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:"some.other.enum" default_value:"UNKNOWN"}] - }] - `), - wantErr: `message field "fizz.buzz.M.F1" cannot resolve type: "*.some.other.enum" not found`, - }, { - label: "unresolved default enum value", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "M" - field: [{name:"F1" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:"E" default_value:"UNKNOWN"}] - enum_type: [{name:"E" value:[{name:"V0" number:0}]}] - }] - `), - wantErr: `message field "fizz.buzz.M.F1" has invalid default: could not parse value for enum: "UNKNOWN"`, - }, { - label: "allowed unresolved default enum value", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "M" - field: [{name:"F1" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".fizz.buzz.M.E" default_value:"UNKNOWN"}] - enum_type: [{name:"E" value:[{name:"V0" number:0}]}] - }] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - }, { - label: "unresolved extendee", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - extension: [{name:"X" number:1 label:LABEL_OPTIONAL extendee:"some.extended.message" type:TYPE_MESSAGE type_name:"some.other.message"}] - `), - wantErr: `extension field "fizz.buzz.X" cannot resolve extendee: "*.some.extended.message" not found`, - }, { - label: "unresolved method input", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - service: [{ - name: "S" - method: [{name:"M" input_type:"foo.bar.input" output_type:".absolute.foo.bar.output"}] - }] - `), - wantErr: `service method "fizz.buzz.S.M" cannot resolve input: "*.foo.bar.input" not found`, - }, { - label: "allowed unresolved references", - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - dependency: "remote.proto" - message_type: [{ - name: "M" - field: [{name:"F1" number:1 label:LABEL_OPTIONAL type_name:"some.other.enum" default_value:"UNKNOWN"}] - }] - extension: [{name:"X" number:1 label:LABEL_OPTIONAL extendee:"some.extended.message" type:TYPE_MESSAGE type_name:"some.other.message"}] - service: [{ - name: "S" - method: [{name:"M" input_type:"foo.bar.input" output_type:".absolute.foo.bar.output"}] - }] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - }, { - label: "resolved but not imported", - inDeps: []*descriptorpb.FileDescriptorProto{mustParseFile(` - name: "dep.proto" - package: "fizz" - message_type: [{name:"M" nested_type:[{name:"M"}]}] - `)}, - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:"M.M"}] - }] - `), - wantErr: `message field "fizz.buzz.M.F" cannot resolve type: resolved "fizz.M.M", but "dep.proto" is not imported`, - }, { - label: "resolved from remote import", - inDeps: []*descriptorpb.FileDescriptorProto{mustParseFile(` - name: "dep.proto" - package: "fizz" - message_type: [{name:"M" nested_type:[{name:"M"}]}] - `)}, - inDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - dependency: "dep.proto" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:"M.M"}] - }] - `), - wantDesc: mustParseFile(` - name: "test.proto" - package: "fizz.buzz" - dependency: "dep.proto" - message_type: [{ - name: "M" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".fizz.M.M"}] - }] - `), - }, { - label: "namespace conflict on enum value", - inDesc: mustParseFile(` - name: "test.proto" - enum_type: [{ - name: "foo" - value: [{name:"foo" number:0}] - }] - `), - wantErr: `descriptor "foo" already declared`, - }, { - label: "no namespace conflict on message field", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{ - name: "foo" - field: [{name:"foo" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }] - `), - }, { - label: "invalid name", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name: "$"}] - `), - wantErr: `descriptor "" has an invalid nested name: "$"`, - }, { - label: "invalid empty enum", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{name:"E"}]}] - `), - wantErr: `enum "M.E" must contain at least one value declaration`, - }, { - label: "invalid enum value without number", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{name:"E" value:[{name:"one"}]}]}] - `), - wantErr: `enum value "M.one" must have a specified number`, - }, { - label: "valid enum", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{name:"E" value:[{name:"one" number:1}]}]}] - `), - }, { - label: "invalid enum reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_name: [""] - value: [{name:"V" number:0}] - }]}] - `), - // NOTE: In theory this should be an error. - // See https://github.com/protocolbuffers/protobuf/issues/6335. - /*wantErr: `enum "M.E" reserved names has invalid name: ""`,*/ - }, { - label: "duplicate enum reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_name: ["foo", "foo"] - }]}] - `), - wantErr: `enum "M.E" reserved names has duplicate name: "foo"`, - }, { - label: "valid enum reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_name: ["foo", "bar"] - value: [{name:"baz" number:1}] - }]}] - `), - }, { - label: "use of enum reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_name: ["foo", "bar"] - value: [{name:"foo" number:1}] - }]}] - `), - wantErr: `enum value "M.foo" must not use reserved name`, - }, { - label: "invalid enum reserved ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_range: [{start:5 end:4}] - }]}] - `), - wantErr: `enum "M.E" reserved ranges has invalid range: 5 to 4`, - }, { - label: "overlapping enum reserved ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_range: [{start:1 end:1000}, {start:10 end:100}] - }]}] - `), - wantErr: `enum "M.E" reserved ranges has overlapping ranges: 1 to 1000 with 10 to 100`, - }, { - label: "valid enum reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_range: [{start:1 end:10}, {start:100 end:1000}] - value: [{name:"baz" number:50}] - }]}] - `), - }, { - label: "use of enum reserved range", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - reserved_range: [{start:1 end:10}, {start:100 end:1000}] - value: [{name:"baz" number:500}] - }]}] - `), - wantErr: `enum value "M.baz" must not use reserved number 500`, - }, { - label: "unused enum alias feature", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"baz" number:500}] - options: {allow_alias:true} - }]}] - `), - wantErr: `enum "M.E" allows aliases, but none were found`, - }, { - label: "enum number conflicts", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"foo" number:0}, {name:"bar" number:1}, {name:"baz" number:1}] - }]}] - `), - wantErr: `enum "M.E" has conflicting non-aliased values on number 1: "baz" with "bar"`, - }, { - label: "aliased enum numbers", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"foo" number:0}, {name:"bar" number:1}, {name:"baz" number:1}] - options: {allow_alias:true} - }]}] - `), - }, { - label: "invalid proto3 enum", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"baz" number:500}] - }]}] - `), - wantErr: `enum "M.baz" using proto3 semantics must have zero number for the first value`, - }, { - label: "valid proto3 enum", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"baz" number:0}] - }]}] - `), - }, { - label: "proto3 enum name prefix conflict", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"e_Foo" number:0}, {name:"fOo" number:1}] - }]}] - `), - wantErr: `enum "M.E" using proto3 semantics has conflict: "fOo" with "e_Foo"`, - }, { - label: "proto2 enum has name prefix check", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"e_Foo" number:0}, {name:"fOo" number:1}] - }]}] - `), - }, { - label: "proto3 enum same name prefix with number conflict", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"e_Foo" number:0}, {name:"fOo" number:0}] - }]}] - `), - wantErr: `enum "M.E" has conflicting non-aliased values on number 0: "fOo" with "e_Foo"`, - }, { - label: "proto3 enum same name prefix with alias numbers", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" enum_type:[{ - name: "E" - value: [{name:"e_Foo" number:0}, {name:"fOo" number:0}] - options: {allow_alias: true} - }]}] - `), - }, { - label: "invalid message reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_name: ["$"] - }]}] - `), - // NOTE: In theory this should be an error. - // See https://github.com/protocolbuffers/protobuf/issues/6335. - /*wantErr: `message "M.M" reserved names has invalid name: "$"`,*/ - }, { - label: "valid message reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_name: ["foo", "bar"] - field: [{name:"foo" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message field "M.M.foo" must not use reserved name`, - }, { - label: "valid message reserved names", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_name: ["foo", "bar"] - field: [{name:"baz" number:1 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:0}] - oneof_decl: [{name:"foo"}] # not affected by reserved_name - }]}] - `), - }, { - label: "invalid reserved number", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_range: [{start:1 end:1}] - field: [{name:"baz" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message "M.M" reserved ranges has invalid field number: 0`, - }, { - label: "invalid reserved ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_range: [{start:2 end:2}] - field: [{name:"baz" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message "M.M" reserved ranges has invalid range: 2 to 1`, - }, { - label: "overlapping reserved ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_range: [{start:1 end:10}, {start:2 end:9}] - field: [{name:"baz" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message "M.M" reserved ranges has overlapping ranges: 1 to 9 with 2 to 8`, - }, { - label: "use of reserved message field number", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_range: [{start:10 end:20}, {start:20 end:30}, {start:30 end:31}] - field: [{name:"baz" number:30 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message field "M.M.baz" must not use reserved number 30`, - }, { - label: "invalid extension ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - extension_range: [{start:-500 end:2}] - field: [{name:"baz" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}] - }]}] - `), - wantErr: `message "M.M" extension ranges has invalid field number: -500`, - }, { - label: "overlapping reserved and extension ranges", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - reserved_range: [{start:15 end:20}, {start:1 end:3}, {start:7 end:10}] - extension_range: [{start:8 end:9}, {start:3 end:5}] - }]}] - `), - wantErr: `message "M.M" reserved and extension ranges has overlapping ranges: 7 to 9 with 8`, - }, { - label: "message field conflicting number", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - field: [ - {name:"one" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"One" number:1 label:LABEL_OPTIONAL type:TYPE_STRING} - ] - }]}] - `), - wantErr: `message "M.M" has conflicting fields: "One" with "one"`, - }, { - label: "invalid MessageSet", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - options: {message_set_wire_format:true} - }]}] - `), - wantErr: func() string { - if flags.ProtoLegacy { - return `message "M.M" is an invalid proto1 MessageSet` - } else { - return `message "M.M" is a MessageSet, which is a legacy proto1 feature that is no longer supported` - } - }(), - }, { - label: "valid MessageSet", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - extension_range: [{start:1 end:100000}] - options: {message_set_wire_format:true} - }]}] - `), - wantErr: func() string { - if flags.ProtoLegacy { - return "" - } else { - return `message "M.M" is a MessageSet, which is a legacy proto1 feature that is no longer supported` - } - }(), - }, { - label: "invalid extension ranges in proto3", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - extension_range: [{start:1 end:100000}] - }]}] - `), - wantErr: `message "M.M" using proto3 semantics cannot have extension ranges`, - }, { - label: "proto3 message fields conflict", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - field: [ - {name:"_b_a_z_" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"baz" number:2 label:LABEL_OPTIONAL type:TYPE_STRING} - ] - }]}] - `), - wantErr: `message "M.M" using proto3 semantics has conflict: "baz" with "_b_a_z_"`, - }, { - label: "proto3 message fields", - inDesc: mustParseFile(` - syntax: "proto3" - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - field: [{name:"_b_a_z_" number:1 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:0}] - oneof_decl: [{name:"baz"}] # proto3 name conflict logic does not include oneof - }]}] - `), - }, { - label: "proto2 message fields with no conflict", - inDesc: mustParseFile(` - name: "test.proto" - message_type: [{name:"M" nested_type:[{ - name: "M" - field: [ - {name:"_b_a_z_" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"baz" number:2 label:LABEL_OPTIONAL type:TYPE_STRING} - ] - }]}] - `), - }, { - label: "proto3 message with unresolved enum", - inDesc: mustParseFile(` - name: "test.proto" - syntax: "proto3" - message_type: [{ - name: "M" - field: [ - {name:"enum" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".fizz.buzz.Enum"} - ] - }] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - // TODO: Test field and oneof handling in validateMessageDeclarations - // TODO: Test unmarshalDefault - // TODO: Test validateExtensionDeclarations - // TODO: Test checkValidGroup - // TODO: Test checkValidMap - }, { - label: "empty service", - inDesc: mustParseFile(` - name: "test.proto" - service: [{name:"service"}] - `), - }, { - label: "service with method with unresolved", - inDesc: mustParseFile(` - name: "test.proto" - service: [{ - name: "service" - method: [{ - name:"method" - input_type:"foo" - output_type:".foo.bar.baz" - }] - }] - `), - inOpts: FileOptions{AllowUnresolvable: true}, - }, { - label: "service with wrong reference type", - inDeps: []*descriptorpb.FileDescriptorProto{ - cloneFile(proto3Message), - cloneFile(proto2Enum), - }, - inDesc: mustParseFile(` - name: "test.proto" - dependency: ["proto2_enum.proto", "proto3_message.proto"] - service: [{ - name: "service" - method: [{ - name: "method" - input_type: ".test.proto2.Enum", - output_type: ".test.proto3.Message" - }] - }] - `), - wantErr: `service method "service.method" cannot resolve input: resolved "test.proto2.Enum", but it is not an message`, - }} - - for _, tt := range tests { - t.Run(tt.label, func(t *testing.T) { - r := new(protoregistry.Files) - for i, dep := range tt.inDeps { - f, err := tt.inOpts.New(dep, r) - if err != nil { - t.Fatalf("dependency %d: unexpected NewFile() error: %v", i, err) - } - if err := r.RegisterFile(f); err != nil { - t.Fatalf("dependency %d: unexpected Register() error: %v", i, err) - } - } - var gotDesc *descriptorpb.FileDescriptorProto - if tt.wantErr == "" && tt.wantDesc == nil { - tt.wantDesc = cloneFile(tt.inDesc) - } - gotFile, err := tt.inOpts.New(tt.inDesc, r) - if gotFile != nil { - gotDesc = ToFileDescriptorProto(gotFile) - } - if !proto.Equal(gotDesc, tt.wantDesc) { - t.Errorf("NewFile() mismatch:\ngot %v\nwant %v", gotDesc, tt.wantDesc) - } - if ((err == nil) != (tt.wantErr == "")) || !strings.Contains(fmt.Sprint(err), tt.wantErr) { - t.Errorf("NewFile() error:\ngot: %v\nwant: %v", err, tt.wantErr) - } - }) - } -} - -func TestNewFiles(t *testing.T) { - fdset := &descriptorpb.FileDescriptorSet{ - File: []*descriptorpb.FileDescriptorProto{ - mustParseFile(` - name: "test.proto" - package: "fizz" - dependency: "dep.proto" - message_type: [{ - name: "M2" - field: [{name:"F" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:"M1"}] - }] - `), - // Inputs deliberately out of order. - mustParseFile(` - name: "dep.proto" - package: "fizz" - message_type: [{name:"M1"}] - `), - }, - } - f, err := NewFiles(fdset) - if err != nil { - t.Fatal(err) - } - m1, err := f.FindDescriptorByName("fizz.M1") - if err != nil { - t.Fatalf(`f.FindDescriptorByName("fizz.M1") = %v`, err) - } - m2, err := f.FindDescriptorByName("fizz.M2") - if err != nil { - t.Fatalf(`f.FindDescriptorByName("fizz.M2") = %v`, err) - } - if m2.(protoreflect.MessageDescriptor).Fields().ByName("F").Message() != m1 { - t.Fatalf(`m1.Fields().ByName("F").Message() != m2`) - } -} - -func TestNewFilesImportCycle(t *testing.T) { - fdset := &descriptorpb.FileDescriptorSet{ - File: []*descriptorpb.FileDescriptorProto{ - mustParseFile(` - name: "test.proto" - package: "fizz" - dependency: "dep.proto" - `), - mustParseFile(` - name: "dep.proto" - package: "fizz" - dependency: "test.proto" - `), - }, - } - _, err := NewFiles(fdset) - if err == nil { - t.Fatal("NewFiles with import cycle: success, want error") - } -} - -func TestSourceLocations(t *testing.T) { - fd := mustParseFile(` - name: "comments.proto" - message_type: [{ - name: "Message1" - field: [ - {name:"field1" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"field2" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}, - {name:"field3" number:3 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:0}, - {name:"field4" number:4 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:0}, - {name:"field5" number:5 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:1}, - {name:"field6" number:6 label:LABEL_OPTIONAL type:TYPE_STRING oneof_index:1} - ] - extension: [ - {name:"extension1" number:100 label:LABEL_OPTIONAL type:TYPE_STRING extendee:".Message1"}, - {name:"extension2" number:101 label:LABEL_OPTIONAL type:TYPE_STRING extendee:".Message1"} - ] - nested_type: [{name:"Message1"}, {name:"Message2"}] - extension_range: {start:100 end:536870912} - oneof_decl: [{name:"oneof1"}, {name:"oneof2"}] - }, { - name: "Message2" - enum_type: { - name: "Enum1" - value: [ - {name: "FOO", number: 0}, - {name: "BAR", number: 1} - ] - } - }] - enum_type: { - name: "Enum1" - value: [ - {name: "FOO", number: 0}, - {name: "BAR", number: 1} - ] - } - service: { - name: "Service1" - method: [ - {name:"Method1" input_type:".Message1" output_type:".Message1"}, - {name:"Method2" input_type:".Message2" output_type:".Message2"} - ] - } - extension: [ - {name:"extension1" number:102 label:LABEL_OPTIONAL type:TYPE_STRING extendee:".Message1"}, - {name:"extension2" number:103 label:LABEL_OPTIONAL type:TYPE_STRING extendee:".Message1"} - ] - source_code_info: { - location: [ - {span:[0,0,69,1]}, - {path:[12] span:[0,0,18]}, - {path:[5,0] span:[3,0,8,1] leading_comments:" Enum1\r\n"}, - {path:[5,0,1] span:[3,5,10]}, - {path:[5,0,2,0] span:[5,2,10] leading_comments:" FOO\r\n"}, - {path:[5,0,2,0,1] span:[5,2,5]}, - {path:[5,0,2,0,2] span:[5,8,9]}, - {path:[5,0,2,1] span:[7,2,10] leading_comments:" BAR\r\n"}, - {path:[5,0,2,1,1] span:[7,2,5]}, - {path:[5,0,2,1,2] span:[7,8,9]}, - {path:[4,0] span:[11,0,43,1] leading_comments:" Message1\r\n"}, - {path:[4,0,1] span:[11,8,16]}, - {path:[4,0,3,0] span:[13,2,21] leading_comments:" Message1.Message1\r\n"}, - {path:[4,0,3,0,1] span:[13,10,18]}, - {path:[4,0,3,1] span:[15,2,21] leading_comments:" Message1.Message2\r\n"}, - {path:[4,0,3,1,1] span:[15,10,18]}, - {path:[4,0,2,0] span:[18,2,29] leading_comments:" Message1.field1\r\n"}, - {path:[4,0,2,0,4] span:[18,2,10]}, - {path:[4,0,2,0,5] span:[18,11,17]}, - {path:[4,0,2,0,1] span:[18,18,24]}, - {path:[4,0,2,0,3] span:[18,27,28]}, - {path:[4,0,2,1] span:[20,2,29] leading_comments:" Message1.field2\r\n"}, - {path:[4,0,2,1,4] span:[20,2,10]}, - {path:[4,0,2,1,5] span:[20,11,17]}, - {path:[4,0,2,1,1] span:[20,18,24]}, - {path:[4,0,2,1,3] span:[20,27,28]}, - {path:[4,0,8,0] span:[22,2,27,3] leading_comments:" Message1.oneof1\r\n"}, - {path:[4,0,8,0,1] span:[22,8,14]}, - {path:[4,0,2,2] span:[24,4,22] leading_comments:" Message1.field3\r\n"}, - {path:[4,0,2,2,5] span:[24,4,10]}, - {path:[4,0,2,2,1] span:[24,11,17]}, - {path:[4,0,2,2,3] span:[24,20,21]}, - {path:[4,0,2,3] span:[26,4,22] leading_comments:" Message1.field4\r\n"}, - {path:[4,0,2,3,5] span:[26,4,10]}, - {path:[4,0,2,3,1] span:[26,11,17]}, - {path:[4,0,2,3,3] span:[26,20,21]}, - {path:[4,0,8,1] span:[29,2,34,3] leading_comments:" Message1.oneof2\r\n"}, - {path:[4,0,8,1,1] span:[29,8,14]}, - {path:[4,0,2,4] span:[31,4,22] leading_comments:" Message1.field5\r\n"}, - {path:[4,0,2,4,5] span:[31,4,10]}, - {path:[4,0,2,4,1] span:[31,11,17]}, - {path:[4,0,2,4,3] span:[31,20,21]}, - {path:[4,0,2,5] span:[33,4,22] leading_comments:" Message1.field6\r\n"}, - {path:[4,0,2,5,5] span:[33,4,10]}, - {path:[4,0,2,5,1] span:[33,11,17]}, - {path:[4,0,2,5,3] span:[33,20,21]}, - {path:[4,0,5] span:[36,2,24]}, - {path:[4,0,5,0] span:[36,13,23]}, - {path:[4,0,5,0,1] span:[36,13,16]}, - {path:[4,0,5,0,2] span:[36,20,23]}, - {path:[4,0,6] span:[37,2,42,3]}, - {path:[4,0,6,0] span:[39,4,37] leading_comments:" Message1.extension1\r\n"}, - {path:[4,0,6,0,2] span:[37,9,18]}, - {path:[4,0,6,0,4] span:[39,4,12]}, - {path:[4,0,6,0,5] span:[39,13,19]}, - {path:[4,0,6,0,1] span:[39,20,30]}, - {path:[4,0,6,0,3] span:[39,33,36]}, - {path:[4,0,6,1] span:[41,4,37] leading_comments:" Message1.extension2\r\n"}, - {path:[4,0,6,1,2] span:[37,9,18]}, - {path:[4,0,6,1,4] span:[41,4,12]}, - {path:[4,0,6,1,5] span:[41,13,19]}, - {path:[4,0,6,1,1] span:[41,20,30]}, - {path:[4,0,6,1,3] span:[41,33,36]}, - {path:[7] span:[45,0,50,1]}, - {path:[7,0] span:[47,2,35] leading_comments:" extension1\r\n"}, - {path:[7,0,2] span:[45,7,15]}, - {path:[7,0,4] span:[47,2,10]}, - {path:[7,0,5] span:[47,11,17]}, - {path:[7,0,1] span:[47,18,28]}, - {path:[7,0,3] span:[47,31,34]}, - {path:[7,1] span:[49,2,35] leading_comments:" extension2\r\n"}, - {path:[7,1,2] span:[45,7,15]}, - {path:[7,1,4] span:[49,2,10]}, - {path:[7,1,5] span:[49,11,17]}, - {path:[7,1,1] span:[49,18,28]}, - {path:[7,1,3] span:[49,31,34]}, - {path:[4,1] span:[53,0,61,1] leading_comments:" Message2\r\n"}, - {path:[4,1,1] span:[53,8,16]}, - {path:[4,1,4,0] span:[55,2,60,3] leading_comments:" Message2.Enum1\r\n"}, - {path:[4,1,4,0,1] span:[55,7,12]}, - {path:[4,1,4,0,2,0] span:[57,4,12] leading_comments:" Message2.FOO\r\n"}, - {path:[4,1,4,0,2,0,1] span:[57,4,7]}, - {path:[4,1,4,0,2,0,2] span:[57,10,11]}, - {path:[4,1,4,0,2,1] span:[59,4,12] leading_comments:" Message2.BAR\r\n"}, - {path:[4,1,4,0,2,1,1] span:[59,4,7]}, - {path:[4,1,4,0,2,1,2] span:[59,10,11]}, - {path:[6,0] span:[64,0,69,1] leading_comments:" Service1\r\n"}, - {path:[6,0,1] span:[64,8,16]}, - {path:[6,0,2,0] span:[66,2,43] leading_comments:" Service1.Method1\r\n"}, - {path:[6,0,2,0,1] span:[66,6,13]}, - {path:[6,0,2,0,2] span:[66,14,22]}, - {path:[6,0,2,0,3] span:[66,33,41]}, - {path:[6,0,2,1] span:[68,2,43] leading_comments:" Service1.Method2\r\n"}, - {path:[6,0,2,1,1] span:[68,6,13]}, - {path:[6,0,2,1,2] span:[68,14,22]}, - {path:[6,0,2,1,3] span:[68,33,41]} - ] - } - `) - fileDesc, err := NewFile(fd, nil) - if err != nil { - t.Fatalf("NewFile error: %v", err) - } - - var walkDescs func(protoreflect.Descriptor, func(protoreflect.Descriptor)) - walkDescs = func(d protoreflect.Descriptor, f func(protoreflect.Descriptor)) { - f(d) - if d, ok := d.(interface { - Enums() protoreflect.EnumDescriptors - }); ok { - eds := d.Enums() - for i := 0; i < eds.Len(); i++ { - walkDescs(eds.Get(i), f) - } - } - if d, ok := d.(interface { - Values() protoreflect.EnumValueDescriptors - }); ok { - vds := d.Values() - for i := 0; i < vds.Len(); i++ { - walkDescs(vds.Get(i), f) - } - } - if d, ok := d.(interface { - Messages() protoreflect.MessageDescriptors - }); ok { - mds := d.Messages() - for i := 0; i < mds.Len(); i++ { - walkDescs(mds.Get(i), f) - } - } - if d, ok := d.(interface { - Fields() protoreflect.FieldDescriptors - }); ok { - fds := d.Fields() - for i := 0; i < fds.Len(); i++ { - walkDescs(fds.Get(i), f) - } - } - if d, ok := d.(interface { - Oneofs() protoreflect.OneofDescriptors - }); ok { - ods := d.Oneofs() - for i := 0; i < ods.Len(); i++ { - walkDescs(ods.Get(i), f) - } - } - if d, ok := d.(interface { - Extensions() protoreflect.ExtensionDescriptors - }); ok { - xds := d.Extensions() - for i := 0; i < xds.Len(); i++ { - walkDescs(xds.Get(i), f) - } - } - if d, ok := d.(interface { - Services() protoreflect.ServiceDescriptors - }); ok { - sds := d.Services() - for i := 0; i < sds.Len(); i++ { - walkDescs(sds.Get(i), f) - } - } - if d, ok := d.(interface { - Methods() protoreflect.MethodDescriptors - }); ok { - mds := d.Methods() - for i := 0; i < mds.Len(); i++ { - walkDescs(mds.Get(i), f) - } - } - } - - var numDescs int - walkDescs(fileDesc, func(d protoreflect.Descriptor) { - // The comment for every descriptor should be the full name itself. - got := strings.TrimSpace(fileDesc.SourceLocations().ByDescriptor(d).LeadingComments) - want := string(d.FullName()) - if got != want { - t.Errorf("comment mismatch: got %v, want %v", got, want) - } - numDescs++ - }) - if numDescs != 30 { - t.Errorf("visited %d descriptor, expected 30", numDescs) - } -} diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/gotest/ya.make b/vendor/google.golang.org/protobuf/reflect/protodesc/gotest/ya.make deleted file mode 100644 index 18b2ef76c1..0000000000 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/gotest/ya.make +++ /dev/null @@ -1,5 +0,0 @@ -GO_TEST_FOR(vendor/google.golang.org/protobuf/reflect/protodesc) - -LICENSE(BSD-3-Clause) - -END() diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go index a7c5ceffc9..9d6e05420f 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go @@ -16,7 +16,7 @@ import ( "google.golang.org/protobuf/types/descriptorpb" ) -// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a +// ToFileDescriptorProto copies a [protoreflect.FileDescriptor] into a // google.protobuf.FileDescriptorProto message. func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto { p := &descriptorpb.FileDescriptorProto{ @@ -70,13 +70,13 @@ func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileD for i, exts := 0, file.Extensions(); i < exts.Len(); i++ { p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i))) } - if syntax := file.Syntax(); syntax != protoreflect.Proto2 { + if syntax := file.Syntax(); syntax != protoreflect.Proto2 && syntax.IsValid() { p.Syntax = proto.String(file.Syntax().String()) } return p } -// ToDescriptorProto copies a protoreflect.MessageDescriptor into a +// ToDescriptorProto copies a [protoreflect.MessageDescriptor] into a // google.protobuf.DescriptorProto message. func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto { p := &descriptorpb.DescriptorProto{ @@ -119,7 +119,7 @@ func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.Des return p } -// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a +// ToFieldDescriptorProto copies a [protoreflect.FieldDescriptor] into a // google.protobuf.FieldDescriptorProto message. func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto { p := &descriptorpb.FieldDescriptorProto{ @@ -168,7 +168,7 @@ func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.Fi return p } -// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a +// ToOneofDescriptorProto copies a [protoreflect.OneofDescriptor] into a // google.protobuf.OneofDescriptorProto message. func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto { return &descriptorpb.OneofDescriptorProto{ @@ -177,7 +177,7 @@ func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.On } } -// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a +// ToEnumDescriptorProto copies a [protoreflect.EnumDescriptor] into a // google.protobuf.EnumDescriptorProto message. func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto { p := &descriptorpb.EnumDescriptorProto{ @@ -200,7 +200,7 @@ func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumD return p } -// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a +// ToEnumValueDescriptorProto copies a [protoreflect.EnumValueDescriptor] into a // google.protobuf.EnumValueDescriptorProto message. func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto { return &descriptorpb.EnumValueDescriptorProto{ @@ -210,7 +210,7 @@ func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descrip } } -// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a +// ToServiceDescriptorProto copies a [protoreflect.ServiceDescriptor] into a // google.protobuf.ServiceDescriptorProto message. func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto { p := &descriptorpb.ServiceDescriptorProto{ @@ -223,7 +223,7 @@ func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descripto return p } -// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a +// ToMethodDescriptorProto copies a [protoreflect.MethodDescriptor] into a // google.protobuf.MethodDescriptorProto message. func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto { p := &descriptorpb.MethodDescriptorProto{ diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/ya.make b/vendor/google.golang.org/protobuf/reflect/protodesc/ya.make index 2a4f165b31..20d7db3136 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/ya.make +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/ya.make @@ -7,11 +7,10 @@ SRCS( desc_init.go desc_resolve.go desc_validate.go + editions.go proto.go ) -GO_TEST_SRCS(file_test.go) +GO_EMBED_PATTERN(editions_defaults.binpb) END() - -RECURSE(gotest) |