Turns out there is a way to find out if a default value is actually missing or not (thanks to some friends at google for this answer):
message Record {
uint32 fileno = 1;
uint64 pos = 2;
uint64 bmsPos = 3;
oneof scanMode_present {
uint32 scanMode = 4;
}
uint32 version = 5; // set to >= 3 for protobuf 3
}
The generate code has additional methods to detect if oneof fields are set, using the getXXXcase() method:
int scanMode = proto.getScanMode();
boolean isMissing = proto.getScanModePresentCase() == Record.ScanModePresentCase.SCANMODEPRESENT_NOT_SET;
if (isMissing) {
boolean isProto3 = proto.getVersion() >= 3;
scanMode = (isProto3) ? 0 : 9999;
}
- Note that the name of the oneof is arbitrary, i have adopted the convention fieldname_present.
- The oneof doesnt add anything to the wire format, so it stays compatible with the proto-2 messages.
- You can add the version info anywhere that makes sense, i put it in the Record message for this example.
With this ‘trick’, i have upgraded to proto-3 with backwards compatibility with non-standard proto-2 default values.