protobuf: Support zero-copy encode/decode

We can do better with our encode/decode passes by taking better
advantage of the various APIs expose through CodedInputStream
and CodedOutputStream to support fewer copies for a number of
different buffer types, including java.nio.ByteBuffer and the
protobuf ByteString wrapper.

During encode we no longer recursively encode a nested object into
a temporary ByteString and append it to our own buffer, but instead
compute its size via the same logic as sizeof(), and then do the
encoding of the data.  Most nested messages will be fairly small
and thus quite easy to compute their nested size, so avoiding the
copy will improve encoding performance.

Also cleaned up the way sizeof generates, so decompiled code is
read correctly as "i += sz" rather than "i = sz + i".

Also fixed the decode function so that the input ByteBuffer is
correctly positioned at the end with no remaining input if we have
consumed everything in the stream.

Change-Id: Ie308c071c4302c55938a2e3cb014433d0c34e7aa
Signed-off-by: Shawn O. Pearce <sop@google.com>
6 files changed