-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
What steps will reproduce the problem?
1. Create a proto and add unknown fields (using UnknownFieldSet.Builder) to it
with wire type fixed32 or fixed64
2. Serialize the proto to JSON using JsonFormat.printToString()
3. Inspect the output string
What is the expected output? What do you see instead?
The output will contain:
"9000": [0x00002328], "9001": [0x0000000000002329]
In this case, there is an unknown fixed32 field with tag 9000 and value 9000 (=
0x2328), and an unknown fixed64 field with tag 9001 and value 9001 (= 0x2329).
However, this output is not valid JSON. Numbers in JSON can only be represented
in decimal form.
If we attempt to parse this output using another JSON library (such as GSON),
it may fail outright due to the bad syntax, but even if it is lenient enough to
perform the conversion, there may not be a way to determine whether the value
in the input stream was "0x" + 8 digits or "0x" + 16 digits. In such a case,
there would be no way to determine which wire type was originally used to store
the value (fixed32 or fixed64), which means we can't reconstruct the proto in a
way that would allow us to reserialize it in binary form without loss.
There are important use cases for representing unknown fields losslessly. For
example a server may hand an object to a client that only knows about an older
version of the proto. Then the client may update some fields it knows about,
and hand the object back to the server. Fields of the proto that are unknown to
the client should not be disturbed. The ability to handle this kind of scenario
seamlessly, without the need to synchronously update all consumers of a proto
definition, is a key advantage of protocol buffers.
In effect, serialization of unknown fields is only lossless when they will be
read by another instance of protobuf-java-format. This negates the value of
using a standard format like JSON. Instead, the values should be encoded in
such a way that only standard JSON constructs are used, and the wire type is
preserved, for example:
"9000":[{"fixed32":9000},{"fixed64":9001}]
What version of the product are you using? On what operating system?
1.2.
Original issue reported on code.google.com by r...@squareup.com on 1 Aug 2013 at 11:54