@@ -221,7 +221,6 @@ func (v *MapperGenerator) GenerateMappers(goImports map[string]string) error {
221221
222222 return nil
223223}
224-
225224func (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 , "\t if len(in.%s) > 0 {\n " , protoAccessor )
335+ if fromProtoElemFunc != "" {
336+ fmt .Fprintf (out , "\t \t out.%s = %s(mapCtx, in.%s[0])\n " , krmFieldName , fromProtoElemFunc , protoAccessor )
337+ } else {
338+ if protoField .Kind () == protoreflect .BytesKind {
339+ fmt .Fprintf (out , "\t \t out.%s = in.%s[0]\n " , krmFieldName , protoAccessor )
340+ } else {
341+ fmt .Fprintf (out , "\t \t out.%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 , "\t if v := in.%s; v != nil {\n " , protoAccessor )
359+ if strings .HasPrefix (krmSliceElemType , "*" ) {
360+ fmt .Fprintf (out , "\t \t out.%s = []*%s.%s{%s(mapCtx, v)}\n " , krmFieldName , krmImportName , strings .TrimPrefix (krmSliceElemType , "*" ), functionName )
361+ } else {
362+ fmt .Fprintf (out , "\t \t out.%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 , "\t out.%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 , "\t if v := in.%s; v != nil {\n " , protoFieldName )
382+ fmt .Fprintf (out , "\t \t out.%s = []%s.%s{v}\n " , krmFieldName , krmImportName , krmSliceElemType )
383+ fmt .Fprintf (out , "\t }\n " )
384+ } else {
385+ fmt .Fprintf (out , "\t out.%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 , "\t out.%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 , "\t out.%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 , "\t if in.%s != nil {\n " , krmFieldRef .Name )
477- fmt .Fprintf (out , "\t \t out.%v = in.%v .External\n " , protoFieldName , krmFieldRef .Name )
547+ fmt .Fprintf (out , "\t \t out.%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 , "\t if 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 \t out.%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 \t out.%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 \t out.%s = in.%s[0]\n " , protoFieldName , krmFieldName )
615+ } else {
616+ fmt .Fprintf (out , "\t \t out.%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 , "\t if v := in.%s; v != nil {\n " , krmFieldName )
651+ if toProtoElemFunc != "" {
652+ if protoField .Kind () == protoreflect .EnumKind {
653+ fmt .Fprintf (out , "\t \t out.%s = []%s{%s(mapCtx, *v)}\n " , protoFieldName , protoSliceElemType , toProtoElemFunc )
654+ } else {
655+ fmt .Fprintf (out , "\t \t out.%s = []%s{%s(mapCtx, v)}\n " , protoFieldName , protoSliceElemType , toProtoElemFunc )
656+ }
657+ } else {
658+ if protoField .Kind () == protoreflect .BytesKind {
659+ fmt .Fprintf (out , "\t \t out.%s = [][]byte{in.%s}\n " , protoFieldName , krmFieldName )
660+ } else {
661+ fmt .Fprintf (out , "\t \t out.%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
781938func 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
789949func 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}
0 commit comments