Skip to content

Commit

Permalink
Make Goa proto wrapper field optional for arrays (#3167)
Browse files Browse the repository at this point in the history
Since proto will serialize empty arrays as nil.
  • Loading branch information
raphael authored Oct 12, 2022
1 parent d96229f commit 5421505
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 48 deletions.
23 changes: 13 additions & 10 deletions grpc/codegen/protobuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ func makeProtoBufMessage(att *expr.AttributeExpr, tname string, sd *ServiceData)
}
return att
case expr.IsPrimitive(att.Type):
wrapAttr(att, tname, sd)
wrapAttr(att, tname, true, sd)
return att
case isut:
if expr.IsArray(ut) {
wrapAttr(att, tname, sd)
wrapAttr(att, tname, false, sd)
}
case expr.IsArray(att.Type) || expr.IsMap(att.Type):
wrapAttr(att, tname, sd)
wrapAttr(att, tname, false, sd)
case expr.IsObject(att.Type) || expr.IsUnion(att.Type):
att.Type = &expr.UserTypeExpr{
TypeName: tname,
Expand Down Expand Up @@ -102,12 +102,12 @@ func makeProtoBufMessageR(att *expr.AttributeExpr, tname *string, sd *ServiceDat
switch {
case expr.IsArray(att.Type):
wrapAttr(att, "ArrayOf"+tname+
protoBufify(protoBufMessageDef(expr.AsArray(att.Type).ElemType, sd), true, true), sd)
protoBufify(protoBufMessageDef(expr.AsArray(att.Type).ElemType, sd), true, true), true, sd)
case expr.IsMap(att.Type):
m := expr.AsMap(att.Type)
wrapAttr(att, tname+"MapOf"+
protoBufify(protoBufMessageDef(m.KeyType, sd), true, true)+
protoBufify(protoBufMessageDef(m.ElemType, sd), true, true), sd)
protoBufify(protoBufMessageDef(m.ElemType, sd), true, true), true, sd)
}
}

Expand All @@ -116,7 +116,7 @@ func makeProtoBufMessageR(att *expr.AttributeExpr, tname *string, sd *ServiceDat
return
case isut:
if expr.IsArray(ut) {
wrapAttr(ut.Attribute(), ut.Name(), sd)
wrapAttr(ut.Attribute(), ut.Name(), false, sd)
}
makeProtoBufMessageR(ut.Attribute(), tname, sd, seen)
case expr.IsArray(att.Type):
Expand All @@ -140,9 +140,9 @@ func makeProtoBufMessageR(att *expr.AttributeExpr, tname *string, sd *ServiceDat

// wrapAttr makes the attribute type a user type by wrapping the given
// attribute into an attribute named "field".
func wrapAttr(att *expr.AttributeExpr, tname string, sd *ServiceData) {
func wrapAttr(att *expr.AttributeExpr, tname string, req bool, sd *ServiceData) {
wrap := func(attr *expr.AttributeExpr) *expr.AttributeExpr {
return &expr.AttributeExpr{
res := &expr.AttributeExpr{
Type: &expr.Object{
&expr.NamedAttributeExpr{
Name: "field",
Expand All @@ -153,10 +153,13 @@ func wrapAttr(att *expr.AttributeExpr, tname string, sd *ServiceData) {
},
},
},
Validation: &expr.ValidationExpr{
}
if req {
res.Validation = &expr.ValidationExpr{
Required: []string{"field"},
},
}
}
return res
}
switch dt := att.Type.(type) {
case expr.UserType:
Expand Down
29 changes: 0 additions & 29 deletions grpc/codegen/testdata/client_type_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,35 +183,6 @@ func NewMethodResultWithCollectionResult(message *service_result_with_collection
return result
}
// ValidateMethodResultWithCollectionResponse runs the validations defined on
// MethodResultWithCollectionResponse.
func ValidateMethodResultWithCollectionResponse(message *service_result_with_collectionpb.MethodResultWithCollectionResponse) (err error) {
if message.Result != nil {
if err2 := ValidateResultT(message.Result); err2 != nil {
err = goa.MergeErrors(err, err2)
}
}
return
}
// ValidateResultT runs the validations defined on ResultT.
func ValidateResultT(result *service_result_with_collectionpb.ResultT) (err error) {
if result.CollectionField != nil {
if err2 := ValidateRTCollection(result.CollectionField); err2 != nil {
err = goa.MergeErrors(err, err2)
}
}
return
}
// ValidateRTCollection runs the validations defined on RTCollection.
func ValidateRTCollection(collectionField *service_result_with_collectionpb.RTCollection) (err error) {
if collectionField.Field == nil {
err = goa.MergeErrors(err, goa.MissingFieldError("field", "collectionField"))
}
return
}
// svcServiceresultwithcollectionResultTToServiceResultWithCollectionpbResultT
// builds a value of type *service_result_with_collectionpb.ResultT from a
// value of type *serviceresultwithcollection.ResultT.
Expand Down
3 changes: 0 additions & 3 deletions grpc/codegen/testdata/request_decoder_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ func DecodeMethodUnaryRPCNoResultRequest(ctx context.Context, v interface{}, md
if message, ok = v.(*service_unary_rpc_no_resultpb.MethodUnaryRPCNoResultRequest); !ok {
return nil, goagrpc.ErrInvalidType("ServiceUnaryRPCNoResult", "MethodUnaryRPCNoResult", "*service_unary_rpc_no_resultpb.MethodUnaryRPCNoResultRequest", v)
}
if err := ValidateMethodUnaryRPCNoResultRequest(message); err != nil {
return nil, err
}
}
var payload []string
{
Expand Down
6 changes: 0 additions & 6 deletions grpc/codegen/testdata/streaming_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,6 @@ func (s *MethodServerStreamingArrayClientStream) Recv() ([]int, error) {
if err != nil {
return res, err
}
if err = ValidateMethodServerStreamingArrayResponse(v); err != nil {
return res, err
}
return NewMethodServerStreamingArrayResponse(v), nil
}
`
Expand All @@ -197,9 +194,6 @@ func (s *MethodServerStreamingMapClientStream) Recv() (map[string]*serviceserver
if err != nil {
return res, err
}
if err = ValidateMethodServerStreamingMapResponse(v); err != nil {
return res, err
}
return NewMethodServerStreamingMapResponse(v), nil
}
`
Expand Down

0 comments on commit 5421505

Please sign in to comment.