Skip to content

Commit 3900708

Browse files
Merge pull request #5187 from yuwenma/mapper-slice-single
fix: mappergenerator slice and single object map
2 parents a9fb9af + 5a4f86c commit 3900708

File tree

3 files changed

+239
-104
lines changed

3 files changed

+239
-104
lines changed

dev/tools/controllerbuilder/pkg/codegen/mappergenerator.go

Lines changed: 177 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,6 @@ func (v *MapperGenerator) GenerateMappers(goImports map[string]string) error {
221221

222222
return nil
223223
}
224-
225224
func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string, pair *typePair) {
226225
klog.V(2).InfoS("writeMapFunctionsForPair", "pair.Proto.FullName", pair.Proto.FullName(), "pair.KRMType.Name", pair.KRMType.Name)
227226
msg := pair.Proto
@@ -316,6 +315,82 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
316315
continue
317316
}
318317

318+
isKRMFieldSlice := strings.HasPrefix(krmField.Type, "[]")
319+
isProtoFieldSlice := protoField.Cardinality() == protoreflect.Repeated
320+
321+
if isProtoFieldSlice && !isKRMFieldSlice && !protoField.IsMap() { // proto slice -> krm single
322+
var fromProtoElemFunc string
323+
switch protoField.Kind() {
324+
case protoreflect.MessageKind:
325+
krmElemTypeName := strings.TrimPrefix(krmField.Type, "*")
326+
fromProtoElemFunc = krmElemTypeName + versionSpecifier + "_FromProto"
327+
if _, ok := protoMessagesNotMappedToGoStruct[string(protoField.Message().FullName())]; ok {
328+
fromProtoElemFunc = krmFromProtoFunctionName(protoField, krmField.Name)
329+
}
330+
case protoreflect.EnumKind:
331+
fromProtoElemFunc = "direct. "
332+
}
333+
334+
fmt.Fprintf(out, "\tif len(in.%s) > 0 {\n", protoAccessor)
335+
if fromProtoElemFunc != "" {
336+
fmt.Fprintf(out, "\t\tout.%s = %s(mapCtx, in.%s[0])\n", krmFieldName, fromProtoElemFunc, protoAccessor)
337+
} else {
338+
if protoField.Kind() == protoreflect.BytesKind {
339+
fmt.Fprintf(out, "\t\tout.%s = in.%s[0]\n", krmFieldName, protoAccessor)
340+
} else {
341+
fmt.Fprintf(out, "\t\tout.%s = direct.LazyPtr(in.%s[0])\n", krmFieldName, protoAccessor)
342+
}
343+
}
344+
fmt.Fprintf(out, "\t}\n")
345+
continue
346+
}
347+
348+
if !isProtoFieldSlice && isKRMFieldSlice { // proto single -> krm slice
349+
krmSliceElemType := strings.TrimPrefix(krmField.Type, "[]")
350+
351+
switch protoField.Kind() {
352+
case protoreflect.MessageKind:
353+
krmElemTypeName := strings.TrimPrefix(krmSliceElemType, "*")
354+
functionName := krmElemTypeName + versionSpecifier + "_FromProto"
355+
if _, ok := protoMessagesNotMappedToGoStruct[string(protoField.Message().FullName())]; ok {
356+
functionName = krmFromProtoFunctionName(protoField, krmField.Name)
357+
}
358+
fmt.Fprintf(out, "\tif v := in.%s; v != nil {\n", protoAccessor)
359+
if strings.HasPrefix(krmSliceElemType, "*") {
360+
fmt.Fprintf(out, "\t\tout.%s = []*%s.%s{%s(mapCtx, v)}\n", krmFieldName, krmImportName, strings.TrimPrefix(krmSliceElemType, "*"), functionName)
361+
} else {
362+
fmt.Fprintf(out, "\t\tout.%s = []%s.%s{%s(mapCtx, v)}\n", krmFieldName, krmImportName, krmSliceElemType, functionName)
363+
}
364+
fmt.Fprintf(out, "\t}\n")
365+
366+
case protoreflect.EnumKind:
367+
functionName := "direct.Enum_FromProto"
368+
fmt.Fprintf(out, "\tout.%s = []%s.%s{%s(mapCtx, in.%s)}\n", krmFieldName, krmImportName, krmSliceElemType, functionName, protoAccessor)
369+
370+
case protoreflect.StringKind,
371+
protoreflect.FloatKind,
372+
protoreflect.DoubleKind,
373+
protoreflect.BoolKind,
374+
protoreflect.Int64Kind,
375+
protoreflect.Int32Kind,
376+
protoreflect.Uint32Kind,
377+
protoreflect.Uint64Kind,
378+
protoreflect.Fixed64Kind,
379+
protoreflect.BytesKind:
380+
if protoIsPointerInGo(protoField) {
381+
fmt.Fprintf(out, "\tif v := in.%s; v != nil {\n", protoFieldName)
382+
fmt.Fprintf(out, "\t\tout.%s = []%s.%s{v}\n", krmFieldName, krmImportName, krmSliceElemType)
383+
fmt.Fprintf(out, "\t}\n")
384+
} else {
385+
fmt.Fprintf(out, "\tout.%s = []%s.%s{direct.LazyPtr(in.%s)}\n", krmFieldName, krmImportName, krmSliceElemType, protoAccessor)
386+
}
387+
388+
default:
389+
klog.Fatalf("unhandled kind %q for field %v", protoField.Kind(), protoField)
390+
}
391+
continue
392+
}
393+
319394
if protoField.Cardinality() == protoreflect.Repeated {
320395
useSliceFromProtoFunction := ""
321396
useCustomMethod := ""
@@ -429,7 +504,8 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
429504
protoreflect.Int32Kind,
430505
protoreflect.Uint32Kind,
431506
protoreflect.Uint64Kind,
432-
protoreflect.Fixed64Kind:
507+
protoreflect.Fixed64Kind,
508+
protoreflect.BytesKind:
433509
if protoIsPointerInGo(protoField) {
434510
fmt.Fprintf(out, "\tout.%s = in.%s\n",
435511
krmFieldName,
@@ -442,12 +518,6 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
442518
)
443519
}
444520

445-
case protoreflect.BytesKind:
446-
fmt.Fprintf(out, "\tout.%s = in.%s\n",
447-
krmFieldName,
448-
protoAccessor,
449-
)
450-
451521
default:
452522
klog.Fatalf("unhandled kind %q for field %v", protoField.Kind(), protoField)
453523
}
@@ -474,7 +544,7 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
474544
// Support refs
475545
if krmFieldRef := goFields[krmFieldName+"Ref"]; krmFieldRef != nil {
476546
fmt.Fprintf(out, "\tif in.%s != nil {\n", krmFieldRef.Name)
477-
fmt.Fprintf(out, "\t\tout.%v = in.%v.External\n", protoFieldName, krmFieldRef.Name)
547+
fmt.Fprintf(out, "\t\tout.%s = in.%s.External\n", protoFieldName, krmFieldRef.Name)
478548
fmt.Fprintf(out, "\t}\n")
479549
continue
480550
}
@@ -486,7 +556,7 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
486556
out.{protoFieldName} = append(out.{protoFieldName}, v[i].External)
487557
}
488558
}
489-
`
559+
`
490560

