From 27bd104cb634f998a69ecf003f091fef3d8fdb3e Mon Sep 17 00:00:00 2001 From: tbxark Date: Sun, 10 Nov 2024 23:21:22 +0800 Subject: [PATCH 1/2] feat: Add proto3 optional label support --- entproto/adapter.go | 18 +++++++++++------- entproto/message.go | 9 +++++++++ entproto/service.go | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/entproto/adapter.go b/entproto/adapter.go index 3c42e16c7..b27c37cac 100644 --- a/entproto/adapter.go +++ b/entproto/adapter.go @@ -39,6 +39,7 @@ const ( var ( ErrSchemaSkipped = errors.New("entproto: schema not annotated with Generate=true") repeatedFieldLabel = descriptorpb.FieldDescriptorProto_LABEL_REPEATED + optionalFieldLabel = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL wktsPaths = map[string]string{ // TODO: handle more Well-Known proto types "google.protobuf.Timestamp": "google/protobuf/timestamp.proto", @@ -324,8 +325,7 @@ func (a *Adapter) toProtoMessageDescriptor(genType *gen.Type) (*descriptorpb.Des if _, ok := f.Annotations[SkipAnnotation]; ok { continue } - - protoField, err := toProtoFieldDescriptor(f) + protoField, err := toProtoFieldDescriptor(f, msgAnnot.EnableOptionLabel) if err != nil { return nil, err } @@ -453,7 +453,7 @@ func toProtoEnumDescriptor(fld *gen.Field) (*descriptorpb.EnumDescriptorProto, e return dp, nil } -func toProtoFieldDescriptor(f *gen.Field) (*descriptorpb.FieldDescriptorProto, error) { +func toProtoFieldDescriptor(f *gen.Field, enableOptionLabel bool) (*descriptorpb.FieldDescriptorProto, error) { fieldDesc := &descriptorpb.FieldDescriptorProto{ Name: &f.Name, } @@ -473,7 +473,7 @@ func toProtoFieldDescriptor(f *gen.Field) (*descriptorpb.FieldDescriptorProto, e } return fieldDesc, nil } - typeDetails, err := extractProtoTypeDetails(f) + typeDetails, err := extractProtoTypeDetails(f, enableOptionLabel) if err != nil { return nil, err } @@ -483,19 +483,21 @@ func toProtoFieldDescriptor(f *gen.Field) (*descriptorpb.FieldDescriptorProto, e } if typeDetails.repeated { fieldDesc.Label = &repeatedFieldLabel + } else if typeDetails.optional { + fieldDesc.Label = &optionalFieldLabel } return fieldDesc, nil } -func extractProtoTypeDetails(f *gen.Field) (fieldType, error) { +func extractProtoTypeDetails(f *gen.Field, enableOptionLabel bool) (fieldType, error) { if f.Type.Type == field.TypeJSON { - return extractJSONDetails(f) + return extractJSONDetails(f) // repeat fields are not required for optional label. } cfg, ok := typeMap[f.Type.Type] if !ok || cfg.unsupported { return fieldType{}, unsupportedTypeError{Type: f.Type} } - if f.Optional { + if f.Optional && !enableOptionLabel { if cfg.optionalType == "" { return fieldType{}, unsupportedTypeError{Type: f.Type} } @@ -511,6 +513,7 @@ func extractProtoTypeDetails(f *gen.Field) (fieldType, error) { return fieldType{ protoType: cfg.pbType, messageName: name, + optional: f.Optional && enableOptionLabel, }, nil } @@ -549,6 +552,7 @@ type fieldType struct { messageName string protoType descriptorpb.FieldDescriptorProto_Type repeated bool + optional bool } func strptr(s string) *string { diff --git a/entproto/message.go b/entproto/message.go index b386547ae..5530449a2 100644 --- a/entproto/message.go +++ b/entproto/message.go @@ -55,9 +55,18 @@ func PackageName(pkg string) MessageOption { } } +// EnableOptionLabel enables the option label in the generated protobuf message instead of google/protobuf/wrappers.proto +func EnableOptionLabel() MessageOption { + return func(msg *message) { + msg.EnableOptionLabel = true + } +} + type message struct { Generate bool Package string + + EnableOptionLabel bool } func (m message) Name() string { diff --git a/entproto/service.go b/entproto/service.go index bf8dec67b..6a5a88b44 100644 --- a/entproto/service.go +++ b/entproto/service.go @@ -123,7 +123,7 @@ var plural = gen.Funcs["plural"].(func(string) string) func (a *Adapter) genMethodProtos(genType *gen.Type, m Method) (methodResources, error) { input := &descriptorpb.DescriptorProto{} - idField, err := toProtoFieldDescriptor(genType.ID) + idField, err := toProtoFieldDescriptor(genType.ID, false) if err != nil { return methodResources{}, err } From 82332b120dcdf4d42423d661eb26a9702e4ce1b5 Mon Sep 17 00:00:00 2001 From: tbxark Date: Sun, 10 Nov 2024 23:28:17 +0800 Subject: [PATCH 2/2] fix: typo `Option` -> `Optional` --- entproto/adapter.go | 12 ++++++------ entproto/message.go | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/entproto/adapter.go b/entproto/adapter.go index b27c37cac..4232ab982 100644 --- a/entproto/adapter.go +++ b/entproto/adapter.go @@ -325,7 +325,7 @@ func (a *Adapter) toProtoMessageDescriptor(genType *gen.Type) (*descriptorpb.Des if _, ok := f.Annotations[SkipAnnotation]; ok { continue } - protoField, err := toProtoFieldDescriptor(f, msgAnnot.EnableOptionLabel) + protoField, err := toProtoFieldDescriptor(f, msgAnnot.EnableOptionalLabel) if err != nil { return nil, err } @@ -453,7 +453,7 @@ func toProtoEnumDescriptor(fld *gen.Field) (*descriptorpb.EnumDescriptorProto, e return dp, nil } -func toProtoFieldDescriptor(f *gen.Field, enableOptionLabel bool) (*descriptorpb.FieldDescriptorProto, error) { +func toProtoFieldDescriptor(f *gen.Field, enableOptionalLabel bool) (*descriptorpb.FieldDescriptorProto, error) { fieldDesc := &descriptorpb.FieldDescriptorProto{ Name: &f.Name, } @@ -473,7 +473,7 @@ func toProtoFieldDescriptor(f *gen.Field, enableOptionLabel bool) (*descriptorpb } return fieldDesc, nil } - typeDetails, err := extractProtoTypeDetails(f, enableOptionLabel) + typeDetails, err := extractProtoTypeDetails(f, enableOptionalLabel) if err != nil { return nil, err } @@ -489,7 +489,7 @@ func toProtoFieldDescriptor(f *gen.Field, enableOptionLabel bool) (*descriptorpb return fieldDesc, nil } -func extractProtoTypeDetails(f *gen.Field, enableOptionLabel bool) (fieldType, error) { +func extractProtoTypeDetails(f *gen.Field, enableOptionalLabel bool) (fieldType, error) { if f.Type.Type == field.TypeJSON { return extractJSONDetails(f) // repeat fields are not required for optional label. } @@ -497,7 +497,7 @@ func extractProtoTypeDetails(f *gen.Field, enableOptionLabel bool) (fieldType, e if !ok || cfg.unsupported { return fieldType{}, unsupportedTypeError{Type: f.Type} } - if f.Optional && !enableOptionLabel { + if f.Optional && !enableOptionalLabel { if cfg.optionalType == "" { return fieldType{}, unsupportedTypeError{Type: f.Type} } @@ -513,7 +513,7 @@ func extractProtoTypeDetails(f *gen.Field, enableOptionLabel bool) (fieldType, e return fieldType{ protoType: cfg.pbType, messageName: name, - optional: f.Optional && enableOptionLabel, + optional: f.Optional && enableOptionalLabel, }, nil } diff --git a/entproto/message.go b/entproto/message.go index 5530449a2..30c357171 100644 --- a/entproto/message.go +++ b/entproto/message.go @@ -55,10 +55,10 @@ func PackageName(pkg string) MessageOption { } } -// EnableOptionLabel enables the option label in the generated protobuf message instead of google/protobuf/wrappers.proto -func EnableOptionLabel() MessageOption { +// EnableOptionalLabel enables the optional label in the generated protobuf message instead of google/protobuf/wrappers.proto +func EnableOptionalLabel() MessageOption { return func(msg *message) { - msg.EnableOptionLabel = true + msg.EnableOptionalLabel = true } } @@ -66,7 +66,7 @@ type message struct { Generate bool Package string - EnableOptionLabel bool + EnableOptionalLabel bool } func (m message) Name() string {