вообще говоря можно делать и через message-обертку, но вроде как правильнее делать через Oneof, пример на go можно поизучать тут. выбор типа сообщения - это строки
// Use a type switch to determine which oneof was set.
switch u := test.Union.(type) {
case *pb.Test_Number: // u.Number contains the number.
case *pb.Test_Name: // u.Name contains the string.
}