mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 13:31:54 +00:00
grpc: log non-utf8 string fields in messages (#52208)
This commit is contained in:
parent
a8aa7d98b8
commit
464c58883b
1
internal/gitserver/v1/BUILD.bazel
generated
1
internal/gitserver/v1/BUILD.bazel
generated
@ -1,3 +1,4 @@
|
||||
load("//dev:go_defs.bzl", "go_test")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
|
||||
load("@rules_buf//buf:defs.bzl", "buf_lint_test")
|
||||
|
||||
8
internal/grpc/internalerrs/BUILD.bazel
generated
8
internal/grpc/internalerrs/BUILD.bazel
generated
@ -12,12 +12,16 @@ go_library(
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//internal/env",
|
||||
"//lib/errors",
|
||||
"@com_github_prometheus_client_golang//prometheus",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto",
|
||||
"@com_github_sourcegraph_log//:log",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//codes",
|
||||
"@org_golang_google_grpc//status",
|
||||
"@org_golang_google_protobuf//proto",
|
||||
"@org_golang_google_protobuf//reflect/protopath",
|
||||
"@org_golang_google_protobuf//reflect/protorange",
|
||||
],
|
||||
)
|
||||
|
||||
@ -26,9 +30,13 @@ go_test(
|
||||
srcs = ["common_test.go"],
|
||||
embed = [":internalerrs"],
|
||||
deps = [
|
||||
"//internal/grpc/testprotos/news/v1:news",
|
||||
"@com_github_google_go_cmp//cmp",
|
||||
"@com_github_google_go_cmp//cmp/cmpopts",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//codes",
|
||||
"@org_golang_google_grpc//status",
|
||||
"@org_golang_google_protobuf//proto",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb",
|
||||
],
|
||||
)
|
||||
|
||||
@ -2,6 +2,12 @@ package internalerrs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protopath"
|
||||
"google.golang.org/protobuf/reflect/protorange"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@ -12,20 +18,20 @@ import (
|
||||
type callBackClientStream struct {
|
||||
grpc.ClientStream
|
||||
|
||||
postMessageSend func(error)
|
||||
postMessageReceive func(error)
|
||||
postMessageSend func(message any, err error)
|
||||
postMessageReceive func(message any, err error)
|
||||
}
|
||||
|
||||
func (c *callBackClientStream) SendMsg(m interface{}) error {
|
||||
func (c *callBackClientStream) SendMsg(m any) error {
|
||||
err := c.ClientStream.SendMsg(m)
|
||||
c.postMessageSend(err)
|
||||
c.postMessageSend(m, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *callBackClientStream) RecvMsg(m interface{}) error {
|
||||
func (c *callBackClientStream) RecvMsg(m any) error {
|
||||
err := c.ClientStream.RecvMsg(m)
|
||||
c.postMessageReceive(err)
|
||||
c.postMessageReceive(m, err)
|
||||
|
||||
return err
|
||||
}
|
||||
@ -87,3 +93,31 @@ func splitMethodName(fullMethod string) (string, string) {
|
||||
}
|
||||
return "unknown", "unknown"
|
||||
}
|
||||
|
||||
// findNonUTF8StringFields returns a list of field names that contain invalid UTF-8 strings
|
||||
// in the given proto message.
|
||||
//
|
||||
// Example: ["author", "attachments[1].key_value_attachment.data["key2"]`]
|
||||
func findNonUTF8StringFields(m proto.Message) ([]string, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var fields []string
|
||||
err := protorange.Range(m.ProtoReflect(), func(p protopath.Values) error {
|
||||
last := p.Index(-1)
|
||||
s, ok := last.Value.Interface().(string)
|
||||
if ok && !utf8.ValidString(s) {
|
||||
fieldName := p.Path[1:].String()
|
||||
fields = append(fields, strings.TrimPrefix(fieldName, "."))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "iterating over proto message")
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
@ -2,9 +2,15 @@ package internalerrs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
newspb "github.com/sourcegraph/sourcegraph/internal/grpc/testprotos/news/v1"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@ -12,7 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func TestCallBackClientStream(t *testing.T) {
|
||||
t.Run("SendMsg calls postMessageSend with error", func(t *testing.T) {
|
||||
t.Run("SendMsg calls postMessageSend with message and error", func(t *testing.T) {
|
||||
sentinelMessage := struct{}{}
|
||||
sentinelErr := errors.New("send error")
|
||||
|
||||
var called bool
|
||||
@ -20,16 +27,19 @@ func TestCallBackClientStream(t *testing.T) {
|
||||
ClientStream: &mockClientStream{
|
||||
sendErr: sentinelErr,
|
||||
},
|
||||
postMessageSend: func(err error) {
|
||||
postMessageSend: func(message any, err error) {
|
||||
called = true
|
||||
|
||||
if diff := cmp.Diff(message, sentinelMessage); diff != "" {
|
||||
t.Errorf("postMessageSend called with unexpected message (-want +got):\n%s", diff)
|
||||
}
|
||||
if !errors.Is(err, sentinelErr) {
|
||||
t.Errorf("got %v, want %v", err, sentinelErr)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
sendErr := stream.SendMsg(nil)
|
||||
sendErr := stream.SendMsg(sentinelMessage)
|
||||
if !called {
|
||||
t.Error("postMessageSend not called")
|
||||
}
|
||||
@ -39,7 +49,8 @@ func TestCallBackClientStream(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("RecvMsg calls postMessageReceive with error", func(t *testing.T) {
|
||||
t.Run("RecvMsg calls postMessageReceive with message and error", func(t *testing.T) {
|
||||
sentinelMessage := struct{}{}
|
||||
sentinelErr := errors.New("receive error")
|
||||
|
||||
var called bool
|
||||
@ -47,16 +58,19 @@ func TestCallBackClientStream(t *testing.T) {
|
||||
ClientStream: &mockClientStream{
|
||||
recvErr: sentinelErr,
|
||||
},
|
||||
postMessageReceive: func(err error) {
|
||||
postMessageReceive: func(message any, err error) {
|
||||
called = true
|
||||
|
||||
if diff := cmp.Diff(message, sentinelMessage); diff != "" {
|
||||
t.Errorf("postMessageReceive called with unexpected message (-want +got):\n%s", diff)
|
||||
}
|
||||
if !errors.Is(err, sentinelErr) {
|
||||
t.Errorf("got %v, want %v", err, sentinelErr)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
receiveErr := stream.RecvMsg(nil)
|
||||
receiveErr := stream.RecvMsg(sentinelMessage)
|
||||
if !called {
|
||||
t.Error("postMessageReceive not called")
|
||||
}
|
||||
@ -74,11 +88,11 @@ type mockClientStream struct {
|
||||
recvErr error
|
||||
}
|
||||
|
||||
func (s *mockClientStream) SendMsg(m interface{}) error {
|
||||
func (s *mockClientStream) SendMsg(any) error {
|
||||
return s.sendErr
|
||||
}
|
||||
|
||||
func (s *mockClientStream) RecvMsg(m interface{}) error {
|
||||
func (s *mockClientStream) RecvMsg(any) error {
|
||||
return s.recvErr
|
||||
}
|
||||
|
||||
@ -221,3 +235,70 @@ func TestSplitMethodName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindNonUTF8StringFields(t *testing.T) {
|
||||
// Create instances of the BinaryAttachment and KeyValueAttachment messages
|
||||
invalidBinaryAttachment := &newspb.BinaryAttachment{
|
||||
Name: "inval\x80id_binary",
|
||||
Data: []byte("sample data"),
|
||||
}
|
||||
|
||||
invalidKeyValueAttachment := &newspb.KeyValueAttachment{
|
||||
Name: "inval\x80id_key_value",
|
||||
Data: map[string]string{
|
||||
"key1": "value1",
|
||||
"key2": "inval\x80id_value",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a sample Article message with invalid UTF-8 strings
|
||||
article := &newspb.Article{
|
||||
Author: "inval\x80id_author",
|
||||
Date: ×tamppb.Timestamp{Seconds: 1234567890},
|
||||
Title: "valid_title",
|
||||
Content: "valid_content",
|
||||
Status: newspb.Article_STATUS_PUBLISHED,
|
||||
Attachments: []*newspb.Attachment{
|
||||
{Contents: &newspb.Attachment_BinaryAttachment{BinaryAttachment: invalidBinaryAttachment}},
|
||||
{Contents: &newspb.Attachment_KeyValueAttachment{KeyValueAttachment: invalidKeyValueAttachment}},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
message proto.Message
|
||||
expectedPaths []string
|
||||
}{
|
||||
{
|
||||
name: "Article with invalid UTF-8 strings",
|
||||
message: article,
|
||||
expectedPaths: []string{
|
||||
"author",
|
||||
"attachments[0].binary_attachment.name",
|
||||
"attachments[1].key_value_attachment.name",
|
||||
`attachments[1].key_value_attachment.data["key2"]`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil message",
|
||||
message: nil,
|
||||
expectedPaths: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
invalidFields, err := findNonUTF8StringFields(tt.message)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
sort.Strings(invalidFields)
|
||||
sort.Strings(tt.expectedPaths)
|
||||
|
||||
if diff := cmp.Diff(tt.expectedPaths, invalidFields, cmpopts.EquateEmpty()); diff != "" {
|
||||
t.Fatalf("unexpected invalid fields (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,14 @@ package internalerrs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/sourcegraph/log"
|
||||
"google.golang.org/grpc"
|
||||
@ -18,6 +24,9 @@ var (
|
||||
|
||||
envLoggingEnabled = env.MustGetBool("SRC_GRPC_INTERNAL_ERROR_LOGGING_ENABLED", true, "Enables logging of gRPC internal errors")
|
||||
envLogStackTracesEnabled = env.MustGetBool("SRC_GRPC_INTERNAL_ERROR_LOGGING_LOG_STACK_TRACES", false, "Enables including stack traces in logs of gRPC internal errors")
|
||||
|
||||
envLogNonUTF8ProtobufMessages = env.MustGetBool("SRC_GRPC_INTERNAL_ERROR_LOGGING_LOG_NON_UTF8_PROTOBUF_MESSAGES_ENABLED", false, "Enables logging of non-UTF-8 protobuf messages")
|
||||
envLogNonUTF8ProtobufMessagesMaxSize = env.MustGetInt("SRC_GRPC_INTERNAL_ERROR_LOGGING_LOG_NON_UTF8_PROTOBUF_MESSAGES_MAX_SIZE_BYTES", 1024, "Maximum size of non-UTF-8 protobuf messages to log before truncation, in bytes. Negative values disable truncation.")
|
||||
)
|
||||
|
||||
// LoggingUnaryClientInterceptor returns a grpc.UnaryClientInterceptor that logs
|
||||
@ -35,7 +44,7 @@ func LoggingUnaryClientInterceptor(l log.Logger) grpc.UnaryClientInterceptor {
|
||||
err := invoker(ctx, fullMethod, req, reply, cc, opts...)
|
||||
if err != nil {
|
||||
serviceName, methodName := splitMethodName(fullMethod)
|
||||
doLog(logger, serviceName, methodName, err)
|
||||
doLog(logger, serviceName, methodName, req, err)
|
||||
}
|
||||
|
||||
return err
|
||||
@ -59,7 +68,11 @@ func LoggingStreamClientInterceptor(l log.Logger) grpc.StreamClientInterceptor {
|
||||
|
||||
stream, err := streamer(ctx, desc, cc, fullMethod, opts...)
|
||||
if err != nil {
|
||||
doLog(logger, serviceName, methodName, err)
|
||||
// Note: This is a bit hacky, we provide a nil message here since the message isn't available
|
||||
// until after the stream is created.
|
||||
//
|
||||
// This is fine since the error is already available, and the non-utf8 string check is robust against nil messages.
|
||||
doLog(logger, serviceName, methodName, nil, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -71,20 +84,22 @@ func LoggingStreamClientInterceptor(l log.Logger) grpc.StreamClientInterceptor {
|
||||
func newLoggingClientStream(s grpc.ClientStream, logger log.Logger, serviceName, methodName string) *callBackClientStream {
|
||||
return &callBackClientStream{
|
||||
ClientStream: s,
|
||||
postMessageSend: func(err error) {
|
||||
|
||||
postMessageSend: func(m any, err error) {
|
||||
if err != nil {
|
||||
doLog(logger, serviceName, methodName, err)
|
||||
doLog(logger, serviceName, methodName, m, err)
|
||||
}
|
||||
},
|
||||
postMessageReceive: func(err error) {
|
||||
|
||||
postMessageReceive: func(m any, err error) {
|
||||
if err != nil && err != io.EOF { // EOF is expected at the end of a stream, so no need to log an error
|
||||
doLog(logger, serviceName, methodName, err)
|
||||
doLog(logger, serviceName, methodName, m, err)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func doLog(logger log.Logger, serviceName, methodName string, err error) {
|
||||
func doLog(logger log.Logger, serviceName, methodName string, payload any, err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
@ -98,15 +113,77 @@ func doLog(logger log.Logger, serviceName, methodName string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
fields := []log.Field{
|
||||
allFields := []log.Field{
|
||||
log.String("grpcService", serviceName),
|
||||
log.String("grpcMethod", methodName),
|
||||
log.String("grpcCode", s.Code().String()),
|
||||
}
|
||||
|
||||
if envLogStackTracesEnabled {
|
||||
fields = append(fields, log.String("errWithStack", fmt.Sprintf("%+v", err)))
|
||||
allFields = append(allFields, log.String("errWithStack", fmt.Sprintf("%+v", err)))
|
||||
}
|
||||
|
||||
logger.Error(s.Message(), fields...)
|
||||
if isNonUTF8StringError(s) {
|
||||
if m, ok := payload.(proto.Message); ok {
|
||||
allFields = append(
|
||||
allFields,
|
||||
additionalNonUTF8StringDebugFields(m, envLogNonUTF8ProtobufMessages, envLogNonUTF8ProtobufMessagesMaxSize)...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Error(s.Message(), allFields...)
|
||||
}
|
||||
|
||||
// additionalNonUTF8StringDebugFields returns additional log fields that should be included when logging a non-UTF8 string error.
|
||||
//
|
||||
// By default, this includes the names of all fields that contain non-UTF8 strings.
|
||||
// If shouldLogMessageJSON is true, then the JSON representation of the message is also included.
|
||||
// The maxMessageSizeLogBytes parameter controls the maximum size of the message that will be logged, after which it will be truncated. Negative values disable truncation.
|
||||
func additionalNonUTF8StringDebugFields(message proto.Message, shouldLogMessageJSON bool, maxMessageLogSizeBytes int) []log.Field {
|
||||
var allFields []log.Field
|
||||
|
||||
// Add the names of all protobuf fields that contain non-UTF-8 strings to the log.
|
||||
|
||||
badFields, err := findNonUTF8StringFields(message)
|
||||
if err != nil {
|
||||
allFields = append(allFields, log.Error(errors.Wrapf(err, "failed to find non-UTF8 string allFields")))
|
||||
return allFields
|
||||
}
|
||||
|
||||
allFields = append(allFields, log.Strings("nonUTF8StringFields", badFields))
|
||||
|
||||
// Add the JSON representation of the message to the log.
|
||||
|
||||
if !shouldLogMessageJSON {
|
||||
return allFields
|
||||
}
|
||||
|
||||
// Note: we can't use the protojson library here since it doesn't support messages with non-UTF8 strings.
|
||||
jsonBytes, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
allFields = append(allFields, log.Error(errors.Wrapf(err, "failed to marshal protobuf message to bytes")))
|
||||
return allFields
|
||||
}
|
||||
|
||||
if maxMessageLogSizeBytes < 0 { // If truncation is disabled, set the max size to the full message size.
|
||||
maxMessageLogSizeBytes = len(jsonBytes)
|
||||
}
|
||||
|
||||
bytesToTruncate := len(jsonBytes) - maxMessageLogSizeBytes
|
||||
if bytesToTruncate > 0 {
|
||||
jsonBytes = jsonBytes[:maxMessageLogSizeBytes]
|
||||
jsonBytes = append(jsonBytes, []byte(fmt.Sprintf("...(truncated %d bytes)", bytesToTruncate))...)
|
||||
}
|
||||
|
||||
allFields = append(allFields, log.String("messageJSON", string(jsonBytes)))
|
||||
return allFields
|
||||
}
|
||||
|
||||
func isNonUTF8StringError(s *status.Status) bool {
|
||||
if s.Code() != codes.Internal {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.Contains(s.Message(), "string field contains invalid UTF-8")
|
||||
}
|
||||
|
||||
@ -66,14 +66,14 @@ func newPrometheusServerStream(s grpc.ClientStream, serviceName, methodName stri
|
||||
|
||||
return &callBackClientStream{
|
||||
ClientStream: s,
|
||||
postMessageSend: func(err error) {
|
||||
postMessageSend: func(_ any, err error) {
|
||||
if err != nil {
|
||||
observeOnce.Do(func() {
|
||||
doObservation(serviceName, methodName, err)
|
||||
})
|
||||
}
|
||||
},
|
||||
postMessageReceive: func(err error) {
|
||||
postMessageReceive: func(_ any, err error) {
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
// EOF signals end of stream, not an error. We handle this by setting err to nil, because
|
||||
|
||||
31
internal/grpc/testprotos/news/v1/BUILD.bazel
generated
Normal file
31
internal/grpc/testprotos/news/v1/BUILD.bazel
generated
Normal file
@ -0,0 +1,31 @@
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
|
||||
|
||||
proto_library(
|
||||
name = "news_proto",
|
||||
srcs = ["news.proto"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = ["@com_google_protobuf//:timestamp_proto"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "news_go_proto",
|
||||
importpath = "github.com/sourcegraph/sourcegraph/internal/grpc/testprotos/news",
|
||||
proto = ":news_proto",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "news",
|
||||
embed = [":v1_go_proto"],
|
||||
importpath = "github.com/sourcegraph/sourcegraph/internal/grpc/testprotos/news/v1",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "v1_go_proto",
|
||||
importpath = "github.com/sourcegraph/sourcegraph/internal/grpc/testprotos/news/v1",
|
||||
proto = ":news_proto",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
||||
7
internal/grpc/testprotos/news/v1/buf.gen.yaml
Normal file
7
internal/grpc/testprotos/news/v1/buf.gen.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
# Configuration file for https://buf.build/, which we use for Protobuf code generation.
|
||||
version: v1
|
||||
plugins:
|
||||
- plugin: buf.build/protocolbuffers/go:v1.29.1
|
||||
out: .
|
||||
opt:
|
||||
- paths=source_relative
|
||||
538
internal/grpc/testprotos/news/v1/news.pb.go
generated
Normal file
538
internal/grpc/testprotos/news/v1/news.pb.go
generated
Normal file
@ -0,0 +1,538 @@
|
||||
// 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.
|
||||
//
|
||||
// Note (@Sourcegraph): This file was copied / adapted from
|
||||
// https://github.com/protocolbuffers/protobuf-go/blob/v1.30.0/internal/testprotos/news/news.proto to aid our testing.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc (unknown)
|
||||
// source: news.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Article_Status int32
|
||||
|
||||
const (
|
||||
Article_STATUS_DRAFT_UNSPECIFIED Article_Status = 0
|
||||
Article_STATUS_PUBLISHED Article_Status = 1
|
||||
Article_STATUS_REVOKED Article_Status = 2
|
||||
)
|
||||
|
||||
// Enum value maps for Article_Status.
|
||||
var (
|
||||
Article_Status_name = map[int32]string{
|
||||
0: "STATUS_DRAFT_UNSPECIFIED",
|
||||
1: "STATUS_PUBLISHED",
|
||||
2: "STATUS_REVOKED",
|
||||
}
|
||||
Article_Status_value = map[string]int32{
|
||||
"STATUS_DRAFT_UNSPECIFIED": 0,
|
||||
"STATUS_PUBLISHED": 1,
|
||||
"STATUS_REVOKED": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Article_Status) Enum() *Article_Status {
|
||||
p := new(Article_Status)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Article_Status) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Article_Status) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_news_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Article_Status) Type() protoreflect.EnumType {
|
||||
return &file_news_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Article_Status) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Article_Status.Descriptor instead.
|
||||
func (Article_Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_news_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
type Article struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Author string `protobuf:"bytes,1,opt,name=author,proto3" json:"author,omitempty"`
|
||||
Date *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=date,proto3" json:"date,omitempty"`
|
||||
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
|
||||
Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Status Article_Status `protobuf:"varint,8,opt,name=status,proto3,enum=grpc.testprotos.news.v1.Article_Status" json:"status,omitempty"`
|
||||
Attachments []*Attachment `protobuf:"bytes,7,rep,name=attachments,proto3" json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Article) Reset() {
|
||||
*x = Article{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_news_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Article) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Article) ProtoMessage() {}
|
||||
|
||||
func (x *Article) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_news_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 Article.ProtoReflect.Descriptor instead.
|
||||
func (*Article) Descriptor() ([]byte, []int) {
|
||||
return file_news_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Article) GetAuthor() string {
|
||||
if x != nil {
|
||||
return x.Author
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Article) GetDate() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Date
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Article) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Article) GetContent() string {
|
||||
if x != nil {
|
||||
return x.Content
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Article) GetStatus() Article_Status {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return Article_STATUS_DRAFT_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *Article) GetAttachments() []*Attachment {
|
||||
if x != nil {
|
||||
return x.Attachments
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Attachment struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to Contents:
|
||||
//
|
||||
// *Attachment_BinaryAttachment
|
||||
// *Attachment_KeyValueAttachment
|
||||
Contents isAttachment_Contents `protobuf_oneof:"contents"`
|
||||
}
|
||||
|
||||
func (x *Attachment) Reset() {
|
||||
*x = Attachment{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_news_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Attachment) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Attachment) ProtoMessage() {}
|
||||
|
||||
func (x *Attachment) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_news_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 Attachment.ProtoReflect.Descriptor instead.
|
||||
func (*Attachment) Descriptor() ([]byte, []int) {
|
||||
return file_news_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *Attachment) GetContents() isAttachment_Contents {
|
||||
if m != nil {
|
||||
return m.Contents
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Attachment) GetBinaryAttachment() *BinaryAttachment {
|
||||
if x, ok := x.GetContents().(*Attachment_BinaryAttachment); ok {
|
||||
return x.BinaryAttachment
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Attachment) GetKeyValueAttachment() *KeyValueAttachment {
|
||||
if x, ok := x.GetContents().(*Attachment_KeyValueAttachment); ok {
|
||||
return x.KeyValueAttachment
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isAttachment_Contents interface {
|
||||
isAttachment_Contents()
|
||||
}
|
||||
|
||||
type Attachment_BinaryAttachment struct {
|
||||
BinaryAttachment *BinaryAttachment `protobuf:"bytes,1,opt,name=binary_attachment,json=binaryAttachment,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Attachment_KeyValueAttachment struct {
|
||||
KeyValueAttachment *KeyValueAttachment `protobuf:"bytes,2,opt,name=key_value_attachment,json=keyValueAttachment,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Attachment_BinaryAttachment) isAttachment_Contents() {}
|
||||
|
||||
func (*Attachment_KeyValueAttachment) isAttachment_Contents() {}
|
||||
|
||||
type BinaryAttachment struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BinaryAttachment) Reset() {
|
||||
*x = BinaryAttachment{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_news_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BinaryAttachment) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BinaryAttachment) ProtoMessage() {}
|
||||
|
||||
func (x *BinaryAttachment) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_news_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 BinaryAttachment.ProtoReflect.Descriptor instead.
|
||||
func (*BinaryAttachment) Descriptor() ([]byte, []int) {
|
||||
return file_news_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *BinaryAttachment) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BinaryAttachment) GetData() []byte {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type KeyValueAttachment struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Data map[string]string `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *KeyValueAttachment) Reset() {
|
||||
*x = KeyValueAttachment{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_news_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *KeyValueAttachment) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*KeyValueAttachment) ProtoMessage() {}
|
||||
|
||||
func (x *KeyValueAttachment) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_news_proto_msgTypes[3]
|
||||
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 KeyValueAttachment.ProtoReflect.Descriptor instead.
|
||||
func (*KeyValueAttachment) Descriptor() ([]byte, []int) {
|
||||
return file_news_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *KeyValueAttachment) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *KeyValueAttachment) GetData() map[string]string {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_news_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_news_proto_rawDesc = []byte{
|
||||
0x0a, 0x0a, 0x6e, 0x65, 0x77, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x67, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x6e, 0x65,
|
||||
0x77, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, 0x02, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63,
|
||||
0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61,
|
||||
0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69,
|
||||
0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x6e, 0x65, 0x77,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x61,
|
||||
0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x23, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63,
|
||||
0x68, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x22, 0x50, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x18,
|
||||
0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x52, 0x41, 0x46, 0x54, 0x5f, 0x55, 0x4e, 0x53,
|
||||
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54,
|
||||
0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x01,
|
||||
0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b,
|
||||
0x45, 0x44, 0x10, 0x02, 0x22, 0xd3, 0x01, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x74,
|
||||
0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
|
||||
0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
|
||||
0x2e, 0x6e, 0x65, 0x77, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41,
|
||||
0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x62, 0x69, 0x6e,
|
||||
0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5f, 0x0a,
|
||||
0x14, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x61, 0x63,
|
||||
0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x6e, 0x65,
|
||||
0x77, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x41, 0x74,
|
||||
0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x6b, 0x65, 0x79, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x0a,
|
||||
0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x0a, 0x10, 0x42, 0x69,
|
||||
0x6e, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xac, 0x01, 0x0a, 0x12, 0x4b, 0x65, 0x79, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x49, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x35, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x73, 0x2e, 0x6e, 0x65, 0x77, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09,
|
||||
0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_news_proto_rawDescOnce sync.Once
|
||||
file_news_proto_rawDescData = file_news_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_news_proto_rawDescGZIP() []byte {
|
||||
file_news_proto_rawDescOnce.Do(func() {
|
||||
file_news_proto_rawDescData = protoimpl.X.CompressGZIP(file_news_proto_rawDescData)
|
||||
})
|
||||
return file_news_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_news_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_news_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_news_proto_goTypes = []interface{}{
|
||||
(Article_Status)(0), // 0: grpc.testprotos.news.v1.Article.Status
|
||||
(*Article)(nil), // 1: grpc.testprotos.news.v1.Article
|
||||
(*Attachment)(nil), // 2: grpc.testprotos.news.v1.Attachment
|
||||
(*BinaryAttachment)(nil), // 3: grpc.testprotos.news.v1.BinaryAttachment
|
||||
(*KeyValueAttachment)(nil), // 4: grpc.testprotos.news.v1.KeyValueAttachment
|
||||
nil, // 5: grpc.testprotos.news.v1.KeyValueAttachment.DataEntry
|
||||
(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
|
||||
}
|
||||
var file_news_proto_depIdxs = []int32{
|
||||
6, // 0: grpc.testprotos.news.v1.Article.date:type_name -> google.protobuf.Timestamp
|
||||
0, // 1: grpc.testprotos.news.v1.Article.status:type_name -> grpc.testprotos.news.v1.Article.Status
|
||||
2, // 2: grpc.testprotos.news.v1.Article.attachments:type_name -> grpc.testprotos.news.v1.Attachment
|
||||
3, // 3: grpc.testprotos.news.v1.Attachment.binary_attachment:type_name -> grpc.testprotos.news.v1.BinaryAttachment
|
||||
4, // 4: grpc.testprotos.news.v1.Attachment.key_value_attachment:type_name -> grpc.testprotos.news.v1.KeyValueAttachment
|
||||
5, // 5: grpc.testprotos.news.v1.KeyValueAttachment.data:type_name -> grpc.testprotos.news.v1.KeyValueAttachment.DataEntry
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_news_proto_init() }
|
||||
func file_news_proto_init() {
|
||||
if File_news_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_news_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Article); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_news_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Attachment); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_news_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BinaryAttachment); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_news_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*KeyValueAttachment); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_news_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*Attachment_BinaryAttachment)(nil),
|
||||
(*Attachment_KeyValueAttachment)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_news_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_news_proto_goTypes,
|
||||
DependencyIndexes: file_news_proto_depIdxs,
|
||||
EnumInfos: file_news_proto_enumTypes,
|
||||
MessageInfos: file_news_proto_msgTypes,
|
||||
}.Build()
|
||||
File_news_proto = out.File
|
||||
file_news_proto_rawDesc = nil
|
||||
file_news_proto_goTypes = nil
|
||||
file_news_proto_depIdxs = nil
|
||||
}
|
||||
46
internal/grpc/testprotos/news/v1/news.proto
Normal file
46
internal/grpc/testprotos/news/v1/news.proto
Normal file
@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
//
|
||||
// Note (@Sourcegraph): This file was copied / adapted from
|
||||
// https://github.com/protocolbuffers/protobuf-go/blob/v1.30.0/internal/testprotos/news/news.proto to aid our testing.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.testprotos.news.v1;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/sourcegraph/sourcegraph/internal/grpc/testprotos/news/v1";
|
||||
|
||||
message Article {
|
||||
enum Status {
|
||||
STATUS_DRAFT_UNSPECIFIED = 0;
|
||||
STATUS_PUBLISHED = 1;
|
||||
STATUS_REVOKED = 2;
|
||||
}
|
||||
|
||||
string author = 1;
|
||||
google.protobuf.Timestamp date = 2;
|
||||
string title = 3;
|
||||
string content = 4;
|
||||
Status status = 8;
|
||||
repeated Attachment attachments = 7;
|
||||
}
|
||||
|
||||
message Attachment {
|
||||
oneof contents {
|
||||
BinaryAttachment binary_attachment = 1;
|
||||
KeyValueAttachment key_value_attachment = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message BinaryAttachment {
|
||||
string name = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
||||
message KeyValueAttachment {
|
||||
string name = 1;
|
||||
map<string, string> data = 2;
|
||||
}
|
||||
@ -124,6 +124,10 @@ env:
|
||||
# OTEL_EXPORTER_OTLP_ENDPOINT: http://127.0.0.1:4318
|
||||
# OTEL_EXPORTER_OTLP_PROTOCOL: http/json
|
||||
|
||||
# Enable full protobuf message logging when a non-utf8 string error occurs
|
||||
SRC_GRPC_INTERNAL_ERROR_LOGGING_LOG_NON_UTF8_PROTOBUF_MESSAGES_ENABLED: "true"
|
||||
SRC_GRPC_INTERNAL_ERROR_LOGGING_LOG_NON_UTF8_PROTOBUF_MESSAGES_MAX_SIZE_BYTES: 1024
|
||||
|
||||
commands:
|
||||
server:
|
||||
description: Run an all-in-one sourcegraph/server image
|
||||
|
||||
Loading…
Reference in New Issue
Block a user