Skip to content

Instantly share code, notes, and snippets.

@javad87
Forked from zz85/animals.proto
Created November 3, 2023 21:03
Show Gist options
  • Save javad87/6749d8b735d935621c723e6619d2589c to your computer and use it in GitHub Desktop.
Save javad87/6749d8b735d935621c723e6619d2589c to your computer and use it in GitHub Desktop.
Java Protobuf Any vs Oneof
message Dog {
}
message Cat {
}
message Elephant {
}
message AnyAnimal {
google.protobuf.Any animal = 1;
}
message OneAnimal {
oneof animal {
Dog dog = 1;
Cat cat = 2;
Elephant elephant = 3;
}
}
class Serde {
static {
// Any Animal Serialization
AnyAnimal anyDogAnimal = AnyAnimal.newBuilder().setAnimal(
Any.pack(Dog.newBuilder().build())
).build();
AnyAnimal anyCatAnimal = AnyAnimal.newBuilder().setAnimal(
Any.pack(Cat.newBuilder().build())
).build();
// One Animal Serialization
OneAnimal oneAnimalDog = OneAnimal.newBuilder().setDog(Dog.newBuilder().build()).build();
OneAnimal oneAnimalCat = OneAnimal.newBuilder().setCat(Cat.newBuilder().build()).build();
// Any Animal Deserialization
Any anAnimal = anyDogAnimal.getAnimal();
GeneratedMessageV3 output1 = Stream.of(Dog.class, Cat.class, Elephant.class)
.filter(klass -> anAnimal.is(klass))
.map(klass -> {
try {
return anAnimal.unpack(klass);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
return null;
})
.limit(1)
.reduce(null, (x, y) -> y);
if (output1 instanceof Dog) {
// ...
}
else if (output1 instanceof Cat) {
//
}
// One Animal deserialzation (switch)
OneAnimal.AnimalCase animalCase = oneAnimalDog.getAnimalCase();
switch (animalCase) {
case DOG: return oneAnimalDog.getDog();
case CAT: return oneAnimalDog.getCat();
case ELEPHANT:: return oneAnimalDog.getElephant();
case ANIMAL_NOT_SET: return null;
}
// One Animal serialization (by field descriptors)
Descriptors.OneofDescriptor field = oneAnimalCat.getDescriptorForType().getOneofs().stream()
.filter(oneofDescriptor -> oneofDescriptor.getName().equals("animal")).reduce(null, (x, y) -> y);
Descriptors.FieldDescriptor field2 = oneAnimalCat.getOneofFieldDescriptor(field);
Object object = oneAnimalCat.getField(field2);
if (object instanceof Cat) {
return (Cat) object;
}
else if (object instanceof Dog) {
return (Dog) object;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment