in dev/tools/proto-to-mapper/main.go [357:681]
func (v *visitor) writeMapFunctionsForPair(out io.Writer, pair *typePair) {
msg := pair.Proto
pbTypeName := protoNameForType(msg)
goType := pair.KRMType
goTypeName := goType.Name
goFields := make(map[string]*gocode.StructField)
for _, f := range goType.Fields {
goFields[f.Name] = f
}
{
fmt.Fprintf(out, "func %s_FromProto(mapCtx *direct.MapContext, in *pb.%s) *krm.%s {\n", goTypeName, pbTypeName, goTypeName)
fmt.Fprintf(out, "\tif in == nil {\n")
fmt.Fprintf(out, "\t\treturn nil\n")
fmt.Fprintf(out, "\t}\n")
fmt.Fprintf(out, "\tout := &krm.%s{}\n", goTypeName)
for i := 0; i < msg.Fields().Len(); i++ {
protoField := msg.Fields().Get(i)
protoFieldName := strings.Title(protoField.JSONName())
protoAccessor := "Get" + protoFieldName + "()"
krmFieldName := strings.Title(protoField.JSONName())
krmField := goFields[krmFieldName]
if krmField == nil {
fmt.Fprintf(out, "\t// MISSING: %s\n", krmFieldName)
continue
}
if protoField.Cardinality() == protoreflect.Repeated {
useSliceFromProtoFunction := ""
useCustomMethod := false
switch protoField.Kind() {
case protoreflect.MessageKind:
krmElemTypeName := krmField.Type
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "*")
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "[]")
functionName := krmElemTypeName + "_FromProto"
useSliceFromProtoFunction = functionName
case protoreflect.StringKind:
if krmField.Type != "[]string" {
useCustomMethod = true
// useSliceFromProtoFunction = fmt.Sprintf("%s_%s_FromProto", goTypeName, protoFieldName)
}
case protoreflect.EnumKind:
krmElemTypeName := krmField.Type
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "*")
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "[]")
functionName := "Enum_FromProto"
useSliceFromProtoFunction = fmt.Sprintf("%s(mapCtx, in.%s)",
functionName,
krmFieldName,
)
case
protoreflect.FloatKind,
protoreflect.DoubleKind,
protoreflect.BoolKind,
protoreflect.Int64Kind,
protoreflect.Int32Kind,
protoreflect.Uint32Kind,
protoreflect.Uint64Kind,
protoreflect.BytesKind:
useSliceFromProtoFunction = ""
default:
klog.Fatalf("unhandled kind %q for repeated field %v", protoField.Kind(), protoField)
}
if useSliceFromProtoFunction != "" {
fmt.Fprintf(out, "\tout.%s = Slice_FromProto(mapCtx, in.%s, %s)\n",
krmFieldName,
krmFieldName,
useSliceFromProtoFunction,
)
} else if useCustomMethod {
methodName := fmt.Sprintf("%s_%s_FromProto", goTypeName, protoFieldName)
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
krmFieldName,
methodName,
krmFieldName,
)
} else {
fmt.Fprintf(out, "\tout.%s = in.%s\n",
krmFieldName,
krmFieldName,
)
}
continue
}
switch protoField.Kind() {
case protoreflect.MessageKind:
krmTypeName := krmField.Type
krmTypeName = strings.TrimPrefix(krmTypeName, "*")
functionName := krmTypeName + "_FromProto"
switch krmTypeName {
case "string":
functionName = string(msg.Name()) + "_" + krmFieldName + "_FromProto"
}
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
krmFieldName,
functionName,
protoAccessor,
)
case protoreflect.EnumKind:
functionName := "Enum_FromProto"
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
krmFieldName,
functionName,
krmFieldName,
)
case protoreflect.StringKind,
protoreflect.FloatKind,
protoreflect.DoubleKind,
protoreflect.BoolKind,
protoreflect.Int64Kind,
protoreflect.Int32Kind,
protoreflect.Uint32Kind,
protoreflect.Uint64Kind,
protoreflect.Fixed64Kind,
protoreflect.BytesKind:
fmt.Fprintf(out, "\tout.%s = LazyPtr(in.%s)\n",
krmFieldName,
protoAccessor,
)
default:
klog.Fatalf("unhandled kind %q for field %v", protoField.Kind(), protoField)
}
}
fmt.Fprintf(out, "\treturn out\n")
fmt.Fprintf(out, "}\n")
}
{
fmt.Fprintf(out, "func %s_ToProto(mapCtx *MapContext, in *krm.%s) *pb.%s {\n", goTypeName, goTypeName, pbTypeName)
fmt.Fprintf(out, "\tif in == nil {\n")
fmt.Fprintf(out, "\t\treturn nil\n")
fmt.Fprintf(out, "\t}\n")
fmt.Fprintf(out, "\tout := &pb.%s{}\n", pbTypeName)
for i := 0; i < msg.Fields().Len(); i++ {
protoField := msg.Fields().Get(i)
krmFieldName := strings.Title(protoField.JSONName())
krmField := goFields[krmFieldName]
if krmField == nil {
fmt.Fprintf(out, "\t// MISSING: %s\n", krmFieldName)
continue
}
protoFieldName := strings.Title(protoField.JSONName())
if protoField.Cardinality() == protoreflect.Repeated {
useSliceToProtoFunction := ""
useCustomMethod := false
switch protoField.Kind() {
case protoreflect.MessageKind:
krmElemTypeName := krmField.Type
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "*")
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "[]")
functionName := krmElemTypeName + "_ToProto"
useSliceToProtoFunction = functionName
case protoreflect.StringKind:
if krmField.Type != "[]string" {
useCustomMethod = true
//useSliceToProtoFunction = fmt.Sprintf("%s_%s_ToProto", goTypeName, protoFieldName)
}
case protoreflect.EnumKind:
krmElemTypeName := krmField.Type
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "*")
krmElemTypeName = strings.TrimPrefix(krmElemTypeName, "[]")
protoTypeName := "pb." + protoNameForEnum(protoField.Enum())
functionName := "Enum_ToProto"
useSliceToProtoFunction = fmt.Sprintf("%s[%s](mapCtx, in.%s)",
functionName,
protoTypeName,
krmFieldName,
)
case protoreflect.FloatKind,
protoreflect.DoubleKind,
protoreflect.BoolKind,
protoreflect.Int64Kind,
protoreflect.Int32Kind,
protoreflect.Uint32Kind,
protoreflect.Uint64Kind,
protoreflect.BytesKind:
useSliceToProtoFunction = ""
default:
klog.Fatalf("unhandled kind %q for repeated field %v", protoField.Kind(), protoField)
}
if useSliceToProtoFunction != "" {
fmt.Fprintf(out, "\tout.%s = Slice_ToProto(mapCtx, in.%s, %s)\n",
protoFieldName,
krmFieldName,
useSliceToProtoFunction,
)
} else if useCustomMethod {
methodName := fmt.Sprintf("%s_%s_ToProto", goTypeName, protoFieldName)
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
krmFieldName,
methodName,
krmFieldName,
)
} else {
fmt.Fprintf(out, "\tout.%s = in.%s\n",
protoFieldName,
krmFieldName,
)
}
continue
}
switch protoField.Kind() {
case protoreflect.MessageKind:
krmTypeName := krmField.Type
krmTypeName = strings.TrimPrefix(krmTypeName, "*")
functionName := krmTypeName + "_ToProto"
switch krmTypeName {
case "string":
// functionName = "String_" + string(protoField.Message().Name()) + "_ToProto"
functionName = string(msg.Name()) + "_" + krmFieldName + "_ToProto"
}
oneof := protoField.ContainingOneof()
if oneof != nil {
fmt.Fprintf(out, "\tif oneof := %s(mapCtx, in.%s); oneof != nil {\n",
functionName,
krmFieldName,
)
oneofFieldName := ToGoFieldName(oneof.Name())
oneofTypeName := protoNameForOneOf(protoField)
fmt.Fprintf(out, "\t\tout.%s = &pb.%s{%s: oneof}\n",
oneofFieldName,
oneofTypeName,
protoFieldName)
fmt.Fprintf(out, "\t}\n")
continue
}
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
protoFieldName,
functionName,
krmFieldName,
)
case protoreflect.EnumKind:
protoTypeName := "pb." + protoNameForEnum(protoField.Enum())
functionName := "Enum_ToProto"
fmt.Fprintf(out, "\tout.%s = %s[%s](mapCtx, in.%s)\n",
protoFieldName,
functionName,
protoTypeName,
krmFieldName,
)
case protoreflect.StringKind,
protoreflect.FloatKind,
protoreflect.DoubleKind,
protoreflect.BoolKind,
protoreflect.Int64Kind,
protoreflect.Int32Kind,
protoreflect.Uint32Kind,
protoreflect.Uint64Kind,
protoreflect.Fixed64Kind,
protoreflect.BytesKind:
useCustomMethod := false
switch protoField.Kind() {
case protoreflect.StringKind:
if krmField.Type != "*string" {
useCustomMethod = true
}
}
oneof := protoField.ContainingOneof()
if oneof != nil {
functionName := fmt.Sprintf("%s_%s_ToProto", goTypeName, protoFieldName)
fmt.Fprintf(out, "\tif oneof := %s(mapCtx, in.%s); oneof != nil {\n",
functionName,
krmFieldName,
)
oneofFieldName := ToGoFieldName(oneof.Name())
fmt.Fprintf(out, "\t\tout.%s = oneof\n",
oneofFieldName)
fmt.Fprintf(out, "\t}\n")
} else if useCustomMethod {
methodName := fmt.Sprintf("%s_%s_ToProto", goTypeName, protoFieldName)
fmt.Fprintf(out, "\tout.%s = %s(mapCtx, in.%s)\n",
krmFieldName,
methodName,
krmFieldName,
)
} else {
fmt.Fprintf(out, "\tout.%s = direct.ValueOf(in.%s)\n",
protoFieldName,
krmFieldName,
)
}
default:
klog.Fatalf("unhandled kind %q for field %v", protoField.Kind(), protoField)
}
}
fmt.Fprintf(out, "\treturn out\n")
fmt.Fprintf(out, "}\n")
}
}