Skip to content

Commit 65c176b

Browse files
authored
Fix Go codegen for string values that contain quotes (#423)
* Fix Go codegen for string values that contain quotes * Remove dbg * Handle escaped characters correctly for both gen and sync
1 parent c8ccd39 commit 65c176b

File tree

2 files changed

+37
-32
lines changed

2 files changed

+37
-32
lines changed

pkg/gen/golang.go

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ func (c *LekkoClient) {{$.FuncName}}({{$.ArgumentString}}) {{$.RetType}} {
478478
}`,
479479
private: `// {{$.Description}}
480480
func {{$.PrivateFunc}}({{$.ArgumentString}}) {{$.RetType}} {
481-
{{range $.NaturalLanguage}}{{ . }}
481+
{{range $.NativeLanguage}}{{ . }}
482482
{{end}}}`,
483483
}
484484
}
@@ -498,7 +498,7 @@ func (c *LekkoClient) {{$.FuncName}}({{$.ArgumentString}}) *{{$.RetType}} {
498498
}`,
499499
private: `// {{$.Description}}
500500
func {{$.PrivateFunc}}({{$.ArgumentString}}) *{{$.RetType}} {
501-
{{range $.NaturalLanguage}}{{ . }}
501+
{{range $.NativeLanguage}}{{ . }}
502502
{{end}}}`,
503503
}
504504
}
@@ -531,7 +531,7 @@ const (
531531
532532
// {{$.Description}}
533533
func {{$.PrivateFunc}}({{$.ArgumentString}}) {{$.RetType}} {
534-
{{range $.NaturalLanguage}}{{ . }}
534+
{{range $.NativeLanguage}}{{ . }}
535535
{{end}}}`,
536536
}
537537
}
@@ -613,19 +613,19 @@ func (g *goGenerator) genGoForFeature(ctx context.Context, r repo.ConfigurationR
613613
}
614614

615615
data := struct {
616-
Description string
617-
FuncName string
618-
PrivateFunc string
619-
GetFunction string
620-
RetType string
621-
Namespace string
622-
Key string
623-
NaturalLanguage []string
624-
ArgumentString string
625-
CallString string
626-
EnumTypeName string
627-
EnumFields []EnumField
628-
CtxStuff string
616+
Description string
617+
FuncName string
618+
PrivateFunc string
619+
GetFunction string
620+
RetType string
621+
Namespace string
622+
Key string
623+
NativeLanguage []string
624+
ArgumentString string
625+
CallString string
626+
EnumTypeName string
627+
EnumFields []EnumField
628+
CtxStuff string
629629
}{
630630
f.Description,
631631
funcName,
@@ -644,7 +644,7 @@ func (g *goGenerator) genGoForFeature(ctx context.Context, r repo.ConfigurationR
644644
generated := &generatedConfigCode{}
645645
usedVariables := make(map[string]string)
646646
if staticCtxType != nil {
647-
data.NaturalLanguage = g.translateFeature(f, protoType, true, usedVariables, &generated.usedStrings, &generated.usedSlices)
647+
data.NativeLanguage = g.translateFeature(f, protoType, true, usedVariables, &generated.usedStrings, &generated.usedSlices)
648648
if staticCtxType.PackageAlias != "" {
649649
data.ArgumentString = fmt.Sprintf("args *%s.%s", staticCtxType.PackageAlias, staticCtxType.Type)
650650
} else {
@@ -653,7 +653,7 @@ func (g *goGenerator) genGoForFeature(ctx context.Context, r repo.ConfigurationR
653653
data.CallString = "args"
654654
} else {
655655
data.CtxStuff = "args := context.Background()\n"
656-
data.NaturalLanguage = g.translateFeature(f, protoType, false, usedVariables, &generated.usedStrings, &generated.usedSlices)
656+
data.NativeLanguage = g.translateFeature(f, protoType, false, usedVariables, &generated.usedStrings, &generated.usedSlices)
657657
var arguments []string
658658
var ctxAddLines []string
659659
for f, t := range usedVariables {
@@ -896,13 +896,7 @@ func (g *goGenerator) translateProtoNonRepeatedValue(parent protoreflect.Message
896896
// TODO: Actually handle enums, right now they're just numbers
897897
return val.String()
898898
case protoreflect.StringKind:
899-
// If the string value is multiline, transform to raw literal instead
900-
valString := val.String()
901-
quote := "\""
902-
if strings.Count(valString, "\n") > 0 {
903-
quote = "`"
904-
}
905-
return fmt.Sprintf("%s%s%s", quote, val.String(), quote)
899+
return g.toQuoted(val.String())
906900
case protoreflect.BoolKind:
907901
return val.String()
908902
case protoreflect.BytesKind:
@@ -945,12 +939,7 @@ func (g *goGenerator) translateAnyValue(val *anypb.Any, protoType *ProtoImport)
945939
if val.MessageIs((*wrapperspb.StringValue)(nil)) {
946940
var s wrapperspb.StringValue
947941
try.To(val.UnmarshalTo(&s))
948-
// If multiline string value, gen as raw string literal instead
949-
quote := "\""
950-
if strings.Count(s.Value, "\n") > 0 {
951-
quote = "`"
952-
}
953-
return fmt.Sprintf("%s%s%s", quote, s.Value, quote)
942+
return g.toQuoted(s.Value)
954943
}
955944
return string(try.To1(protojson.Marshal(msg)))
956945
}
@@ -977,6 +966,16 @@ func (g *goGenerator) translateProtoValue(parent protoreflect.Message, val proto
977966
}
978967
}
979968

969+
// Takes a string and returns a double-quoted literal with applicable internal characters escaped, etc.
970+
// For strings with newlines, returns a raw string literal instead.
971+
func (g *goGenerator) toQuoted(s string) string {
972+
if strings.Count(s, "\n") > 0 {
973+
return fmt.Sprintf("`%s`", s)
974+
}
975+
// Quote automatically handles escaping, etc.
976+
return strconv.Quote(s)
977+
}
978+
980979
// Handles getting import & type literal information for both top-level and nested messages.
981980
// TODO: Consider moving logic into UnpackProtoType directly which is shared with TS codegen as well
982981
// TODO: This can definitely be cached, and doesn't need values, just descriptors

pkg/sync/golang.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,13 @@ func (g *goSyncer) primitiveToProtoValue(expr ast.Expr) any {
578578
case *ast.BasicLit:
579579
switch x.Kind {
580580
case token.STRING:
581-
return strings.Trim(x.Value, "\"`")
581+
// Need to unescape escaped - Unquote also handles escaped chars in middle
582+
// and is fine with alternate quotes like ' or `
583+
if unescaped, err := strconv.Unquote(x.Value); err == nil {
584+
return unescaped
585+
} else {
586+
panic(errors.Wrapf(err, "unescape string literal %s", x.Value))
587+
}
582588
case token.INT:
583589
// TODO - parse/validate based on field Kind, because this breaks for
584590
// int32, etc. fields

0 commit comments

Comments
 (0)