How do I make protobuf case-insensitive? - protocol-buffers

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.

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.

how we can parse proto file if it having "." and "-" sign

I create one proto file using java and another using python when I put "." and "-" sign in proto file message field name it shows error that is "missing field number". I m not able to parse that file. and if proto file not accept this character please can share list of character which proto file not accept.
Please find the protobuf documentation on proper syntax for defining messages in protos.
. is used for selecting an attribute of an object in python, so obviously one shouldn't use it in message fields of proto. Instead You can use _ as character for separating words in a single field name.
A small Sample for you :
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}

can .proto file fields be without values?

I received "missing field number" error. Is it possible to declare fields without value? since i do not have a default value to the fields.
syntax = "proto3";
package tutorial;
message Person {
required string name;
required string email;
}
The field number is not refer to a default value but each field in the message definition has a unique number. These numbers are used to identify your fields in the message binary format, and should not be changed once your message type is in use.
More info here in the doc

Go XML suppression of automatically generated tags?

I'm trying to implement an XML format under Go that was originally written in Fortran. The format is already specified so I'm not free to make changes to the standard. Unfortunately, the format includes data that is not enclosed by an XML tag, thus I would like to suppress the automatic tag creation provided by xml.Marshal.
I've investigated all the standard option associated with marshalling,as documented at : https://golang.org/pkg/encoding/xml/
By default marshalling will use the structure variable name, which can be overridden by the xml: definition. As far as I can tell there is no definition that suppresses the tag name.
type SAO_FREQUENCY_LIST struct {
Type string `xml:",attr"`
SigFig int `xml:",attr"`
Units string `xml:",attr"`
Description string `xml:",attr"`
Frequencies string `xml:""`
}
I want the XML output to be as follows:
<FrequencyList Type="float" SigFig="5" Units="MHz" Description="Nominal Frequency">
3.7 3.8
</FrequencyList>"
By default xml.MarshalIndent(..) yields:
<FrequencyList Type="float" SigFig="5" Units="MHz" Description="”Nominal Frequency">
<Frequencies>3.7 3.8</Frequencies>
</FrequencyList>
You can use the ,chardata modifier to indicate that the value of a struct member should be used as character data for the XML element. For your example, this would be:
type FrequencyList struct {
...
Frequencies string `xml:",chardata"`
}
You can experiment with an example using this change here: https://play.golang.org/p/oBa8HuE-57d

Resources