Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define dictionary in protocol buffer

I'm new to both protocol buffers and C++, so this may be a basic question, but I haven't had any luck finding answers. Basically, I want the functionality of a dictionary defined in my .proto file like an enum. I'm using the protocol buffer to send data, and I want to define units and their respective names. An enum would allow me to define the units, but I don't know how to map the human-readable strings to that.

As an example of what I mean, the .proto file might look something like:

message DataPack {
    // obviously not valid, but something like this
    dict UnitType {
        KmPerHour = "km/h";
        MiPerHour = "mph";
    }

    required int id = 1;
    repeated DataPoint pt = 2;

    message DataPoint {
        required int id = 1;
        required int value = 2;
        optional UnitType theunit = 3;
    }
}

and then have something like to create / handle messages:

// construct
DataPack pack;
pack->set_id(123);
DataPack::DataPoint pt = pack.add_point();
pt->set_id(456);
pt->set_value(789);
pt->set_unit(DataPack::UnitType::KmPerHour);

// read values
DataPack::UnitType theunit = pt.unit();
cout << theunit.name << endl; // print "km/h"

I could just define an enum with the unit names and write a function to map them to strings on the receiving end, but it would make more sense to have them defined in the same spot, and that solution seems too complicated (at least, for someone who has lately been spoiled by the conveniences of Python). Is there an easier way to accomplish this?

like image 544
user812786 Avatar asked Jul 13 '12 16:07

user812786


2 Answers

You could use custom options to associate a string with each enum member: https://developers.google.com/protocol-buffers/docs/proto#options

It would look like this in the .proto:

extend google.protobuf.FieldOptions {
  optional string name = 12345;
}

enum UnitType {
    KmPerHour = 1 [(name) = "km/h"];
    MiPerHour = 2 [(name) = "mph"];
}

Beware, though, that some third-party protobuf libraries don't understand these options.

like image 130
jpa Avatar answered Sep 20 '22 16:09

jpa


In proto3, it's:

extend google.protobuf.EnumValueOptions {
  string name = 12345;
}

enum UnitType {
  KM_PER_HOUR = 0 [(name) = "km/h"];
  MI_PER_HOUR = 1 [(name) = "mph"];
}

and to access it in Java:

UnitType.KM_PER_HOUR.getValueDescriptor().getOptions().getExtension(MyOuterClass.name);
like image 38
Noel Yap Avatar answered Sep 22 '22 16:09

Noel Yap