jinganix / enif_protobuf

A Google Protobuf implementation with enif (Erlang nif)
38 stars 21 forks source link

Does not skip encoding "empty" fields #30

Closed Vagabond closed 2 years ago

Vagabond commented 2 years ago

Using the x.proto example file, converted to proto3:

syntax = "proto3";

message Person {
    string name = 1;
    int32 id = 2;
    string email = 3;
}

blank, default value fields still get encoded:

4> enif_protobuf:encode(#'Person'{}).
<<10,0,16,0,26,0>>
5> x:encode_msg(#'Person'{}).
<<>>

This is allowed by the spec, but it's not binary compatible with gpb or protoc

jinganix commented 2 years ago

Please refer to THIS

Vagabond commented 2 years ago

ok, but even using get_proto_defs:

2> rr(x_pb).
[field,gpb_oneof,libp2p_Person_pb,rpc]
3> x_pb:encode_msg(#'libp2p_Person_pb'{}).
<<>>

4> x_pb:get_proto_defs().
[{proto_defs_version,1},
 {file,{"x","x.proto"}},
 {{msg_containment,"x"},[libp2p_Person_pb]},
 {{enum_containment,"x"},[]},
 {syntax,"proto3"},
 {{msg,libp2p_Person_pb},
  [#field{name = name,fnum = 1,rnum = 2,type = string,
          occurrence = optional,opts = []},
   #field{name = id,fnum = 2,rnum = 3,type = int32,
          occurrence = optional,opts = []},
   #field{name = email,fnum = 3,rnum = 4,type = string,
          occurrence = optional,opts = []}]},
 {proto3_msgs,[libp2p_Person_pb]}]
5> enif_protobuf:load_cache(x_pb:get_proto_defs()).
ok
6> enif_protobuf:encode(#'libp2p_Person_pb'{}).
<<10,0,16,0,26,0>>
Vagabond commented 2 years ago

I seem unable to set proto_defs_version effectively using the rebar3 gpb plugin, is that the problem?

Vagabond commented 2 years ago

aha! the crucial gpb option is {introspect_proto_defs_version, 2}, not {proto_defs_version,2}

Vagabond commented 2 years ago

Ok, it works now, thanks!