in cmd/go-to-protobuf/protobuf/generator.go [472:546]
func memberTypeToProtobufField(locator ProtobufLocator, field *protoField, t *types.Type) error {
var err error
switch t.Kind {
case types.Protobuf:
field.Type, err = locator.ProtoTypeFor(t)
case types.Builtin:
field.Type, err = locator.ProtoTypeFor(t)
case types.Map:
valueField := &protoField{}
if err := memberTypeToProtobufField(locator, valueField, t.Elem); err != nil {
return err
}
keyField := &protoField{}
if err := memberTypeToProtobufField(locator, keyField, t.Key); err != nil {
return err
}
// All other protobuf types have kind types.Protobuf, so setting types.Map
// here would be very misleading.
field.Type = &types.Type{
Kind: types.Protobuf,
Key: keyField.Type,
Elem: valueField.Type,
}
if !strings.HasPrefix(t.Name.Name, "map[") {
field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name))
}
if k, ok := keyField.Extras["(gogoproto.casttype)"]; ok {
field.Extras["(gogoproto.castkey)"] = k
}
if v, ok := valueField.Extras["(gogoproto.casttype)"]; ok {
field.Extras["(gogoproto.castvalue)"] = v
}
field.Map = true
case types.Pointer:
if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil {
return err
}
field.Nullable = true
case types.Alias:
if isOptionalAlias(t) {
field.Type, err = locator.ProtoTypeFor(t)
field.Nullable = true
} else {
if err := memberTypeToProtobufField(locator, field, t.Underlying); err != nil {
log.Printf("failed to alias: %s %s: err %v", t.Name, t.Underlying.Name, err)
return err
}
// If this is not an alias to a slice, cast to the alias
if !field.Repeated {
if field.Extras == nil {
field.Extras = make(map[string]string)
}
field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name))
}
}
case types.Slice:
if t.Elem.Name.Name == "byte" && len(t.Elem.Name.Package) == 0 {
field.Type = &types.Type{Name: types.Name{Name: "bytes"}, Kind: types.Protobuf}
return nil
}
if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil {
return err
}
field.Repeated = true
case types.Struct:
if len(t.Name.Name) == 0 {
return errUnrecognizedType
}
field.Type, err = locator.ProtoTypeFor(t)
field.Nullable = false
default:
return errUnrecognizedType
}
return err
}