Search code examples
protocol-buffersscalapb

How to generate protobuf Enum as String using ScalaPB?


I have the following in my Protobuf message:

enum SegmentType {
     UNKNOWN = 0;
     TYPE_1 = 1;
     TYPE_2 = 2;
     TYPE_3 = 3;
        }
optional SegmentType segment_type = 1 [default = UNKNOWN]

Instead of GeneratedEnum type, I would like to generate a string, with value as the particular type. For example

SegmentType: String = "TYPE_1"

This link explains how to map as a custom type, but it's not clear to me how to map as a value type. When I try the following, ScalaPB is showing error that it should be implemented in String companion class.

implicit val segmentType = TypeMapper[SegmentType, String](_.name)(SegmentType.fromName(_).get)

How can I achieve it? Also is there a way to transform all Enum types in a message as String ?


Solution

  • To get the implicit typemapper picked up by the compiler, you can put it in a package object for the same package SegmentType belongs to.

    Let's say your proto has a package statement like this:

    package a.b.c.d;
    

    Then in Scala:

    package a.b.c
    
    package object d {
      implicit val segmentType =
        TypeMapper[SegmentType, String](_.name)(SegmentType.fromName(_).get)
    }
    

    You can also have it in any parent package of a.b.c.d (such as a.b.c, a.b or a).

    To your second question, you can't make all enums be strings, but you can make all occurrences of a given enum type to be strings, so you don't have to specify the custom type for each field individually:

    enum SegmentType {
         option (scalapb.enum_options).type = "String";
         UNKNOWN = 0;
         TYPE_1 = 1;
         TYPE_2 = 2;
         TYPE_3 = 3;
    }
    
    message F {
      optional SegmentType segment_type = 1; // will be an Option[String]
    }