I have tried converting proto to java pojo . But got the error
[Stderr] Order.proto:12:18: Expected "required", "optional", or "repeated".
[Stderr] Order.proto:12:21: Expected field name.
optional int32 orderID = 1;
optional int32 quantity = 2;
map<string,string> map_field = 4;
repeated string product = 3;
Please help me what needs to be changed. i searched on google protobuf developer site
https://developers.google.com/protocol-buffers/docs/proto#maps
It says that Map fields cannot be repeated, optional, or required
Please help me to resolve the issue.
Maps are a new feature in protobuf 3.0 (aka "proto3"), which is still in alpha. You are probably using 2.x, in which case there are no maps. Your best bet is to use a repeated field:
repeated MyMap map_field = 4;
message MyMap {
optional string key = 1;
optional string value = 2;
}
Related
I am working on project where I am using nodejs and Proto3 for jobs. I have following proto3 file. where I want to add version as a field.
message Request {
string id = 1;
string body = 4;
string createdAt = 5;
string updatedAt = 6;
string traceId = 7;
}
I have an additional field version, when I was sending this field to it my system was giving error
Expect string provided number
So I modified it like this
message Request {
string id = 1;
string body = 4;
string createdAt = 5;
string updatedAt = 6;
string traceId = 7;
optional int32 version = 8;
}
Now I am getting reverse error that it expected integer and getting string. Althought I define here int32 which is integer in proto3.
I think it is about matching number in nodejs and int32 in proto3. I tried optional float version = 8; but still getting.
Here is complete error.
message="[rabbit] Request received"
version_$numberLong="1"
request.version: number expected" stack="Error: request.version: number expected\n
It is saying it expect number and client is sending number version_$numberLong="1". The project is a lot complicated with large files I just condense to show working code. Any solution how can I make them to work together.
I have reading Protobuf from Kaka so finally I'm getting a generated Java Object.
I would like to rename/create other Protobuf based on the original I got.
let say I have 2 classes A and B.
my code listen to Kafka topic and gets A.
I would like to "convert" A to B which is almost the same Object (few variable name changes).
is there any way to overwrite Protobuf Parser? in order to Generate B instead of A?
for example:
Class A{
String aa;
int aaaa;
}
Class B{
String bb;
int bbbb;
}
my Listener gets A and i would like to get B (bb=aa, bb=aaaa
Assuming A and B are compatible (same tags have the same type), you can serialize back your proto and parse it again.
This will also work if some tags are missing in one object, but parsing will mostly fail if two tags exists with the different types.
Proto:
Message A {
string aa = 1;
int32 aaaa = 2;
int32 a_only = 3;
}
Message B {
string bb = 1;
int32 bbbb = 2;
string b_only = 4; // Must not be 3.
}
Java:
A a = GetAFromQueue();
B b = B.parseFrom(a.toByteArray());
Another (probably better) option would be to get a the message from Kafka as a byte array and to parse it into a A or into a B as needed. This avoids re-serializing the data, though the same tags with different type issue is still relevant.
byte[] data = GetDataFromQueue();
A a = A.parseFrom(data);
[...]
B b = B.parseFrom(data);
I try to write my first *.proto file. This is my try:
syntax = "proto3";
package Message;
message Message {
string name = 1;
string serial = 2;
int32 command = 3;
enum Status {
GOOD = 0;
BAD = 1;
}
Status status = 4;
int32 length = 5;
// end of header
// start of payload
int32 data = 6;
string address = 7;
}
The header has the field length. This value defines the length of the data field in the payload. And that is my problem: The data field is dynamic, I can't know the size right now.
I could split the header and the payload in 2 separate *.proto files. But then still I don't know how to dynamically set the length of one of the fields.
Thanks in advance for the help!
Protocol buffer does not allow to check dependencies between fields. You have to check if the length matches the length of data yourself.
Boxing Conversion can be acheived by using as keyword
So I tried to perform boxing using as keyword.
So I tried the below example
Eg 1:-
int i = 12;
string a = i.ToString(); // Boxing Conversion
Console.WriteLine(a); //This works
Console.ReadKey();
Eg 2:-
var aa = i as object; // This works
var a = (i as string) // Compile time error
var a = (i as string).ToString(); // Compile time error
Can anyone explain why boxing can't be performed using as keyword for a string reference type?
1)
int i = 12;
string a = i.ToString();
ToString() is not a boxing conversion at all (and I'm not sure the term is quite right - boxing is just boxing). It is conversion to string. "a" is totally different object, not related to i anymore. It's type is string and value is "12", not 12.
2)
int i = 12;
var aa = i as object;
It is boxing, but aa still keeps object of int type.
var a = (i as string)
Here you are trying to convert int to string, which is impossible to do what way.
What you are trying to do here is usual in many languages, like JavaScript. But C# has very strong rules about type conversions. And most of the time, you cannot just cast type to string and back.
I'm wanting to parse a string into a nullable int list in C#
I'm able to convert it to int list bit not a nullable one
string data = "1,2";
List<int> TagIds = data.Split(',').Select(int.Parse).ToList();
say when data will be empty i want to handle that part!
Thanks
You can use following extension method:
public static int? TryGetInt32(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
Then it's simple:
List<int?> TagIds = data.Split(',')
.Select(s => s.TryGetInt32())
.ToList();
I use that extension method always in LINQ queries if the format can be invalid, it's better than using a local variable and int.TryParse (E. Lippert gave an example, follow link).
Apart from that it may be better to use data.Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries) instead which omits empty strings in the first place.