From eba8b0975f4efc219baabc1e0e13df28a6e1ad28 Mon Sep 17 00:00:00 2001 From: googleberg Date: Wed, 1 Mar 2023 21:35:32 -0700 Subject: [PATCH] cmd/protoc-gen-go: support protobuf retention feature This change strips out all descriptor option fields marked with [retention = RETENTION_SOURCE] before writing the FileDescriptor to the generated go code bindings. Change-Id: Ie624d9d4b4f211a256661d80a04199ae8401662b Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/472696 Reviewed-by: Damien Neil Reviewed-by: Lasse Folger --- cmd/protoc-gen-go/internal_gengo/reflect.go | 23 +- cmd/protoc-gen-go/retention_test.go | 178 +++++ cmd/protoc-gen-go/testdata/gen_test.go | 1 + .../testdata/retention/options_message.pb.go | 250 ++++++ .../testdata/retention/options_message.proto | 30 + .../testdata/retention/retention.pb.go | 725 ++++++++++++++++++ .../testdata/retention/retention.proto | 176 +++++ compiler/protogen/protogen.go | 96 +++ 8 files changed, 1478 insertions(+), 1 deletion(-) create mode 100644 cmd/protoc-gen-go/retention_test.go create mode 100755 cmd/protoc-gen-go/testdata/retention/options_message.pb.go create mode 100644 cmd/protoc-gen-go/testdata/retention/options_message.proto create mode 100755 cmd/protoc-gen-go/testdata/retention/retention.pb.go create mode 100644 cmd/protoc-gen-go/testdata/retention/retention.proto diff --git a/cmd/protoc-gen-go/internal_gengo/reflect.go b/cmd/protoc-gen-go/internal_gengo/reflect.go index 1319a1267..0048beb1e 100644 --- a/cmd/protoc-gen-go/internal_gengo/reflect.go +++ b/cmd/protoc-gen-go/internal_gengo/reflect.go @@ -12,6 +12,8 @@ import ( "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protopath" + "google.golang.org/protobuf/reflect/protorange" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" @@ -233,10 +235,29 @@ func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f g.P("}") } +// stripSourceRetentionFieldsFromMessage walks the given message tree recursively +// and clears any fields with the field option: [retention = RETENTION_SOURCE] +func stripSourceRetentionFieldsFromMessage(m protoreflect.Message) { + protorange.Range(m, func(ppv protopath.Values) error { + m2, ok := ppv.Index(-1).Value.Interface().(protoreflect.Message) + if !ok { + return nil + } + m2.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + fdo, ok := fd.Options().(*descriptorpb.FieldOptions) + if ok && fdo.GetRetention() == descriptorpb.FieldOptions_RETENTION_SOURCE { + m2.Clear(fd) + } + return true + }) + return nil + }) +} + func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) { descProto := proto.Clone(f.Proto).(*descriptorpb.FileDescriptorProto) descProto.SourceCodeInfo = nil // drop source code information - + stripSourceRetentionFieldsFromMessage(descProto.ProtoReflect()) b, err := proto.MarshalOptions{AllowPartial: true, Deterministic: true}.Marshal(descProto) if err != nil { gen.Error(err) diff --git a/cmd/protoc-gen-go/retention_test.go b/cmd/protoc-gen-go/retention_test.go new file mode 100644 index 000000000..db0b5f3a1 --- /dev/null +++ b/cmd/protoc-gen-go/retention_test.go @@ -0,0 +1,178 @@ +// 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 main + +import ( + "testing" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + retentionpb "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/retention" +) + +func TestFileOptionRetention(t *testing.T) { + options := retentionpb.File_cmd_protoc_gen_go_testdata_retention_retention_proto.Options() + tests := []struct { + name string + ext protoreflect.ExtensionType + wantField bool + wantValue int32 + }{ + { + name: "imported_plain_option", + ext: retentionpb.E_ImportedPlainOption, + wantField: true, + wantValue: 1, + }, + { + name: "imported_runtime_option", + ext: retentionpb.E_ImportedRuntimeRetentionOption, + wantField: true, + wantValue: 2, + }, + { + name: "imported_source_option", + ext: retentionpb.E_ImportedSourceRetentionOption, + wantField: false, + wantValue: 0, + }, + { + name: "plain_option", + ext: retentionpb.E_PlainOption, + wantField: true, + wantValue: 1, + }, + { + name: "runtime_option", + ext: retentionpb.E_RuntimeRetentionOption, + wantField: true, + wantValue: 2, + }, + { + name: "source_option", + ext: retentionpb.E_SourceRetentionOption, + wantField: false, + wantValue: 0, + }, + } + + for _, test := range tests { + if test.wantField != proto.HasExtension(options, test.ext) { + t.Errorf("HasExtension(%s): got %v, want %v", test.name, proto.HasExtension(options, test.ext), test.wantField) + } + if test.wantValue != proto.GetExtension(options, test.ext).(int32) { + t.Errorf("GetExtension(%s): got %d, want %d", test.name, proto.GetExtension(options, test.ext).(int32), test.wantValue) + } + } +} + +func TestAllEntitiesWithMessageOption(t *testing.T) { + file := retentionpb.File_cmd_protoc_gen_go_testdata_retention_retention_proto + verifyDescriptorOptions(t, string(file.Name()), file.Options()) + verifyEnums(t, file.Enums()) + verifyMessages(t, file.Messages()) + verifyExtensions(t, file.Extensions()) + verifyServices(t, file.Services()) +} + +func verifyExtensions(t *testing.T, extensions protoreflect.ExtensionDescriptors) { + t.Helper() + for i := 0; i < extensions.Len(); i++ { + verifyDescriptorOptions(t, string(extensions.Get(i).Name()), extensions.Get(i).Options()) + } +} + +func verifyMessages(t *testing.T, messages protoreflect.MessageDescriptors) { + t.Helper() + for i := 0; i < messages.Len(); i++ { + verifyDescriptorOptions(t, string(messages.Get(i).Name()), messages.Get(i).Options()) + verifyEnums(t, messages.Get(i).Enums()) + verifyMessages(t, messages.Get(i).Messages()) + verifyExtensions(t, messages.Get(i).Extensions()) + verifyFields(t, messages.Get(i).Fields()) + } +} + +func verifyFields(t *testing.T, fields protoreflect.FieldDescriptors) { + t.Helper() + for i := 0; i < fields.Len(); i++ { + verifyDescriptorOptions(t, string(fields.Get(i).Name()), fields.Get(i).Options()) + } +} + +func verifyEnums(t *testing.T, enums protoreflect.EnumDescriptors) { + t.Helper() + for i := 0; i < enums.Len(); i++ { + verifyDescriptorOptions(t, string(enums.Get(i).Name()), enums.Get(i).Options()) + verifyEnumValues(t, enums.Get(i).Values()) + } +} + +func verifyEnumValues(t *testing.T, values protoreflect.EnumValueDescriptors) { + t.Helper() + for i := 0; i < values.Len(); i++ { + verifyDescriptorOptions(t, string(values.Get(i).Name()), values.Get(i).Options()) + } +} + +func verifyServices(t *testing.T, services protoreflect.ServiceDescriptors) { + t.Helper() + for i := 0; i < services.Len(); i++ { + verifyDescriptorOptions(t, string(services.Get(i).Name()), services.Get(i).Options()) + verifyMethods(t, services.Get(i).Methods()) + } +} + +func verifyMethods(t *testing.T, methods protoreflect.MethodDescriptors) { + t.Helper() + for i := 0; i < methods.Len(); i++ { + verifyDescriptorOptions(t, string(methods.Get(i).Name()), methods.Get(i).Options()) + } +} + +func verifyDescriptorOptions(t *testing.T, entity string, options protoreflect.ProtoMessage) { + t.Helper() + options.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + maybeVerifyOption(t, fd, v) + return true + }) +} + +func maybeVerifyOption(t *testing.T, fd protoreflect.FieldDescriptor, v protoreflect.Value) { + t.Helper() + if fd.Kind() == protoreflect.MessageKind && string(fd.Message().FullName()) == "goproto.proto.testretention.OptionsMessage" { + if fd.IsList() { + for i := 0; i < v.List().Len(); i++ { + verifyOptionsMessage(t, string(fd.FullName()), v.List().Get(i).Message().Interface().(*retentionpb.OptionsMessage)) + } + } else { + verifyOptionsMessage(t, string(fd.FullName()), v.Message().Interface().(*retentionpb.OptionsMessage)) + } + } +} + +func verifyOptionsMessage(t *testing.T, entity string, msg *retentionpb.OptionsMessage) { + t.Helper() + if msg.PlainField == nil { + t.Errorf("%s.OptionsMessage.HasField(plain_field): got false, want true", entity) + } + if msg.GetPlainField() != 1 { + t.Errorf("%s.OptionsMessage.GetField(plain_field): got %d, want 1", entity, msg.GetPlainField()) + } + if msg.RuntimeRetentionField == nil { + t.Errorf("%s.OptionsMessage.HasField(runtime_retention_field): got false, want true", entity) + } + if msg.GetRuntimeRetentionField() != 2 { + t.Errorf("%s.OptionsMessage.GetField(runtime_retention_field): got %d, want 2", entity, msg.GetRuntimeRetentionField()) + } + if msg.SourceRetentionField != nil { + t.Errorf("%s.OptionsMessage.HasField(source_retention_field): got true, want false", entity) + } + if msg.GetSourceRetentionField() != 0 { + // Checking that we get 0 even though this was set to 3 in the source file + t.Errorf("%s.OptionsMessage.GetField(source_retention_field): got %d, want 0", entity, msg.GetSourceRetentionField()) + } +} diff --git a/cmd/protoc-gen-go/testdata/gen_test.go b/cmd/protoc-gen-go/testdata/gen_test.go index fa411566f..8e7c27a1b 100644 --- a/cmd/protoc-gen-go/testdata/gen_test.go +++ b/cmd/protoc-gen-go/testdata/gen_test.go @@ -26,4 +26,5 @@ import ( _ "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/nopackage" _ "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/proto2" _ "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/proto3" + _ "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/retention" ) diff --git a/cmd/protoc-gen-go/testdata/retention/options_message.pb.go b/cmd/protoc-gen-go/testdata/retention/options_message.pb.go new file mode 100755 index 000000000..5b132bf97 --- /dev/null +++ b/cmd/protoc-gen-go/testdata/retention/options_message.pb.go @@ -0,0 +1,250 @@ +// 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: cmd/protoc-gen-go/testdata/retention/options_message.proto + +package retention + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" +) + +// Retention attributes set on fields nested within a message +type OptionsMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlainField *int32 `protobuf:"varint,1,opt,name=plain_field,json=plainField" json:"plain_field,omitempty"` + RuntimeRetentionField *int32 `protobuf:"varint,2,opt,name=runtime_retention_field,json=runtimeRetentionField" json:"runtime_retention_field,omitempty"` + SourceRetentionField *int32 `protobuf:"varint,3,opt,name=source_retention_field,json=sourceRetentionField" json:"source_retention_field,omitempty"` +} + +func (x *OptionsMessage) Reset() { + *x = OptionsMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionsMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionsMessage) ProtoMessage() {} + +func (x *OptionsMessage) ProtoReflect() protoreflect.Message { + mi := &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionsMessage.ProtoReflect.Descriptor instead. +func (*OptionsMessage) Descriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescGZIP(), []int{0} +} + +func (x *OptionsMessage) GetPlainField() int32 { + if x != nil && x.PlainField != nil { + return *x.PlainField + } + return 0 +} + +func (x *OptionsMessage) GetRuntimeRetentionField() int32 { + if x != nil && x.RuntimeRetentionField != nil { + return *x.RuntimeRetentionField + } + return 0 +} + +func (x *OptionsMessage) GetSourceRetentionField() int32 { + if x != nil && x.SourceRetentionField != nil { + return *x.SourceRetentionField + } + return 0 +} + +var file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 511807920, + Name: "testretention.imported_plain_option", + Tag: "varint,511807920,opt,name=imported_plain_option", + Filename: "cmd/protoc-gen-go/testdata/retention/options_message.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 512484074, + Name: "testretention.imported_runtime_retention_option", + Tag: "varint,512484074,opt,name=imported_runtime_retention_option", + Filename: "cmd/protoc-gen-go/testdata/retention/options_message.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 512645287, + Name: "testretention.imported_source_retention_option", + Tag: "varint,512645287,opt,name=imported_source_retention_option", + Filename: "cmd/protoc-gen-go/testdata/retention/options_message.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504871168, + Name: "testretention.file_option", + Tag: "bytes,504871168,opt,name=file_option", + Filename: "cmd/protoc-gen-go/testdata/retention/options_message.proto", + }, +} + +// Extension fields to descriptorpb.FileOptions. +var ( + // optional int32 imported_plain_option = 511807920; + E_ImportedPlainOption = &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes[0] + // optional int32 imported_runtime_retention_option = 512484074; + E_ImportedRuntimeRetentionOption = &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes[1] + // optional int32 imported_source_retention_option = 512645287; + E_ImportedSourceRetentionOption = &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes[2] + // optional testretention.OptionsMessage file_option = 504871168; + E_FileOption = &file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes[3] +) + +var File_cmd_protoc_gen_go_testdata_retention_options_message_proto protoreflect.FileDescriptor + +var file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDesc = []byte{ + 0x0a, 0x3a, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, + 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x74, 0x65, + 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x20, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa9, 0x01, + 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x12, 0x3b, 0x0a, 0x17, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x42, 0x03, 0x88, 0x01, 0x01, 0x52, 0x15, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x39, + 0x0a, 0x16, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, + 0x88, 0x01, 0x02, 0x52, 0x14, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x54, 0x0a, 0x15, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xb0, 0xa3, 0x86, 0xf4, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x70, 0x0a, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0xea, 0xc5, 0xaf, 0xf4, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0x88, 0x01, + 0x01, 0x52, 0x1e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x6e, 0x0a, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0xa7, 0xb1, 0xb9, 0xf4, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0x88, + 0x01, 0x02, 0x52, 0x1d, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x60, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x80, + 0xf2, 0xde, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, + 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x41, 0x5a, 0x3f, 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, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, + 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, +} + +var ( + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescOnce sync.Once + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescData = file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDesc +) + +func file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescGZIP() []byte { + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescOnce.Do(func() { + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescData) + }) + return file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDescData +} + +var file_cmd_protoc_gen_go_testdata_retention_options_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_cmd_protoc_gen_go_testdata_retention_options_message_proto_goTypes = []interface{}{ + (*OptionsMessage)(nil), // 0: testretention.OptionsMessage + (*descriptorpb.FileOptions)(nil), // 1: google.protobuf.FileOptions +} +var file_cmd_protoc_gen_go_testdata_retention_options_message_proto_depIdxs = []int32{ + 1, // 0: testretention.imported_plain_option:extendee -> google.protobuf.FileOptions + 1, // 1: testretention.imported_runtime_retention_option:extendee -> google.protobuf.FileOptions + 1, // 2: testretention.imported_source_retention_option:extendee -> google.protobuf.FileOptions + 1, // 3: testretention.file_option:extendee -> google.protobuf.FileOptions + 0, // 4: testretention.file_option:type_name -> testretention.OptionsMessage + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 4, // [4:5] is the sub-list for extension type_name + 0, // [0:4] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_cmd_protoc_gen_go_testdata_retention_options_message_proto_init() } +func file_cmd_protoc_gen_go_testdata_retention_options_message_proto_init() { + if File_cmd_protoc_gen_go_testdata_retention_options_message_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionsMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 4, + NumServices: 0, + }, + GoTypes: file_cmd_protoc_gen_go_testdata_retention_options_message_proto_goTypes, + DependencyIndexes: file_cmd_protoc_gen_go_testdata_retention_options_message_proto_depIdxs, + MessageInfos: file_cmd_protoc_gen_go_testdata_retention_options_message_proto_msgTypes, + ExtensionInfos: file_cmd_protoc_gen_go_testdata_retention_options_message_proto_extTypes, + }.Build() + File_cmd_protoc_gen_go_testdata_retention_options_message_proto = out.File + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_rawDesc = nil + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_goTypes = nil + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_depIdxs = nil +} diff --git a/cmd/protoc-gen-go/testdata/retention/options_message.proto b/cmd/protoc-gen-go/testdata/retention/options_message.proto new file mode 100644 index 000000000..afa6cd44f --- /dev/null +++ b/cmd/protoc-gen-go/testdata/retention/options_message.proto @@ -0,0 +1,30 @@ +// 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. + +syntax = "proto2"; + +package testretention; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/retention"; + +// Retention attributes set on fields nested within a message +message OptionsMessage { + optional int32 plain_field = 1; + optional int32 runtime_retention_field = 2 [retention = RETENTION_RUNTIME]; + optional int32 source_retention_field = 3 [retention = RETENTION_SOURCE]; +} + +extend google.protobuf.FileOptions { + optional int32 imported_plain_option = 511807920; + optional int32 imported_runtime_retention_option = 512484074 + [retention = RETENTION_RUNTIME]; + optional int32 imported_source_retention_option = 512645287 + [retention = RETENTION_SOURCE]; +} + +extend google.protobuf.FileOptions { + optional OptionsMessage file_option = 504871168; +} \ No newline at end of file diff --git a/cmd/protoc-gen-go/testdata/retention/retention.pb.go b/cmd/protoc-gen-go/testdata/retention/retention.pb.go new file mode 100755 index 000000000..f9624b783 --- /dev/null +++ b/cmd/protoc-gen-go/testdata/retention/retention.pb.go @@ -0,0 +1,725 @@ +// 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: cmd/protoc-gen-go/testdata/retention/retention.proto + +package retention + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" +) + +type TopLevelEnum int32 + +const ( + TopLevelEnum_TOP_LEVEL_UNKNOWN TopLevelEnum = 0 +) + +// Enum value maps for TopLevelEnum. +var ( + TopLevelEnum_name = map[int32]string{ + 0: "TOP_LEVEL_UNKNOWN", + } + TopLevelEnum_value = map[string]int32{ + "TOP_LEVEL_UNKNOWN": 0, + } +) + +func (x TopLevelEnum) Enum() *TopLevelEnum { + p := new(TopLevelEnum) + *p = x + return p +} + +func (x TopLevelEnum) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TopLevelEnum) Descriptor() protoreflect.EnumDescriptor { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes[0].Descriptor() +} + +func (TopLevelEnum) Type() protoreflect.EnumType { + return &file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes[0] +} + +func (x TopLevelEnum) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *TopLevelEnum) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = TopLevelEnum(num) + return nil +} + +// Deprecated: Use TopLevelEnum.Descriptor instead. +func (TopLevelEnum) EnumDescriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP(), []int{0} +} + +type TopLevelMessage_NestedEnum int32 + +const ( + TopLevelMessage_NESTED_UNKNOWN TopLevelMessage_NestedEnum = 0 +) + +// Enum value maps for TopLevelMessage_NestedEnum. +var ( + TopLevelMessage_NestedEnum_name = map[int32]string{ + 0: "NESTED_UNKNOWN", + } + TopLevelMessage_NestedEnum_value = map[string]int32{ + "NESTED_UNKNOWN": 0, + } +) + +func (x TopLevelMessage_NestedEnum) Enum() *TopLevelMessage_NestedEnum { + p := new(TopLevelMessage_NestedEnum) + *p = x + return p +} + +func (x TopLevelMessage_NestedEnum) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TopLevelMessage_NestedEnum) Descriptor() protoreflect.EnumDescriptor { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes[1].Descriptor() +} + +func (TopLevelMessage_NestedEnum) Type() protoreflect.EnumType { + return &file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes[1] +} + +func (x TopLevelMessage_NestedEnum) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *TopLevelMessage_NestedEnum) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = TopLevelMessage_NestedEnum(num) + return nil +} + +// Deprecated: Use TopLevelMessage_NestedEnum.Descriptor instead. +func (TopLevelMessage_NestedEnum) EnumDescriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP(), []int{1, 0} +} + +type Extendee struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + extensionFields protoimpl.ExtensionFields +} + +func (x *Extendee) Reset() { + *x = Extendee{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Extendee) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Extendee) ProtoMessage() {} + +func (x *Extendee) ProtoReflect() protoreflect.Message { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Extendee.ProtoReflect.Descriptor instead. +func (*Extendee) Descriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP(), []int{0} +} + +type TopLevelMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + extensionFields protoimpl.ExtensionFields + + F *float32 `protobuf:"fixed32,1,opt,name=f" json:"f,omitempty"` + // Types that are assignable to O: + // + // *TopLevelMessage_I + O isTopLevelMessage_O `protobuf_oneof:"o"` +} + +func (x *TopLevelMessage) Reset() { + *x = TopLevelMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopLevelMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopLevelMessage) ProtoMessage() {} + +func (x *TopLevelMessage) ProtoReflect() protoreflect.Message { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopLevelMessage.ProtoReflect.Descriptor instead. +func (*TopLevelMessage) Descriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP(), []int{1} +} + +func (x *TopLevelMessage) GetF() float32 { + if x != nil && x.F != nil { + return *x.F + } + return 0 +} + +func (m *TopLevelMessage) GetO() isTopLevelMessage_O { + if m != nil { + return m.O + } + return nil +} + +func (x *TopLevelMessage) GetI() int64 { + if x, ok := x.GetO().(*TopLevelMessage_I); ok { + return x.I + } + return 0 +} + +type isTopLevelMessage_O interface { + isTopLevelMessage_O() +} + +type TopLevelMessage_I struct { + I int64 `protobuf:"varint,2,opt,name=i,oneof"` +} + +func (*TopLevelMessage_I) isTopLevelMessage_O() {} + +type TopLevelMessage_NestedMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *TopLevelMessage_NestedMessage) Reset() { + *x = TopLevelMessage_NestedMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopLevelMessage_NestedMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopLevelMessage_NestedMessage) ProtoMessage() {} + +func (x *TopLevelMessage_NestedMessage) ProtoReflect() protoreflect.Message { + mi := &file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopLevelMessage_NestedMessage.ProtoReflect.Descriptor instead. +func (*TopLevelMessage_NestedMessage) Descriptor() ([]byte, []int) { + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP(), []int{1, 0} +} + +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 505092806, + Name: "testretention.plain_option", + Tag: "varint,505092806,opt,name=plain_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 505039132, + Name: "testretention.runtime_retention_option", + Tag: "varint,505039132,opt,name=runtime_retention_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 504878676, + Name: "testretention.source_retention_option", + Tag: "varint,504878676,opt,name=source_retention_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: ([]*OptionsMessage)(nil), + Field: 504823570, + Name: "testretention.repeated_options", + Tag: "bytes,504823570,rep,name=repeated_options", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.ExtensionRangeOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504822148, + Name: "testretention.extension_range_option", + Tag: "bytes,504822148,opt,name=extension_range_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504820819, + Name: "testretention.message_option", + Tag: "bytes,504820819,opt,name=message_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504589219, + Name: "testretention.field_option", + Tag: "bytes,504589219,opt,name=field_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.OneofOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504479153, + Name: "testretention.oneof_option", + Tag: "bytes,504479153,opt,name=oneof_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.EnumOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504451567, + Name: "testretention.enum_option", + Tag: "bytes,504451567,opt,name=enum_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504450522, + Name: "testretention.enum_entry_option", + Tag: "bytes,504450522,opt,name=enum_entry_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.ServiceOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504387709, + Name: "testretention.service_option", + Tag: "bytes,504387709,opt,name=service_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*OptionsMessage)(nil), + Field: 504349420, + Name: "testretention.method_option", + Tag: "bytes,504349420,opt,name=method_option", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*Extendee)(nil), + ExtensionType: (*int32)(nil), + Field: 1, + Name: "testretention.i", + Tag: "varint,1,opt,name=i", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, + { + ExtendedType: (*Extendee)(nil), + ExtensionType: (*string)(nil), + Field: 2, + Name: "testretention.TopLevelMessage.s", + Tag: "bytes,2,opt,name=s", + Filename: "cmd/protoc-gen-go/testdata/retention/retention.proto", + }, +} + +// Extension fields to descriptorpb.FileOptions. +var ( + // optional int32 plain_option = 505092806; + E_PlainOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[0] + // optional int32 runtime_retention_option = 505039132; + E_RuntimeRetentionOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[1] + // optional int32 source_retention_option = 504878676; + E_SourceRetentionOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[2] + // repeated testretention.OptionsMessage repeated_options = 504823570; + E_RepeatedOptions = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[3] +) + +// Extension fields to descriptorpb.ExtensionRangeOptions. +var ( + // optional testretention.OptionsMessage extension_range_option = 504822148; + E_ExtensionRangeOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[4] +) + +// Extension fields to descriptorpb.MessageOptions. +var ( + // optional testretention.OptionsMessage message_option = 504820819; + E_MessageOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[5] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // optional testretention.OptionsMessage field_option = 504589219; + E_FieldOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[6] +) + +// Extension fields to descriptorpb.OneofOptions. +var ( + // optional testretention.OptionsMessage oneof_option = 504479153; + E_OneofOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[7] +) + +// Extension fields to descriptorpb.EnumOptions. +var ( + // optional testretention.OptionsMessage enum_option = 504451567; + E_EnumOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[8] +) + +// Extension fields to descriptorpb.EnumValueOptions. +var ( + // optional testretention.OptionsMessage enum_entry_option = 504450522; + E_EnumEntryOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[9] +) + +// Extension fields to descriptorpb.ServiceOptions. +var ( + // optional testretention.OptionsMessage service_option = 504387709; + E_ServiceOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[10] +) + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional testretention.OptionsMessage method_option = 504349420; + E_MethodOption = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[11] +) + +// Extension fields to Extendee. +var ( + // optional int32 i = 1; + E_I = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[12] + // optional string s = 2; + E_TopLevelMessage_S = &file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes[13] +) + +var File_cmd_protoc_gen_go_testdata_retention_retention_proto protoreflect.FileDescriptor + +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDesc = []byte{ + 0x0a, 0x34, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, + 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, + 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x3a, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, + 0x61, 0x2f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x16, 0x0a, 0x08, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x2a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xe8, 0x01, 0x0a, 0x0f, + 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x18, 0x0a, 0x01, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x42, 0x0a, 0x9a, 0xba, 0xed, 0x84, + 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x01, 0x66, 0x12, 0x0e, 0x0a, 0x01, 0x69, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x01, 0x69, 0x1a, 0x1b, 0x0a, 0x0d, 0x4e, 0x65, 0x73, + 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x0a, 0x9a, 0xc5, 0xde, 0x85, + 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x2c, 0x0a, 0x0a, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x0a, 0xfa, 0x9e, 0xaa, 0x84, 0x0f, 0x04, + 0x08, 0x01, 0x10, 0x02, 0x2a, 0x10, 0x08, 0x0a, 0x10, 0x65, 0x1a, 0x0a, 0xa2, 0x98, 0xdf, 0x85, + 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x32, 0x31, 0x0a, 0x01, 0x73, 0x12, 0x17, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0x9a, 0xba, 0xed, 0x84, + 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x01, 0x73, 0x3a, 0x0a, 0x9a, 0xc5, 0xde, 0x85, 0x0f, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x01, 0x6f, 0x12, 0x0a, 0x8a, 0xdb, 0xb7, 0x84, + 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a, 0x3d, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x21, 0x0a, 0x11, 0x54, 0x4f, 0x50, 0x5f, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x0a, 0xd2, + 0xdd, 0xa9, 0x84, 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x0a, 0xfa, 0x9e, 0xaa, 0x84, 0x0f, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x32, 0x6c, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x55, 0x0a, 0x07, 0x44, 0x6f, 0x53, 0x74, 0x75, 0x66, 0x66, 0x12, 0x1e, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x6f, 0x70, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1e, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x6f, 0x70, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0a, 0xe2, 0xae, 0xf8, + 0x83, 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x0a, 0xea, 0x87, 0x8b, 0x84, 0x0f, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x3a, 0x43, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0xc6, 0xb5, 0xec, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x6c, 0x61, + 0x69, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x5f, 0x0a, 0x18, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x9c, 0x92, 0xe9, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0x88, 0x01, + 0x01, 0x52, 0x16, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x5d, 0x0a, 0x17, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0xd4, 0xac, 0xdf, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0x88, 0x01, + 0x02, 0x52, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6a, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x92, 0xfe, 0xdb, 0xf0, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x7f, 0x0a, 0x16, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x84, 0xf3, 0xdb, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x14, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x69, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd3, 0xe8, 0xdb, 0xf0, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x63, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xa3, 0xd7, 0xcd, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x63, 0x0a, 0x0c, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb1, 0xfb, 0xc6, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x6f, + 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x60, 0x0a, 0x0b, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xef, 0xa3, 0xc5, 0xf0, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x70, 0x0a, 0x11, + 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xda, 0x9b, 0xc5, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x65, + 0x6e, 0x75, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x69, + 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0xfd, 0xb0, 0xc1, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x66, 0x0a, 0x0d, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xec, 0x85, 0xbf, 0xf0, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x31, 0x0a, 0x01, 0x69, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0a, 0x9a, 0xba, 0xed, 0x84, 0x0f, 0x04, 0x08, 0x01, 0x10, + 0x02, 0x52, 0x01, 0x69, 0x42, 0x6d, 0x92, 0xf1, 0xdf, 0x85, 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, + 0x82, 0x90, 0xf7, 0x85, 0x0f, 0x04, 0x08, 0x01, 0x10, 0x02, 0xe0, 0x91, 0xc9, 0x86, 0x0f, 0x02, + 0xb0, 0xac, 0xe3, 0x86, 0x0f, 0x01, 0x80, 0x9b, 0xb2, 0xa0, 0x0f, 0x01, 0xd0, 0xae, 0xfc, 0xa2, + 0x0f, 0x02, 0x5a, 0x3f, 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, 0x63, + 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, +} + +var ( + file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescOnce sync.Once + file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescData = file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDesc +) + +func file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescGZIP() []byte { + file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescOnce.Do(func() { + file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescData = protoimpl.X.CompressGZIP(file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescData) + }) + return file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDescData +} + +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_goTypes = []interface{}{ + (TopLevelEnum)(0), // 0: testretention.TopLevelEnum + (TopLevelMessage_NestedEnum)(0), // 1: testretention.TopLevelMessage.NestedEnum + (*Extendee)(nil), // 2: testretention.Extendee + (*TopLevelMessage)(nil), // 3: testretention.TopLevelMessage + (*TopLevelMessage_NestedMessage)(nil), // 4: testretention.TopLevelMessage.NestedMessage + (*descriptorpb.FileOptions)(nil), // 5: google.protobuf.FileOptions + (*descriptorpb.ExtensionRangeOptions)(nil), // 6: google.protobuf.ExtensionRangeOptions + (*descriptorpb.MessageOptions)(nil), // 7: google.protobuf.MessageOptions + (*descriptorpb.FieldOptions)(nil), // 8: google.protobuf.FieldOptions + (*descriptorpb.OneofOptions)(nil), // 9: google.protobuf.OneofOptions + (*descriptorpb.EnumOptions)(nil), // 10: google.protobuf.EnumOptions + (*descriptorpb.EnumValueOptions)(nil), // 11: google.protobuf.EnumValueOptions + (*descriptorpb.ServiceOptions)(nil), // 12: google.protobuf.ServiceOptions + (*descriptorpb.MethodOptions)(nil), // 13: google.protobuf.MethodOptions + (*OptionsMessage)(nil), // 14: testretention.OptionsMessage +} +var file_cmd_protoc_gen_go_testdata_retention_retention_proto_depIdxs = []int32{ + 5, // 0: testretention.plain_option:extendee -> google.protobuf.FileOptions + 5, // 1: testretention.runtime_retention_option:extendee -> google.protobuf.FileOptions + 5, // 2: testretention.source_retention_option:extendee -> google.protobuf.FileOptions + 5, // 3: testretention.repeated_options:extendee -> google.protobuf.FileOptions + 6, // 4: testretention.extension_range_option:extendee -> google.protobuf.ExtensionRangeOptions + 7, // 5: testretention.message_option:extendee -> google.protobuf.MessageOptions + 8, // 6: testretention.field_option:extendee -> google.protobuf.FieldOptions + 9, // 7: testretention.oneof_option:extendee -> google.protobuf.OneofOptions + 10, // 8: testretention.enum_option:extendee -> google.protobuf.EnumOptions + 11, // 9: testretention.enum_entry_option:extendee -> google.protobuf.EnumValueOptions + 12, // 10: testretention.service_option:extendee -> google.protobuf.ServiceOptions + 13, // 11: testretention.method_option:extendee -> google.protobuf.MethodOptions + 2, // 12: testretention.i:extendee -> testretention.Extendee + 2, // 13: testretention.TopLevelMessage.s:extendee -> testretention.Extendee + 14, // 14: testretention.repeated_options:type_name -> testretention.OptionsMessage + 14, // 15: testretention.extension_range_option:type_name -> testretention.OptionsMessage + 14, // 16: testretention.message_option:type_name -> testretention.OptionsMessage + 14, // 17: testretention.field_option:type_name -> testretention.OptionsMessage + 14, // 18: testretention.oneof_option:type_name -> testretention.OptionsMessage + 14, // 19: testretention.enum_option:type_name -> testretention.OptionsMessage + 14, // 20: testretention.enum_entry_option:type_name -> testretention.OptionsMessage + 14, // 21: testretention.service_option:type_name -> testretention.OptionsMessage + 14, // 22: testretention.method_option:type_name -> testretention.OptionsMessage + 3, // 23: testretention.Service.DoStuff:input_type -> testretention.TopLevelMessage + 3, // 24: testretention.Service.DoStuff:output_type -> testretention.TopLevelMessage + 24, // [24:25] is the sub-list for method output_type + 23, // [23:24] is the sub-list for method input_type + 14, // [14:23] is the sub-list for extension type_name + 0, // [0:14] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_cmd_protoc_gen_go_testdata_retention_retention_proto_init() } +func file_cmd_protoc_gen_go_testdata_retention_retention_proto_init() { + if File_cmd_protoc_gen_go_testdata_retention_retention_proto != nil { + return + } + file_cmd_protoc_gen_go_testdata_retention_options_message_proto_init() + if !protoimpl.UnsafeEnabled { + file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Extendee); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + case 3: + return &v.extensionFields + default: + return nil + } + } + file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopLevelMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + case 3: + return &v.extensionFields + default: + return nil + } + } + file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopLevelMessage_NestedMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*TopLevelMessage_I)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDesc, + NumEnums: 2, + NumMessages: 3, + NumExtensions: 14, + NumServices: 1, + }, + GoTypes: file_cmd_protoc_gen_go_testdata_retention_retention_proto_goTypes, + DependencyIndexes: file_cmd_protoc_gen_go_testdata_retention_retention_proto_depIdxs, + EnumInfos: file_cmd_protoc_gen_go_testdata_retention_retention_proto_enumTypes, + MessageInfos: file_cmd_protoc_gen_go_testdata_retention_retention_proto_msgTypes, + ExtensionInfos: file_cmd_protoc_gen_go_testdata_retention_retention_proto_extTypes, + }.Build() + File_cmd_protoc_gen_go_testdata_retention_retention_proto = out.File + file_cmd_protoc_gen_go_testdata_retention_retention_proto_rawDesc = nil + file_cmd_protoc_gen_go_testdata_retention_retention_proto_goTypes = nil + file_cmd_protoc_gen_go_testdata_retention_retention_proto_depIdxs = nil +} diff --git a/cmd/protoc-gen-go/testdata/retention/retention.proto b/cmd/protoc-gen-go/testdata/retention/retention.proto new file mode 100644 index 000000000..e409a132c --- /dev/null +++ b/cmd/protoc-gen-go/testdata/retention/retention.proto @@ -0,0 +1,176 @@ +// 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. + +syntax = "proto2"; + +package testretention; + +import "cmd/protoc-gen-go/testdata/retention/options_message.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/retention"; + +option (imported_plain_option) = 1; +option (imported_runtime_retention_option) = 2; +option (imported_source_retention_option) = 3; + +// Retention attributes set directly on custom options +extend google.protobuf.FileOptions { + optional int32 plain_option = 505092806; + optional int32 runtime_retention_option = 505039132 + [retention = RETENTION_RUNTIME]; + optional int32 source_retention_option = 504878676 + [retention = RETENTION_SOURCE]; +} + +option (plain_option) = 1; +option (runtime_retention_option) = 2; +option (source_retention_option) = 3; + +option (file_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 +}; + +// Retention attribute nested inside a repeated message field +extend google.protobuf.FileOptions { + repeated OptionsMessage repeated_options = 504823570; +} + +option (repeated_options) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 +}; + +extend google.protobuf.ExtensionRangeOptions { + optional OptionsMessage extension_range_option = 504822148; +} + +extend google.protobuf.MessageOptions { + optional OptionsMessage message_option = 504820819; +} + +extend google.protobuf.FieldOptions { + optional OptionsMessage field_option = 504589219; +} + +extend google.protobuf.OneofOptions { + optional OptionsMessage oneof_option = 504479153; +} + +extend google.protobuf.EnumOptions { + optional OptionsMessage enum_option = 504451567; +} + +extend google.protobuf.EnumValueOptions { + optional OptionsMessage enum_entry_option = 504450522; +} + +extend google.protobuf.ServiceOptions { + optional OptionsMessage service_option = 504387709; +} + +extend google.protobuf.MethodOptions { + optional OptionsMessage method_option = 504349420; +} + +message Extendee { + extensions 1, 2; +} + +extend Extendee { + optional int32 i = 1 [(field_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }]; +} + +message TopLevelMessage { + option (message_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + + message NestedMessage { + option (message_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + } + + enum NestedEnum { + option (enum_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + + NESTED_UNKNOWN = 0; + } + + optional float f = 1 [(field_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }]; + + oneof o { + option (oneof_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + + int64 i = 2; + } + + extensions 10 to 100 [(extension_range_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }]; + + extend Extendee { + optional string s = 2 [(field_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }]; + } +} + +enum TopLevelEnum { + option (enum_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + + TOP_LEVEL_UNKNOWN = 0 [(enum_entry_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }]; +} + +service Service { + option (service_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + + rpc DoStuff(TopLevelMessage) returns (TopLevelMessage) { + option (method_option) = { + plain_field: 1 + runtime_retention_field: 2 + source_retention_field: 3 + }; + } +} \ No newline at end of file diff --git a/compiler/protogen/protogen.go b/compiler/protogen/protogen.go index 678bf010f..2d2171e55 100644 --- a/compiler/protogen/protogen.go +++ b/compiler/protogen/protogen.go @@ -36,6 +36,7 @@ import ( "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/pluginpb" ) @@ -209,6 +210,7 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) { } } } + // When the module= option is provided, we strip the module name // prefix from generated files. This only makes sense if generated // filenames are based on the import path. @@ -298,6 +300,8 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) { } } + // The extracted types from the full import set + typeRegistry := newExtensionRegistry() for _, fdesc := range gen.Request.ProtoFile { filename := fdesc.GetName() if gen.FilesByPath[filename] != nil { @@ -309,6 +313,9 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) { } gen.Files = append(gen.Files, f) gen.FilesByPath[filename] = f + if err = typeRegistry.registerAllExtensionsFromFile(f.Desc); err != nil { + return nil, err + } } for _, filename := range gen.Request.FileToGenerate { f, ok := gen.FilesByPath[filename] @@ -317,6 +324,20 @@ func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) { } f.Generate = true } + + // Create fully-linked descriptors if new extensions were found + if typeRegistry.hasNovelExtensions() { + for _, f := range gen.Files { + b, err := proto.Marshal(f.Proto.ProtoReflect().Interface()) + if err != nil { + return nil, err + } + err = proto.UnmarshalOptions{Resolver: typeRegistry}.Unmarshal(b, f.Proto) + if err != nil { + return nil, err + } + } + } return gen, nil } @@ -1259,3 +1280,78 @@ func (c Comments) String() string { } return string(b) } + +// extensionRegistry allows registration of new extensions defined in the .proto +// file for which we are generating bindings. +// +// Lookups consult the local type registry first and fall back to the base type +// registry which defaults to protoregistry.GlobalTypes +type extensionRegistry struct { + base *protoregistry.Types + local *protoregistry.Types +} + +func newExtensionRegistry() *extensionRegistry { + return &extensionRegistry{ + base: protoregistry.GlobalTypes, + local: &protoregistry.Types{}, + } +} + +// FindExtensionByName implements proto.UnmarshalOptions.FindExtensionByName +func (e *extensionRegistry) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { + if xt, err := e.local.FindExtensionByName(field); err == nil { + return xt, nil + } + + return e.base.FindExtensionByName(field) +} + +// FindExtensionByNumber implements proto.UnmarshalOptions.FindExtensionByNumber +func (e *extensionRegistry) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + if xt, err := e.local.FindExtensionByNumber(message, field); err == nil { + return xt, nil + } + + return e.base.FindExtensionByNumber(message, field) +} + +func (e *extensionRegistry) hasNovelExtensions() bool { + return e.local.NumExtensions() > 0 +} + +func (e *extensionRegistry) registerAllExtensionsFromFile(f protoreflect.FileDescriptor) error { + if err := e.registerAllExtensions(f.Extensions()); err != nil { + return err + } + return nil +} + +func (e *extensionRegistry) registerAllExtensionsFromMessage(ms protoreflect.MessageDescriptors) error { + for i := 0; i < ms.Len(); i++ { + m := ms.Get(i) + if err := e.registerAllExtensions(m.Extensions()); err != nil { + return err + } + } + return nil +} + +func (e *extensionRegistry) registerAllExtensions(exts protoreflect.ExtensionDescriptors) error { + for i := 0; i < exts.Len(); i++ { + if err := e.registerExtension(exts.Get(i)); err != nil { + return err + } + } + return nil +} + +// registerExtension adds the given extension to the type registry if an +// extension with that full name does not exist yet. +func (e *extensionRegistry) registerExtension(xd protoreflect.ExtensionDescriptor) error { + if _, err := e.FindExtensionByName(xd.FullName()); err != protoregistry.NotFound { + // Either the extension already exists or there was an error, either way we're done. + return err + } + return e.local.RegisterExtension(dynamicpb.NewExtensionType(xd)) +}