From fc4cded474c2f8934972e2207425e8d98bbc2c89 Mon Sep 17 00:00:00 2001 From: Kevin McDonald Date: Mon, 19 Aug 2024 15:26:52 +0200 Subject: [PATCH] Fix SetDataOnMessage on concrete (generated) types --- example/{generate-messages => }/go.mod | 4 +- example/{generate-messages => }/go.sum | 2 - .../main.go | 0 example/set-data-on-message/main.go | 44 ++++++++++ gen_fields.go | 21 ++++- gen_msg_test.go | 84 +++++++++++++++++-- 6 files changed, 143 insertions(+), 12 deletions(-) rename example/{generate-messages => }/go.mod (88%) rename example/{generate-messages => }/go.sum (94%) rename example/{generate-messages => new-message}/main.go (100%) create mode 100644 example/set-data-on-message/main.go diff --git a/example/generate-messages/go.mod b/example/go.mod similarity index 88% rename from example/generate-messages/go.mod rename to example/go.mod index 4d4ad8a..6820f1a 100644 --- a/example/generate-messages/go.mod +++ b/example/go.mod @@ -1,4 +1,4 @@ -module github.com/sudorandom/fauxrpc/examples/generate-messages +module github.com/sudorandom/fauxrpc/examples go 1.22.4 @@ -16,3 +16,5 @@ require ( github.com/brianvoe/gofakeit/v7 v7.0.4 // indirect github.com/bufbuild/protovalidate-go v0.6.3 // indirect ) + +replace github.com/sudorandom/fauxrpc => ../ diff --git a/example/generate-messages/go.sum b/example/go.sum similarity index 94% rename from example/generate-messages/go.sum rename to example/go.sum index 62bba25..58c1765 100644 --- a/example/generate-messages/go.sum +++ b/example/go.sum @@ -22,8 +22,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/sudorandom/fauxrpc v0.0.10 h1:kPdRRub6TmKec+ZCQtc6UkOUuOEduOXb0yX8Ah5gp00= -github.com/sudorandom/fauxrpc v0.0.10/go.mod h1:LdFnyF0FAEoKlvEc8JztPZm2dPDhBN734M62DFKyZEI= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/example/generate-messages/main.go b/example/new-message/main.go similarity index 100% rename from example/generate-messages/main.go rename to example/new-message/main.go diff --git a/example/set-data-on-message/main.go b/example/set-data-on-message/main.go new file mode 100644 index 0000000..b1afcdf --- /dev/null +++ b/example/set-data-on-message/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "log" + + ownerv1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1" + elizav1 "buf.build/gen/go/connectrpc/eliza/protocolbuffers/go/connectrpc/eliza/v1" + runtimeapi "buf.build/gen/go/kubernetes/cri-api/protocolbuffers/go/pkg/apis/runtime/v1" + "github.com/sudorandom/fauxrpc" + "google.golang.org/protobuf/encoding/protojson" +) + +func main() { + { + msg := &elizav1.SayResponse{} + fauxrpc.SetDataOnMessage(msg) + b, err := protojson.MarshalOptions{Indent: " "}.Marshal(msg) + if err != nil { + log.Fatalf("err: %s", err) + } + fmt.Println(string(b)) + } + + { + msg := &ownerv1.Owner{} + fauxrpc.SetDataOnMessage(msg) + b, err := protojson.MarshalOptions{Indent: " "}.Marshal(msg) + if err != nil { + log.Fatalf("err: %s", err) + } + fmt.Println(string(b)) + } + + { + msg := &runtimeapi.ListMetricDescriptorsResponse{} + fauxrpc.SetDataOnMessage(msg) + b, err := protojson.MarshalOptions{Indent: " "}.Marshal(msg) + if err != nil { + log.Fatalf("err: %s", err) + } + fmt.Println(string(b)) + } +} diff --git a/gen_fields.go b/gen_fields.go index 54049df..742d1b2 100644 --- a/gen_fields.go +++ b/gen_fields.go @@ -2,6 +2,7 @@ package fauxrpc import ( "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/dynamicpb" ) @@ -95,13 +96,25 @@ func getFieldValue(fd protoreflect.FieldDescriptor, st state) *protoreflect.Valu } } - nested := dynamicpb.NewMessage(fd.Message()) - setDataOnMessage(nested, st.Inc()) + var nested protoreflect.Message + mt, err := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()) + if err != nil { + nested = dynamicpb.NewMessageType(fd.Message()).New() + } else { + nested = mt.New() + } + setDataOnMessage(nested.Interface(), st.Inc()) v := protoreflect.ValueOf(nested) return &v case protoreflect.GroupKind: - nested := dynamicpb.NewMessage(fd.Message()) - setDataOnMessage(nested, st.Inc()) + var nested protoreflect.Message + mt, err := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()) + if err != nil { + nested = dynamicpb.NewMessageType(fd.Message()).New() + } else { + nested = mt.New() + } + setDataOnMessage(nested.Interface(), st.Inc()) v := protoreflect.ValueOf(nested) return &v } diff --git a/gen_msg_test.go b/gen_msg_test.go index dd2b8ae..415676d 100644 --- a/gen_msg_test.go +++ b/gen_msg_test.go @@ -23,21 +23,21 @@ func ExampleNewMessage() { fmt.Println(string(b)) } -func requireFieldByName(t *testing.T, md protoreflect.MessageDescriptor, msg *dynamicpb.Message, fieldName string) protoreflect.Value { +func requireFieldByName(t *testing.T, md protoreflect.MessageDescriptor, msg protoreflect.Message, fieldName string) protoreflect.Value { fd := md.Fields().ByJSONName(fieldName) require.NotNil(t, fd, "field %s does not exist", fieldName) return msg.Get(fd) } -func assertFieldIsSet(t *testing.T, md protoreflect.MessageDescriptor, msg *dynamicpb.Message, fieldName string) { +func assertFieldIsSet(t *testing.T, md protoreflect.MessageDescriptor, msg protoreflect.Message, fieldName string) { value := requireFieldByName(t, md, msg, fieldName) assert.NotNil(t, value, "field not set: %s", fieldName) assert.NotZero(t, value.Interface()) assert.True(t, value.IsValid()) } -func TestGenerateMessage(t *testing.T) { - t.Run("AllTypes", func(t *testing.T) { +func TestNewMessage(t *testing.T) { + t.Run("AllTypes - dynamicpb", func(t *testing.T) { md := testv1.File_test_v1_test_proto.Messages().ByName("AllTypes") msg := dynamicpb.NewMessage(md) fauxrpc.SetDataOnMessage(msg) @@ -75,7 +75,46 @@ func TestGenerateMessage(t *testing.T) { assertFieldIsSet(t, md, msg, "optMsgValue") }) - t.Run("ParameterValues", func(t *testing.T) { + t.Run("AllTypes - concrete", func(t *testing.T) { + msg := &testv1.AllTypes{} + fauxrpc.SetDataOnMessage(msg) + md := msg.ProtoReflect().Descriptor() + pmsg := msg.ProtoReflect() + assertFieldIsSet(t, md, pmsg, "doubleValue") + assertFieldIsSet(t, md, pmsg, "doubleValue") + assertFieldIsSet(t, md, pmsg, "floatValue") + assertFieldIsSet(t, md, pmsg, "int32Value") + assertFieldIsSet(t, md, pmsg, "int64Value") + assertFieldIsSet(t, md, pmsg, "uint32Value") + assertFieldIsSet(t, md, pmsg, "uint64Value") + assertFieldIsSet(t, md, pmsg, "sint32Value") + assertFieldIsSet(t, md, pmsg, "sint64Value") + assertFieldIsSet(t, md, pmsg, "fixed32Value") + assertFieldIsSet(t, md, pmsg, "fixed64Value") + assertFieldIsSet(t, md, pmsg, "sfixed32Value") + assertFieldIsSet(t, md, pmsg, "sfixed64Value") + assertFieldIsSet(t, md, pmsg, "boolValue") + assertFieldIsSet(t, md, pmsg, "stringValue") + assertFieldIsSet(t, md, pmsg, "bytesValue") + assertFieldIsSet(t, md, pmsg, "optDoubleValue") + assertFieldIsSet(t, md, pmsg, "optFloatValue") + assertFieldIsSet(t, md, pmsg, "optInt32Value") + assertFieldIsSet(t, md, pmsg, "optInt64Value") + assertFieldIsSet(t, md, pmsg, "optUint32Value") + assertFieldIsSet(t, md, pmsg, "optUint64Value") + assertFieldIsSet(t, md, pmsg, "optSint32Value") + assertFieldIsSet(t, md, pmsg, "optSint64Value") + assertFieldIsSet(t, md, pmsg, "optFixed32Value") + assertFieldIsSet(t, md, pmsg, "optFixed64Value") + assertFieldIsSet(t, md, pmsg, "optSfixed32Value") + assertFieldIsSet(t, md, pmsg, "optSfixed64Value") + assertFieldIsSet(t, md, pmsg, "optBoolValue") + assertFieldIsSet(t, md, pmsg, "optStringValue") + assertFieldIsSet(t, md, pmsg, "optBytesValue") + assertFieldIsSet(t, md, pmsg, "optMsgValue") + }) + + t.Run("ParameterValues - dynamicpb", func(t *testing.T) { md := testv1.File_test_v1_test_proto.Messages().ByName("ParameterValues") msg := dynamicpb.NewMessage(md) fauxrpc.SetDataOnMessage(msg) @@ -108,4 +147,39 @@ func TestGenerateMessage(t *testing.T) { assertFieldIsSet(t, md, msg, "fieldMask") assertFieldIsSet(t, md, msg, "enumList") }) + + t.Run("ParameterValues - concrete", func(t *testing.T) { + msg := &testv1.ParameterValues{} + fauxrpc.SetDataOnMessage(msg) + md := msg.ProtoReflect().Descriptor() + pmsg := msg.ProtoReflect() + assertFieldIsSet(t, md, pmsg, "doubleValue") + assertFieldIsSet(t, md, pmsg, "floatValue") + assertFieldIsSet(t, md, pmsg, "int32Value") + assertFieldIsSet(t, md, pmsg, "int64Value") + assertFieldIsSet(t, md, pmsg, "uint32Value") + assertFieldIsSet(t, md, pmsg, "uint64Value") + assertFieldIsSet(t, md, pmsg, "sint32Value") + assertFieldIsSet(t, md, pmsg, "sint64Value") + assertFieldIsSet(t, md, pmsg, "fixed32Value") + assertFieldIsSet(t, md, pmsg, "fixed64Value") + assertFieldIsSet(t, md, pmsg, "sfixed32Value") + assertFieldIsSet(t, md, pmsg, "sfixed64Value") + assertFieldIsSet(t, md, pmsg, "boolValue") + assertFieldIsSet(t, md, pmsg, "stringValue") + assertFieldIsSet(t, md, pmsg, "bytesValue") + assertFieldIsSet(t, md, pmsg, "timestamp") + assertFieldIsSet(t, md, pmsg, "duration") + assertFieldIsSet(t, md, pmsg, "boolValueWrapper") + assertFieldIsSet(t, md, pmsg, "int32ValueWrapper") + assertFieldIsSet(t, md, pmsg, "int64ValueWrapper") + assertFieldIsSet(t, md, pmsg, "uint32ValueWrapper") + assertFieldIsSet(t, md, pmsg, "uint64ValueWrapper") + assertFieldIsSet(t, md, pmsg, "floatValueWrapper") + assertFieldIsSet(t, md, pmsg, "doubleValueWrapper") + assertFieldIsSet(t, md, pmsg, "bytesValueWrapper") + assertFieldIsSet(t, md, pmsg, "stringValueWrapper") + assertFieldIsSet(t, md, pmsg, "fieldMask") + assertFieldIsSet(t, md, pmsg, "enumList") + }) }