Skip to content

Commit

Permalink
Use dynamicpb
Browse files Browse the repository at this point in the history
  • Loading branch information
rerost committed Sep 1, 2024
1 parent 0eeeaae commit 0106224
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 37 deletions.
45 changes: 42 additions & 3 deletions domain/grpcreflectiface/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import (
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection/grpc_reflection_v1"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/dynamicpb"
)

type Client interface {
ListServices() ([]string, error)
ResolveService(serviceName string) (*desc.ServiceDescriptor, error)
ResolveMessage(messageName string) (*desc.MessageDescriptor, error)
ResolveMessage(messageName string) (proto.Message, error)
}

type Stream = grpc.BidiStreamingClient[grpc_reflection_v1.ServerReflectionRequest, grpc_reflection_v1.ServerReflectionResponse]
Expand Down Expand Up @@ -54,8 +60,41 @@ func (c *clientImpl) ResolveService(serviceName string) (*desc.ServiceDescriptor
return c.rawGrpcReflectClient.ResolveService(serviceName)
}

func (c *clientImpl) ResolveMessage(messageName string) (*desc.MessageDescriptor, error) {
return c.rawGrpcReflectClient.ResolveMessage(messageName)
func (c *clientImpl) ResolveMessage(messageName string) (proto.Message, error) {
req := grpc_reflection_v1.ServerReflectionRequest{
MessageRequest: &grpc_reflection_v1.ServerReflectionRequest_FileContainingSymbol{
FileContainingSymbol: messageName,
},
}

resp, err := c.call(&req)
if err != nil {
return nil, errors.WithStack(err)
}

var dynamicMessage proto.Message
for _, fdProtoBytes := range resp.GetFileDescriptorResponse().FileDescriptorProto {
var fdProto descriptorpb.FileDescriptorProto

if err := proto.Unmarshal(fdProtoBytes, &fdProto); err != nil {
return nil, errors.WithStack(err)
}

file, err := protodesc.NewFile(&fdProto, protoregistry.GlobalFiles)
if err != nil {
return nil, errors.WithStack(err)
}

msgDescriptor := file.Messages().ByName(protoreflect.FullName(messageName).Name())
if msgDescriptor == nil {
continue
}

// dynamicpbを使用してメッセージを動的に生成
dynamicMessage = dynamicpb.NewMessage(msgDescriptor)
}

return dynamicMessage, nil
}

func (c *clientImpl) call(request *grpc_reflection_v1.ServerReflectionRequest) (*grpc_reflection_v1.ServerReflectionResponse, error) {
Expand Down
45 changes: 12 additions & 33 deletions domain/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package message
import (
"context"

//nolint:staticcheck
"github.com/golang/protobuf/jsonpb"
"github.com/jhump/protoreflect/dynamic"
"github.com/pkg/errors"
"github.com/rerost/giro/domain/grpcreflectiface"
"github.com/rerost/giro/domain/messagename"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)

type JSON []byte
Expand All @@ -21,21 +19,21 @@ type MessageService interface {
ToJSON(ctx context.Context, messageName messagename.MessageName, binary Binary) (JSON, error)
ToBinary(ctx context.Context, messageName messagename.MessageName, json JSON) (Binary, error)
// NOTE: For internal.
ToDynamicMessage(ctx context.Context, messageName messagename.MessageName, json JSON) (protoiface.MessageV1, error)
ToDynamicMessage(ctx context.Context, messageName messagename.MessageName, json JSON) (proto.Message, error)
}

type messageServiceImpl struct {
grpcreflectClient grpcreflectiface.Client
messageNameResolver messagename.MessageNameResolver
jsonMarshaler *jsonpb.Marshaler
jsonMarshaler protojson.MarshalOptions
}

func NewMessageService(client grpcreflectiface.Client, messageNameResolver messagename.MessageNameResolver) MessageService {
return &messageServiceImpl{
grpcreflectClient: client,
messageNameResolver: messageNameResolver,
jsonMarshaler: &jsonpb.Marshaler{
EmitDefaults: true,
jsonMarshaler: protojson.MarshalOptions{
EmitDefaultValues: true,
},
}
}
Expand All @@ -46,9 +44,7 @@ func (ms messageServiceImpl) EmptyJSON(ctx context.Context, messageName messagen
return nil, errors.WithStack(err)
}

dMessage := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md)

json, err := dMessage.MarshalJSONPB(ms.jsonMarshaler)
json, err := ms.jsonMarshaler.Marshal(md)
if err != nil {
return nil, errors.WithStack(err)
}
Expand Down Expand Up @@ -76,14 +72,7 @@ func (ms messageServiceImpl) ToJSON(ctx context.Context, messageName messagename
return nil, errors.WithStack(err)
}

dMessage := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md)

err = dMessage.Unmarshal(binary)
if err != nil {
return nil, errors.WithStack(err)
}

json, err := dMessage.MarshalJSONPB(ms.jsonMarshaler)
json, err := ms.jsonMarshaler.Marshal(md)
if err != nil {
return nil, errors.WithStack(err)
}
Expand All @@ -97,33 +86,23 @@ func (ms messageServiceImpl) ToBinary(ctx context.Context, messageName messagena
return nil, errors.WithStack(err)
}

dMessage := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md)

err = dMessage.UnmarshalJSON(json)
if err != nil {
return nil, errors.WithStack(err)
}

bin, err := dMessage.Marshal()
bin, err := proto.Marshal(md)
if err != nil {
return nil, errors.WithStack(err)
}

return bin, nil
}

func (ms messageServiceImpl) ToDynamicMessage(ctx context.Context, messageName messagename.MessageName, json JSON) (protoiface.MessageV1, error) {
func (ms messageServiceImpl) ToDynamicMessage(ctx context.Context, messageName messagename.MessageName, json JSON) (proto.Message, error) {
md, err := ms.grpcreflectClient.ResolveMessage(string(messageName))
if err != nil {
return nil, errors.WithStack(err)
}

dMessage := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md)

err = dMessage.UnmarshalJSON(json)
if err != nil {
if err := protojson.Unmarshal(json, md); err != nil {
return nil, errors.WithStack(err)
}

return dMessage, nil
return md, nil
}
2 changes: 1 addition & 1 deletion domain/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"time"

"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
"github.com/rerost/giro/domain/grpcreflectiface"
"github.com/rerost/giro/domain/host"
Expand All @@ -14,6 +13,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/proto"
)

type ServiceService interface {
Expand Down

0 comments on commit 0106224

Please sign in to comment.