Reputation: 68
Having this proto3 schema on a PHP client and Python server:
service GetAnimalData{
rpc GetData (AnimalRequest) returns (AnimalData) {}
}
message AnimalRequest {
OneOfAnimal TypeAnimal = 1;
}
message AnimalData {
repeated int32 data = 1;
}
message OneOfAnimal {
oneof animal_oneof {
CAT cat = 1;
DOG dog = 2;
}
}
message CAT{
int32 p = 1;
int32 d = 2;
int32 q = 3;
}
message DOG{
int32 p = 1;
int32 d = 2;
int32 q = 3;
int32 p2 = 4;
int32 d2 = 5;
int32 q2 = 6;
}
In oder to set up a request from the PHP client, I need to do:
CAT
OneOfAnimal
as CAT
AnimalRequest.TypeAnimal
as OneOfAnimal
Is there a schema for proto3 where I can just set either a CAT
or DOG
object directly as my AnimalRequest.TypeAnimal
Upvotes: 1
Views: 3835
Reputation: 1062510
In general terms; no, not really.
In some very specific cases, the answer is "yes" - for example, protobuf-net (a "code-first" protobuf implementation in .NET) happens to implement inheritance in exactly this way, so you could use:
[ProtoContract]
public class AnimalRequest {
[ProtoMember(1)] public Animal Animal {get;set;}
}
[ProtoContract]
[ProtoInclude(1, typeof(Cat))]
[ProtoInclude(2, typeof(Dog))]
class Animal {} // acts identically to your OneOfAnimal message type
[ProtoContract]
class Cat {
[ProtoMember(1)] public int P {get;set;}
[ProtoMember(2)] public int D {get;set;}
[ProtoMember(3)] public int Q {get;set;}
}
[ProtoContract]
class Dog {
[ProtoMember(1)] public int P {get;set;}
[ProtoMember(2)] public int D {get;set;}
[ProtoMember(3)] public int Q {get;set;}
[ProtoMember(4)] public int P2 {get;set;}
[ProtoMember(5)] public int D2 {get;set;}
[ProtoMember(6)] public int Q2 {get;set;}
}
and then you use:
var result = svc.GetData(
new AnimalRequest { Animal = new Dog { P = 42, ... Q2 = 19 } }
);
and it would work exactly the same way - the same bytes would be sent; essentially, protobuf-net treats inheritance as oneof
(at each level in the type hierarchy).
But: because .proto
is intended to work in a very generic "least common denominator" way, .proto
itself has no concept of inheritance, so: you can't do this from .proto
or the Google libraries.
Upvotes: 4