diff options
Diffstat (limited to 'vendor/google.golang.org/grpc/encoding')
| -rw-r--r-- | vendor/google.golang.org/grpc/encoding/encoding.go | 5 | ||||
| -rw-r--r-- | vendor/google.golang.org/grpc/encoding/encoding_v2.go | 81 | ||||
| -rw-r--r-- | vendor/google.golang.org/grpc/encoding/proto/proto.go | 44 | 
3 files changed, 118 insertions, 12 deletions
| diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index 5ebf88d71..11d0ae142 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -94,7 +94,7 @@ type Codec interface {  	Name() string  } -var registeredCodecs = make(map[string]Codec) +var registeredCodecs = make(map[string]any)  // RegisterCodec registers the provided Codec for use with all gRPC clients and  // servers. @@ -126,5 +126,6 @@ func RegisterCodec(codec Codec) {  //  // The content-subtype is expected to be lowercase.  func GetCodec(contentSubtype string) Codec { -	return registeredCodecs[contentSubtype] +	c, _ := registeredCodecs[contentSubtype].(Codec) +	return c  } diff --git a/vendor/google.golang.org/grpc/encoding/encoding_v2.go b/vendor/google.golang.org/grpc/encoding/encoding_v2.go new file mode 100644 index 000000000..074c5e234 --- /dev/null +++ b/vendor/google.golang.org/grpc/encoding/encoding_v2.go @@ -0,0 +1,81 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *     http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package encoding + +import ( +	"strings" + +	"google.golang.org/grpc/mem" +) + +// CodecV2 defines the interface gRPC uses to encode and decode messages. Note +// that implementations of this interface must be thread safe; a CodecV2's +// methods can be called from concurrent goroutines. +type CodecV2 interface { +	// Marshal returns the wire format of v. The buffers in the returned +	// [mem.BufferSlice] must have at least one reference each, which will be freed +	// by gRPC when they are no longer needed. +	Marshal(v any) (out mem.BufferSlice, err error) +	// Unmarshal parses the wire format into v. Note that data will be freed as soon +	// as this function returns. If the codec wishes to guarantee access to the data +	// after this function, it must take its own reference that it frees when it is +	// no longer needed. +	Unmarshal(data mem.BufferSlice, v any) error +	// Name returns the name of the Codec implementation. The returned string +	// will be used as part of content type in transmission.  The result must be +	// static; the result cannot change between calls. +	Name() string +} + +// RegisterCodecV2 registers the provided CodecV2 for use with all gRPC clients and +// servers. +// +// The CodecV2 will be stored and looked up by result of its Name() method, which +// should match the content-subtype of the encoding handled by the CodecV2.  This +// is case-insensitive, and is stored and looked up as lowercase.  If the +// result of calling Name() is an empty string, RegisterCodecV2 will panic. See +// Content-Type on +// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for +// more details. +// +// If both a Codec and CodecV2 are registered with the same name, the CodecV2 +// will be used. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe.  If multiple Codecs are +// registered with the same name, the one registered last will take effect. +func RegisterCodecV2(codec CodecV2) { +	if codec == nil { +		panic("cannot register a nil CodecV2") +	} +	if codec.Name() == "" { +		panic("cannot register CodecV2 with empty string result for Name()") +	} +	contentSubtype := strings.ToLower(codec.Name()) +	registeredCodecs[contentSubtype] = codec +} + +// GetCodecV2 gets a registered CodecV2 by content-subtype, or nil if no CodecV2 is +// registered for the content-subtype. +// +// The content-subtype is expected to be lowercase. +func GetCodecV2(contentSubtype string) CodecV2 { +	c, _ := registeredCodecs[contentSubtype].(CodecV2) +	return c +} diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go index 66d5cdf03..ceec319dd 100644 --- a/vendor/google.golang.org/grpc/encoding/proto/proto.go +++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go @@ -1,6 +1,6 @@  /*   * - * Copyright 2018 gRPC authors. + * Copyright 2024 gRPC authors.   *   * Licensed under the Apache License, Version 2.0 (the "License");   * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import (  	"fmt"  	"google.golang.org/grpc/encoding" +	"google.golang.org/grpc/mem"  	"google.golang.org/protobuf/proto"  	"google.golang.org/protobuf/protoadapt"  ) @@ -32,28 +33,51 @@ import (  const Name = "proto"  func init() { -	encoding.RegisterCodec(codec{}) +	encoding.RegisterCodecV2(&codecV2{})  } -// codec is a Codec implementation with protobuf. It is the default codec for gRPC. -type codec struct{} +// codec is a CodecV2 implementation with protobuf. It is the default codec for +// gRPC. +type codecV2 struct{} -func (codec) Marshal(v any) ([]byte, error) { +func (c *codecV2) Marshal(v any) (data mem.BufferSlice, err error) {  	vv := messageV2Of(v)  	if vv == nil { -		return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) +		return nil, fmt.Errorf("proto: failed to marshal, message is %T, want proto.Message", v)  	} -	return proto.Marshal(vv) +	size := proto.Size(vv) +	if mem.IsBelowBufferPoolingThreshold(size) { +		buf, err := proto.Marshal(vv) +		if err != nil { +			return nil, err +		} +		data = append(data, mem.SliceBuffer(buf)) +	} else { +		pool := mem.DefaultBufferPool() +		buf := pool.Get(size) +		if _, err := (proto.MarshalOptions{}).MarshalAppend((*buf)[:0], vv); err != nil { +			pool.Put(buf) +			return nil, err +		} +		data = append(data, mem.NewBuffer(buf, pool)) +	} + +	return data, nil  } -func (codec) Unmarshal(data []byte, v any) error { +func (c *codecV2) Unmarshal(data mem.BufferSlice, v any) (err error) {  	vv := messageV2Of(v)  	if vv == nil {  		return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)  	} -	return proto.Unmarshal(data, vv) +	buf := data.MaterializeToBuffer(mem.DefaultBufferPool()) +	defer buf.Free() +	// TODO: Upgrade proto.Unmarshal to support mem.BufferSlice. Right now, it's not +	//  really possible without a major overhaul of the proto package, but the +	//  vtprotobuf library may be able to support this. +	return proto.Unmarshal(buf.ReadOnlyData(), vv)  }  func messageV2Of(v any) proto.Message { @@ -67,6 +91,6 @@ func messageV2Of(v any) proto.Message {  	return nil  } -func (codec) Name() string { +func (c *codecV2) Name() string {  	return Name  } | 
