From 5510a584e4bbb78ab42f6c9567bf938e6b8baea6 Mon Sep 17 00:00:00 2001 From: Robert Boros Date: Fri, 2 Dec 2022 14:28:07 +0100 Subject: [PATCH 1/2] add zero_override field option to handle custom getter default return values --- README.md | 7 ++-- cmd/protoc-gen-go/internal_gengo/main.go | 36 ++++++++++++++----- .../internal_gengo/test_data/config.proto | 1 + .../internal_gengo/test_data/test.proto | 1 + internal/impl/decode.go | 4 +++ 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3c6b50cf9..dff01eb44 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Fork of [Protobuf Golang](https://github.com/protocolbuffers/protobuf-go) specialized for type generation -This package supposed to focus on type generation based on proto file. +This package supposed to focus on type generation based on proto file. ### Features compared to original repository @@ -41,8 +41,9 @@ message TimeTime {} #### Important -Currently the overwritten FieldOptions (go_type, go_import, go_import_alias) must be paired with these numbers: +Currently the overwritten FieldOptions (go_type, go_import, go_import_alias, zero_override) must be paired with these numbers: go_type = 1001 go_import = 1002 go_import_alias = 1003 -Because `protoc` can't process the extended options, so we can't find the by name, just by place. +zero_override = 1004 +Because `protoc` can't process the extended options, so we can't find the by name, just by place. diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go index ae212dba4..85a15c4a5 100644 --- a/cmd/protoc-gen-go/internal_gengo/main.go +++ b/cmd/protoc-gen-go/internal_gengo/main.go @@ -39,6 +39,7 @@ type overrideParams struct { goType string goImport string goImportAlias string + zeroOverride string } // overrideFields stores all the found messages which are created to override types @@ -197,6 +198,10 @@ func processExtensions(field *protogen.Field) (overrideParams, bool) { case impl.FieldOptionGoImportAlias: override.goImportAlias = ex.Value().String() ok = true + case impl.FieldOptionZeroOverride: + log.Log("processExtensions:: zero override found!") + override.zeroOverride = ex.Value().String() + ok = true } } return override, ok @@ -219,6 +224,9 @@ func processUninterpretedOptions(field *protogen.Field) (overrideParams, bool) { case impl.FieldOptionGoImportAlias: override.goImportAlias = string(o.GetStringValue()) ok = true + case impl.FieldOptionZeroOverride: + override.zeroOverride = string(o.GetStringValue()) + ok = true } } } @@ -523,7 +531,9 @@ func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, fie if pointer { goType = "*" + goType } - goType, _ = goTypeOverride(goType, m.GoIdent.GoName, field.GoName) + if overrideParam, ok := goTypeOverride(m.GoIdent.GoName, field.GoName); ok { + goType = overrideParam.goType + } tags := structTags{ {"protobuf", fieldProtobufTagValue(field)}, {"json", fieldJSONTagValue(field)}, @@ -563,7 +573,9 @@ func genMessageDefaultDecls(g *protogen.GeneratedFile, f *fileInfo, m *messageIn } name := "Default_" + m.GoIdent.GoName + "_" + field.GoName goType, _ := fieldGoType(g, f, field) - goType, _ = goTypeOverride(goType, m.GoIdent.GoName, field.GoName) + if overrideParam, ok := goTypeOverride(m.GoIdent.GoName, field.GoName); ok { + goType = overrideParam.goType + } defVal := field.Desc.Default() switch field.Desc.Kind() { case protoreflect.StringKind: @@ -686,9 +698,11 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI // Getter for message field. goType, pointer := fieldGoType(g, f, field) - var overwritten bool - goType, overwritten = goTypeOverride(goType, m.GoIdent.GoName, field.GoName) - defaultValue := fieldDefaultValue(g, f, m, field, goType, overwritten) + overrideParam, overwritten := goTypeOverride(m.GoIdent.GoName, field.GoName) + if overwritten { + goType = overrideParam.goType + } + defaultValue := fieldDefaultValue(g, f, m, field, goType, overrideParam, overwritten) g.Annotate(m.GoIdent.GoName+".Get"+field.GoName, field.Location) leadingComments := appendDeprecationSuffix("", field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated()) @@ -814,8 +828,12 @@ func fieldProtobufTagValue(field *protogen.Field) string { return tag.Marshal(field.Desc, enumName) } -func fieldDefaultValue(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field, goType string, overwritten bool) string { +func fieldDefaultValue(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field, goType string, overrideParam overrideParams, overwritten bool) string { if overwritten { + log.Log("custom zero value: %q", overrideParam.zeroOverride) + if overrideParam.zeroOverride != "" { + return overrideParam.zeroOverride + } return overwrittenDefault(goType) } if field.Desc.IsList() { @@ -1051,17 +1069,17 @@ func (c trailingComment) String() string { return s } -func goTypeOverride(goType string, msgName string, fieldName string) (string, bool) { +func goTypeOverride(msgName string, fieldName string) (overrideParams, bool) { if TypeOverride { // TODO check the case when goType is a map if oMsg, okMsg := overrideFields[msgName]; okMsg { if o, okField := oMsg[fieldName]; okField { - return o.goType, true + return o, true } } // if strings.Contains(goType, "RepeatedString") { // return strings.ReplaceAll(goType, "RepeatedString", "[]string") // } } - return goType, false + return overrideParams{}, false } diff --git a/cmd/protoc-gen-go/internal_gengo/test_data/config.proto b/cmd/protoc-gen-go/internal_gengo/test_data/config.proto index 659fd714c..366c376c8 100644 --- a/cmd/protoc-gen-go/internal_gengo/test_data/config.proto +++ b/cmd/protoc-gen-go/internal_gengo/test_data/config.proto @@ -10,4 +10,5 @@ extend google.protobuf.FieldOptions { optional string go_type = 1001; optional string go_import = 1002; optional string go_import_alias = 1003; + optional string zero_override = 1004; } diff --git a/cmd/protoc-gen-go/internal_gengo/test_data/test.proto b/cmd/protoc-gen-go/internal_gengo/test_data/test.proto index 823d6a2a7..c888f7314 100644 --- a/cmd/protoc-gen-go/internal_gengo/test_data/test.proto +++ b/cmd/protoc-gen-go/internal_gengo/test_data/test.proto @@ -29,4 +29,5 @@ message Test { string optStr = 4 [(go_type) = "null.String", (go_import) = "github.com/volatiletech/null/v9", (go_import_alias) = "null"]; int32 optInt = 5 [(go_type) = "null.Int32"]; int32 optBigInt = 6 [(go_type) = "null.Int64", (go_import) = "github.com/volatiletech/null/v9", (go_import_alias) = "null"]; + string something = 7 [(go_type) = "Something", (go_import) = "", (zero_override) = "\"\""]; } diff --git a/internal/impl/decode.go b/internal/impl/decode.go index cbd6a0b1a..65229cbfc 100644 --- a/internal/impl/decode.go +++ b/internal/impl/decode.go @@ -23,10 +23,12 @@ const ( FieldOptionGoType = "go_type" FieldOptionGoImport = "go_import" FieldOptionGoImportAlias = "go_import_alias" + FieldOptionZeroOverride = "zero_override" FieldOptionGoTypeNum = 1001 FieldOptionGoImportNum = 1002 FieldOptionGoImportAliasNum = 1003 + FieldOptionZeroOverrideNum = 1004 ) var errDecode = errors.New("cannot parse invalid wire-format data") @@ -281,6 +283,8 @@ func (mi *MessageInfo) fallbackCreateExtension(num protowire.Number) (protorefle name = FieldOptionGoImport case FieldOptionGoImportAliasNum: name = FieldOptionGoImportAlias + case FieldOptionZeroOverrideNum: + name = FieldOptionZeroOverride default: return nil, errors.New("invalid name") } From 84a5d376502431989474ec72d3b2723efd51f14f Mon Sep 17 00:00:00 2001 From: PumpkinSeed Date: Sat, 3 Dec 2022 10:29:56 +0100 Subject: [PATCH 2/2] Rename it to goZeroOverride --- README.md | 4 ++-- cmd/protoc-gen-go/internal_gengo/main.go | 22 +++++++++---------- .../internal_gengo/test_data/config.proto | 2 +- .../internal_gengo/test_data/test.proto | 2 +- internal/impl/decode.go | 20 ++++++++--------- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index dff01eb44..cc3e7f04a 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ message TimeTime {} #### Important -Currently the overwritten FieldOptions (go_type, go_import, go_import_alias, zero_override) must be paired with these numbers: +Currently the overwritten FieldOptions (go_type, go_import, go_import_alias, go_zero_override) must be paired with these numbers: go_type = 1001 go_import = 1002 go_import_alias = 1003 -zero_override = 1004 +go_zero_override = 1004 Because `protoc` can't process the extended options, so we can't find the by name, just by place. diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go index 85a15c4a5..ced7db486 100644 --- a/cmd/protoc-gen-go/internal_gengo/main.go +++ b/cmd/protoc-gen-go/internal_gengo/main.go @@ -36,10 +36,10 @@ const ( ) type overrideParams struct { - goType string - goImport string - goImportAlias string - zeroOverride string + goType string + goImport string + goImportAlias string + goZeroOverride string } // overrideFields stores all the found messages which are created to override types @@ -198,9 +198,9 @@ func processExtensions(field *protogen.Field) (overrideParams, bool) { case impl.FieldOptionGoImportAlias: override.goImportAlias = ex.Value().String() ok = true - case impl.FieldOptionZeroOverride: + case impl.FieldOptionGoZeroOverride: log.Log("processExtensions:: zero override found!") - override.zeroOverride = ex.Value().String() + override.goZeroOverride = ex.Value().String() ok = true } } @@ -224,8 +224,8 @@ func processUninterpretedOptions(field *protogen.Field) (overrideParams, bool) { case impl.FieldOptionGoImportAlias: override.goImportAlias = string(o.GetStringValue()) ok = true - case impl.FieldOptionZeroOverride: - override.zeroOverride = string(o.GetStringValue()) + case impl.FieldOptionGoZeroOverride: + override.goZeroOverride = string(o.GetStringValue()) ok = true } } @@ -830,9 +830,9 @@ func fieldProtobufTagValue(field *protogen.Field) string { func fieldDefaultValue(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field, goType string, overrideParam overrideParams, overwritten bool) string { if overwritten { - log.Log("custom zero value: %q", overrideParam.zeroOverride) - if overrideParam.zeroOverride != "" { - return overrideParam.zeroOverride + log.Log("custom zero value: %q", overrideParam.goZeroOverride) + if overrideParam.goZeroOverride != "" { + return overrideParam.goZeroOverride } return overwrittenDefault(goType) } diff --git a/cmd/protoc-gen-go/internal_gengo/test_data/config.proto b/cmd/protoc-gen-go/internal_gengo/test_data/config.proto index 366c376c8..ed7ccf574 100644 --- a/cmd/protoc-gen-go/internal_gengo/test_data/config.proto +++ b/cmd/protoc-gen-go/internal_gengo/test_data/config.proto @@ -10,5 +10,5 @@ extend google.protobuf.FieldOptions { optional string go_type = 1001; optional string go_import = 1002; optional string go_import_alias = 1003; - optional string zero_override = 1004; + optional string go_zero_override = 1004; } diff --git a/cmd/protoc-gen-go/internal_gengo/test_data/test.proto b/cmd/protoc-gen-go/internal_gengo/test_data/test.proto index c888f7314..0c58a6897 100644 --- a/cmd/protoc-gen-go/internal_gengo/test_data/test.proto +++ b/cmd/protoc-gen-go/internal_gengo/test_data/test.proto @@ -29,5 +29,5 @@ message Test { string optStr = 4 [(go_type) = "null.String", (go_import) = "github.com/volatiletech/null/v9", (go_import_alias) = "null"]; int32 optInt = 5 [(go_type) = "null.Int32"]; int32 optBigInt = 6 [(go_type) = "null.Int64", (go_import) = "github.com/volatiletech/null/v9", (go_import_alias) = "null"]; - string something = 7 [(go_type) = "Something", (go_import) = "", (zero_override) = "\"\""]; + string something = 7 [(go_type) = "Something", (go_import) = "", (go_zero_override) = "\"\""]; } diff --git a/internal/impl/decode.go b/internal/impl/decode.go index 65229cbfc..1a510566b 100644 --- a/internal/impl/decode.go +++ b/internal/impl/decode.go @@ -20,15 +20,15 @@ import ( ) const ( - FieldOptionGoType = "go_type" - FieldOptionGoImport = "go_import" - FieldOptionGoImportAlias = "go_import_alias" - FieldOptionZeroOverride = "zero_override" + FieldOptionGoType = "go_type" + FieldOptionGoImport = "go_import" + FieldOptionGoImportAlias = "go_import_alias" + FieldOptionGoZeroOverride = "go_zero_override" - FieldOptionGoTypeNum = 1001 - FieldOptionGoImportNum = 1002 - FieldOptionGoImportAliasNum = 1003 - FieldOptionZeroOverrideNum = 1004 + FieldOptionGoTypeNum = 1001 + FieldOptionGoImportNum = 1002 + FieldOptionGoImportAliasNum = 1003 + FieldOptionGoZeroOverrideNum = 1004 ) var errDecode = errors.New("cannot parse invalid wire-format data") @@ -283,8 +283,8 @@ func (mi *MessageInfo) fallbackCreateExtension(num protowire.Number) (protorefle name = FieldOptionGoImport case FieldOptionGoImportAliasNum: name = FieldOptionGoImportAlias - case FieldOptionZeroOverrideNum: - name = FieldOptionZeroOverride + case FieldOptionGoZeroOverrideNum: + name = FieldOptionGoZeroOverride default: return nil, errors.New("invalid name") }