Skip to content

Commit

Permalink
Merge pull request #13 from infiniteloopcloud/12-fix-zero-value
Browse files Browse the repository at this point in the history
Add zero_override field option
  • Loading branch information
PumpkinSeed authored Dec 3, 2022
2 parents 502726f + 84a5d37 commit bb44b2b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 21 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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, go_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.
go_zero_override = 1004
Because `protoc` can't process the extended options, so we can't find the by name, just by place.
42 changes: 30 additions & 12 deletions cmd/protoc-gen-go/internal_gengo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ const (
)

type overrideParams struct {
goType string
goImport string
goImportAlias string
goType string
goImport string
goImportAlias string
goZeroOverride string
}

// overrideFields stores all the found messages which are created to override types
Expand Down Expand Up @@ -197,6 +198,10 @@ func processExtensions(field *protogen.Field) (overrideParams, bool) {
case impl.FieldOptionGoImportAlias:
override.goImportAlias = ex.Value().String()
ok = true
case impl.FieldOptionGoZeroOverride:
log.Log("processExtensions:: zero override found!")
override.goZeroOverride = ex.Value().String()
ok = true
}
}
return override, ok
Expand All @@ -219,6 +224,9 @@ func processUninterpretedOptions(field *protogen.Field) (overrideParams, bool) {
case impl.FieldOptionGoImportAlias:
override.goImportAlias = string(o.GetStringValue())
ok = true
case impl.FieldOptionGoZeroOverride:
override.goZeroOverride = string(o.GetStringValue())
ok = true
}
}
}
Expand Down Expand Up @@ -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)},
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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.goZeroOverride)
if overrideParam.goZeroOverride != "" {
return overrideParam.goZeroOverride
}
return overwrittenDefault(goType)
}
if field.Desc.IsList() {
Expand Down Expand Up @@ -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
}
1 change: 1 addition & 0 deletions cmd/protoc-gen-go/internal_gengo/test_data/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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 go_zero_override = 1004;
}
1 change: 1 addition & 0 deletions cmd/protoc-gen-go/internal_gengo/test_data/test.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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) = "", (go_zero_override) = "\"\""];
}
16 changes: 10 additions & 6 deletions internal/impl/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import (
)

const (
FieldOptionGoType = "go_type"
FieldOptionGoImport = "go_import"
FieldOptionGoImportAlias = "go_import_alias"
FieldOptionGoType = "go_type"
FieldOptionGoImport = "go_import"
FieldOptionGoImportAlias = "go_import_alias"
FieldOptionGoZeroOverride = "go_zero_override"

FieldOptionGoTypeNum = 1001
FieldOptionGoImportNum = 1002
FieldOptionGoImportAliasNum = 1003
FieldOptionGoTypeNum = 1001
FieldOptionGoImportNum = 1002
FieldOptionGoImportAliasNum = 1003
FieldOptionGoZeroOverrideNum = 1004
)

var errDecode = errors.New("cannot parse invalid wire-format data")
Expand Down Expand Up @@ -281,6 +283,8 @@ func (mi *MessageInfo) fallbackCreateExtension(num protowire.Number) (protorefle
name = FieldOptionGoImport
case FieldOptionGoImportAliasNum:
name = FieldOptionGoImportAlias
case FieldOptionGoZeroOverrideNum:
name = FieldOptionGoZeroOverride
default:
return nil, errors.New("invalid name")
}
Expand Down

0 comments on commit bb44b2b

Please sign in to comment.