491561
s := template
492562
s = strings.ReplaceAll(s, "{protoFieldName}", protoFieldName)
@@ -508,6 +578,93 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
508578
continue
509579
}
510580

581+
isKRMFieldSlice := strings.HasPrefix(krmField.Type, "[]")
582+
isProtoFieldSlice := protoField.Cardinality() == protoreflect.Repeated
583+
584+
if !isProtoFieldSlice && isKRMFieldSlice { // proto single <- krm slice
585+
krmElemType := strings.TrimPrefix(krmField.Type, "[]")
586+
krmElemTypeName := strings.TrimPrefix(krmElemType, "*")
587+
588+
fmt.Fprintf(out, "\tif len(in.%s) > 0 && in.%s[0] != nil {\n", krmFieldName, krmFieldName)
589+
590+
switch protoField.Kind() {
591+
case protoreflect.MessageKind:
592+
functionName := krmElemTypeName + versionSpecifier + "_ToProto"
593+
if _, ok := protoMessagesNotMappedToGoStruct[string(protoField.Message().FullName())]; ok {
594+
functionName = krmToProtoFunctionName(protoField, krmField.Name)
595+
}
596+
fmt.Fprintf(out, "\t\tout.%s = %s(mapCtx, in.%s[0])\n", protoFieldName, functionName, krmFieldName)
597+
598+
case protoreflect.EnumKind:
599+
protoTypeName := v.goPackageForProto(protoField.Enum().ParentFile()) + "." + protoNameForEnum(protoField.Enum())
600+
functionName := "direct.Enum_ToProto"
601+
fmt.Fprintf(out, "\t\tout.%s = %s[%s](mapCtx, *in.%s[0])\n", protoFieldName, functionName, protoTypeName, krmFieldName)
602+
603+
case protoreflect.StringKind,
604+
protoreflect.FloatKind,
605+
protoreflect.DoubleKind,
606+
protoreflect.BoolKind,
607+
protoreflect.Int64Kind,
608+
protoreflect.Int32Kind,
609+
protoreflect.Uint32Kind,
610+
protoreflect.Uint64Kind,
611+
protoreflect.Fixed64Kind,
612+
protoreflect.BytesKind:
613+
if protoIsPointerInGo(protoField) {
614+
fmt.Fprintf(out, "\t\tout.%s = in.%s[0]\n", protoFieldName, krmFieldName)
615+
} else {
616+
fmt.Fprintf(out, "\t\tout.%s = direct.ValueOf(in.%s[0])\n", protoFieldName, krmFieldName)
617+
}
618+
619+
default:
620+
klog.Fatalf("unhandled kind %q for field %v", protoField.Kind(), protoField)
621+
}
622+
fmt.Fprintf(out, "\t}\n")
623+
continue
624+
}
625+
626+
if isProtoFieldSlice && !isKRMFieldSlice && !protoField.IsMap() { // proto slice <- krm single
627+
var toProtoElemFunc string
628+
krmElemTypeName := strings.TrimPrefix(krmField.Type, "*")
629+
630+
var protoSliceElemType string
631+
632+
switch protoField.Kind() {
633+
case protoreflect.MessageKind:
634+
functionName := krmElemTypeName + versionSpecifier + "_ToProto"
635+
if _, ok := protoMessagesNotMappedToGoStruct[string(protoField.Message().FullName())]; ok {
636+
functionName = krmToProtoFunctionName(protoField, krmField.Name)
637+
}
638+
toProtoElemFunc = functionName
639+
protoSliceElemType = "*pb." + protoNameForType(protoField.Message())
640+
641+
case protoreflect.EnumKind:
642+
protoTypeName := v.goPackageForProto(protoField.Enum().ParentFile()) + "." + protoNameForEnum(protoField.Enum())
643+
toProtoElemFunc = fmt.Sprintf("direct.Enum_ToProto[%s]", protoTypeName)
644+
protoSliceElemType = "pb." + protoNameForEnum(protoField.Enum())
645+
646+
default:
647+
protoSliceElemType = goTypeForProtoKind(protoField.Kind())
648+
}
649+
650+
fmt.Fprintf(out, "\tif v := in.%s; v != nil {\n", krmFieldName)
651+
if toProtoElemFunc != "" {
652+
if protoField.Kind() == protoreflect.EnumKind {
653+
fmt.Fprintf(out, "\t\tout.%s = []%s{%s(mapCtx, *v)}\n", protoFieldName, protoSliceElemType, toProtoElemFunc)
654+
} else {
655+
fmt.Fprintf(out, "\t\tout.%s = []%s{%s(mapCtx, v)}\n", protoFieldName, protoSliceElemType, toProtoElemFunc)
656+
}
657+
} else {
658+
if protoField.Kind() == protoreflect.BytesKind {
659+
fmt.Fprintf(out, "\t\tout.%s = [][]byte{in.%s}\n", protoFieldName, krmFieldName)
660+
} else {
661+
fmt.Fprintf(out, "\t\tout.%s = []%s{direct.ValueOf(in.%s)}\n", protoFieldName, protoSliceElemType, krmFieldName)
662+
}
663+
}
664+
fmt.Fprintf(out, "\t}\n")
665+
continue
666+
}
667+
511668
if protoField.Cardinality() == protoreflect.Repeated {
512669
useSliceToProtoFunction := ""
513670
useCustomMethod := ""
@@ -780,16 +937,22 @@ func (v *MapperGenerator) writeMapFunctionsForPair(out io.Writer, srcDir string,
780937

781938
func protoNameForType(msg protoreflect.MessageDescriptor) string {
782939
fullName := string(msg.FullName())
783-
fullName = strings.TrimPrefix(fullName, string(msg.ParentFile().FullName()))
784-
fullName = strings.TrimPrefix(fullName, ".")
940+
namespace := string(msg.ParentFile().Package())
941+
if namespace != "" {
942+
namespace = namespace + "."
943+
}
944+
fullName = strings.TrimPrefix(fullName, namespace)
785945
fullName = strings.ReplaceAll(fullName, ".", "_")
786946
return fullName
787947
}
788948

789949
func protoNameForEnum(msg protoreflect.EnumDescriptor) string {
790950
fullName := string(msg.FullName())
791-
fullName = strings.TrimPrefix(fullName, string(msg.ParentFile().FullName()))
792-
fullName = strings.TrimPrefix(fullName, ".")
951+
namespace := string(msg.ParentFile().Package())
952+
if namespace != "" {
953+
namespace = namespace + "."
954+
}
955+
fullName = strings.TrimPrefix(fullName, namespace)
793956
fullName = strings.ReplaceAll(fullName, ".", "_")
794957
return fullName
795958
}

pkg/controller/direct/run/job_mapper.go

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)