How serialized protobuf text format looks like? - protocol-buffers

Given the following proto file
syntax = "proto3";
package tutorial;
message MyMessage {
string my_value = 1;
}
How the corresponding serialized text file should look like?
my_value : "abc"
or
MyMessage {
my_value : "abc"
}

Neither. There are two data formats found in protobuf; the more common is the binary protobuf format; the second (and rarer) is an opinionated JSON variant. So; if we assume that you're talking about the JSON version, we would expect valid JSON (note that I'm not accounting for whitespace here) similar to:
{
"my_value" : "abc"
}

Related

How to convert Ruby protobuf Message to JSON while preserving the case used in the proto?

When you convert a Protobuf Message in Ruby to JSON using to_json it converts all fieldnames to camelCase.
e.g. with protobuf message Person as
message Person {
string name = 1;
int32 id = 2;
string email_address = 3;
and Person in Ruby as
person = Person.new(:name => "Bob",
:id => 1,
:email_address => "foo#bar.com")
Serialized to JSON
person.to_json
>>> {"name":"Bob","id":"1","emailAddress":"foo#bar.com"}
the field email_address gets serialized in camelCase instead of snake case as it is in the proto
How can you serialize it with the original proto fieldnames?
I tried converting it to a Ruby Hash (with .to_h) at first since it preserves field names, but ran into a different issue. Fields with double values will be rendered as a Hash like price: {"value": 10.0"} instead of price: 10.0.
Buried deep in the source code is the answer.
There is an option in to_json to preserve the case used in the proto by passing in preserve_proto_fieldnames: true
e.g. person.to_json({preserve_proto_fieldnames: true})
Unfortunately this doesn't seem to be elsewhere in the Ruby protobuf documentation

regex as protobuf message field name?

can we define regular expression in protobuf field name? I send the request as list of dictinary in client.py file
"cur_cur_bin" : [{"cur_cur_bin1_bin3_bin1" : 4,"cur_cur_bin3_bin5_bin8" : 6} ]
I defined .proto file like,
int32 cur_cur_bin1_bin3_bin1 = 1;
}
message Message{
repeated cur_cur_BIN cur_cur_bin = 1;
}```
any one can explain how to define this type of field in .proto file dynamically. because
(bin1) having some range like (1 - [1-8]) same for (bin3) like (3 -[8-11]) like this.
No, as far as I know there is no mechanism to generate field names automatically or dynamically in protoc.
You can create messages dynamically through the python-protobuf reflection API, but that probably doesn't make sense for your usecase.
Instead define a reasonable .proto format, and then write some custom Python code to convert your JSON data to that.

Looking into weird protocol-buffer message (decoding and encoding)

I'm trying to figure out, is there a way to create a .proto definition, which could create and decode a message that looks like this:
parent_field {
carrier_field { (field id: 1)
subfield_1: 10 (field id: 1)
subfield_2: 20 (field id: 2)
}
carrier_field: "string" (field id: 1)
}
which means that under same field identifier I can get either sub message or a string.
I tried something like:
message MessageWrapper {
message ParentField {
message SubMessage {
....
}
repeated SubMessage carrier_field = 1
}
ParentField parent_field = 1
}
but when I try to decode the message I get:
# protoc --experimental_allow_proto3_optional --decode MessageWrapper proto_definitions/test.proto < test.buff
Failed to parse input.
How should the .proto definition look like to be able to decode and encode a message showed above?
The only way of doing that would be for carrier_field to be a bytes field that you would then separately decode as either a string or a protobuf message. Frankly, I'd advise against this: it would be better to use a oneof with different field numbers.

How do I make protobuf case-insensitive?

I have a protobuf contract like this,
message Car{
string carId = 1;
}
I generate java classes from this contract and use it to parse JSON request.
Now if my JSON has "CarID" or "carid" then protobuf generated java classes don't recognize that field. How do I make it case-insensitive?
The protobuff descriptor (.proto) are case insensitive. If you try to compile:
message Car{
string carId = 1;
string carid =2;
}
You will have the compilation error:
CARID_FIELD_NUMBER is already defined in ...
Also you have to know that for proto3, the JSON parser are dealing with lowerCamelCase. As stated on reference guide:
https://developers.google.com/protocol-buffers/docs/proto3#json
Use proto field name instead of lowerCamelCase name: By default proto3
JSON printer should convert the field name to lowerCamelCase and use
that as the JSON name. An implementation may provide an option to use
proto field name as the JSON name instead. Proto3 JSON parsers are
required to accept both the converted lowerCamelCase name and the
proto field name.
From your parser point of view "carID" and "CarID" are the same, because it will automatically convert "CarID" to "carID". But "carId" and "carid" will always be different.

Could protobuf read text file which has no schema but just data?

For example, the proto file is like this.
message {
required int key = 1;
repeated int value = 2;
}
The text file is like this where the first column indicates key while the others indicates the repeated value.
3391 [ 4847 3948 4849 ]
9483 [ 4938 48497 71 ]
...
Could protobuf read and parse this text file?
No, protobuf has no support for custom text formats.
You'll have to write custom parser code for it, which can then convert to protobuf or whatever other representation you might want.

Resources