164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Protocol Buffers - Google's data interchange format 264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Copyright 2013 Google Inc. All rights reserved. 364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// http://code.google.com/p/protobuf/ 464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Redistribution and use in source and binary forms, with or without 664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// modification, are permitted provided that the following conditions are 764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// met: 864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Redistributions of source code must retain the above copyright 1064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// notice, this list of conditions and the following disclaimer. 1164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Redistributions in binary form must reproduce the above 1264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// copyright notice, this list of conditions and the following disclaimer 1364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// in the documentation and/or other materials provided with the 1464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// distribution. 1564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Neither the name of Google Inc. nor the names of its 1664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// contributors may be used to endorse or promote products derived from 1764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// this software without specific prior written permission. 1864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 1964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 3164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcipackage com.google.protobuf.nano; 3264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 3364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciimport java.io.IOException; 340e055f079f53b07de3705838a7b4742ce56839f8Brian Duffimport java.util.ArrayList; 350e055f079f53b07de3705838a7b4742ce56839f8Brian Duffimport java.util.Iterator; 360e055f079f53b07de3705838a7b4742ce56839f8Brian Duffimport java.util.List; 3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci/** 3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * This class is used internally by the Protocol Buffer library and generated 4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * message implementations. It is public only because those generated messages 4164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * do not reside in the {@code protobuf} package. Others should not use this 4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * class directly. 4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * 4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * This class contains constants and helper functions useful for dealing with 4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * the Protocol Buffer wire format. 4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * 4764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * @author kenton@google.com Kenton Varda 4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci */ 4964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcipublic final class WireFormatNano { 5064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Do not allow instantiation. 5164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci private WireFormatNano() {} 5264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 5364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_VARINT = 0; 5464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_FIXED64 = 1; 5564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_LENGTH_DELIMITED = 2; 5664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_START_GROUP = 3; 5764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_END_GROUP = 4; 5864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int WIRETYPE_FIXED32 = 5; 5964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 6064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int TAG_TYPE_BITS = 3; 6164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1; 6264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 6364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci /** Given a tag value, determines the wire type (the lower 3 bits). */ 6464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static int getTagWireType(final int tag) { 6564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return tag & TAG_TYPE_MASK; 6664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 6764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 6864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci /** Given a tag value, determines the field number (the upper 29 bits). */ 6964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static int getTagFieldNumber(final int tag) { 7064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return tag >>> TAG_TYPE_BITS; 7164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 7264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 7364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci /** Makes a tag value given a field number and wire type. */ 7464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static int makeTag(final int fieldNumber, final int wireType) { 7564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return (fieldNumber << TAG_TYPE_BITS) | wireType; 7664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 7764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 7864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Field numbers for feilds in MessageSet wire format. 7964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_ITEM = 1; 8064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_TYPE_ID = 2; 8164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_MESSAGE = 3; 8264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 8364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Tag numbers. 8464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_ITEM_TAG = 8564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP); 8664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_ITEM_END_TAG = 8764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP); 8864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_TYPE_ID_TAG = 8964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT); 9064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci static final int MESSAGE_SET_MESSAGE_TAG = 9164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED); 9264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 9364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final int EMPTY_INT_ARRAY[] = {}; 9464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final long EMPTY_LONG_ARRAY[] = {}; 9564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final float EMPTY_FLOAT_ARRAY[] = {}; 9664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final double EMPTY_DOUBLE_ARRAY[] = {}; 9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final boolean EMPTY_BOOLEAN_ARRAY[] = {}; 9864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final String EMPTY_STRING_ARRAY[] = {}; 9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final byte[] EMPTY_BYTES_ARRAY[] = {}; 10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final byte[] EMPTY_BYTES = {}; 10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci /** 1030e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Parses an unknown field. This implementation skips the field. 1040e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 1050e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * <p>Generated messages will call this for unknown fields if the store_unknown_fields 1060e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * option is off. 1070e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 1080e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @return {@literal true} unless the tag is an end-group tag. 10964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci */ 11064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static boolean parseUnknownField( 11164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci final CodedInputByteBufferNano input, 11264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci final int tag) throws IOException { 11364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return input.skipField(tag); 11464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 11564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 11664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci /** 1170e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Stores the binary data of an unknown field. 1180e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 1190e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * <p>Generated messages will call this for unknown fields if the store_unknown_fields 1200e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * option is on. 1210e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 1220e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @param data a Collection in which to store the data. 1230e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @param input the input buffer. 1240e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @param tag the tag of the field. 1250e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 1260e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @return {@literal true} unless the tag is an end-group tag. 1270e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 1280e055f079f53b07de3705838a7b4742ce56839f8Brian Duff public static boolean storeUnknownField( 1290e055f079f53b07de3705838a7b4742ce56839f8Brian Duff final List<UnknownFieldData> data, 1300e055f079f53b07de3705838a7b4742ce56839f8Brian Duff final CodedInputByteBufferNano input, 1310e055f079f53b07de3705838a7b4742ce56839f8Brian Duff final int tag) throws IOException { 1320e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int startPos = input.getPosition(); 1330e055f079f53b07de3705838a7b4742ce56839f8Brian Duff boolean skip = input.skipField(tag); 1340e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int endPos = input.getPosition(); 1350e055f079f53b07de3705838a7b4742ce56839f8Brian Duff byte[] bytes = input.getData(startPos, endPos - startPos); 1360e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data.add(new UnknownFieldData(tag, bytes)); 1370e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return skip; 1380e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1390e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 1400e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 14164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * Computes the array length of a repeated field. We assume that in the common case repeated 14264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * fields are contiguously serialized but we still correctly handle interspersed values of a 14364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * repeated field (but with extra allocations). 14464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * 14564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * Rewinds to current input position before returning. 14664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * 14764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * @param input stream input, pointing to the byte after the first tag 14864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * @param tag repeated field tag just read 14964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * @return length of array 15064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci * @throws IOException 15164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci */ 15264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci public static final int getRepeatedFieldArrayLength( 15364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci final CodedInputByteBufferNano input, 15464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci final int tag) throws IOException { 15564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci int arrayLength = 1; 15664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci int startPos = input.getPosition(); 15764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci input.skipField(tag); 15864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci while (input.getBytesUntilLimit() > 0) { 15964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci int thisTag = input.readTag(); 16064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (thisTag != tag) { 16164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci break; 16264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 16364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci input.skipField(tag); 16464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci arrayLength++; 16564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 16664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci input.rewindToPosition(startPos); 16764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return arrayLength; 16864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 1690e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 1700e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 1710e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Decodes the value of an extension. 1720e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 1730e055f079f53b07de3705838a7b4742ce56839f8Brian Duff public static <T> T getExtension(Extension<T> extension, List<UnknownFieldData> unknownFields) { 1740e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (unknownFields == null) { 1750e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return null; 1760e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1770e055f079f53b07de3705838a7b4742ce56839f8Brian Duff List<UnknownFieldData> dataForField = new ArrayList<UnknownFieldData>(); 1780e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (UnknownFieldData data : unknownFields) { 1790e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (getTagFieldNumber(data.tag) == extension.fieldNumber) { 1800e055f079f53b07de3705838a7b4742ce56839f8Brian Duff dataForField.add(data); 1810e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1820e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1830e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (dataForField.isEmpty()) { 1840e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return null; 1850e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1860e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 1870e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (extension.isRepeatedField) { 1880e055f079f53b07de3705838a7b4742ce56839f8Brian Duff List<Object> result = new ArrayList<Object>(dataForField.size()); 1890e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (UnknownFieldData data : dataForField) { 1900e055f079f53b07de3705838a7b4742ce56839f8Brian Duff result.add(readData(extension.fieldType, data.bytes)); 1910e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1920e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return extension.listType.cast(result); 1930e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 1940e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 1950e055f079f53b07de3705838a7b4742ce56839f8Brian Duff // Normal fields. Note that the protobuf docs require us to handle multiple instances 1960e055f079f53b07de3705838a7b4742ce56839f8Brian Duff // of the same field even for fields that are not repeated. 1970e055f079f53b07de3705838a7b4742ce56839f8Brian Duff UnknownFieldData lastData = dataForField.get(dataForField.size() - 1); 1980e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return readData(extension.fieldType, lastData.bytes); 1990e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2000e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 2010e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 2020e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Reads (extension) data of the specified type from the specified byte array. 2030e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 2040e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @throws IllegalArgumentException if an error occurs while reading the data. 2050e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 2060e055f079f53b07de3705838a7b4742ce56839f8Brian Duff private static <T> T readData(Class<T> clazz, byte[] data) { 2070e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (data.length == 0) { 2080e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return null; 2090e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2100e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedInputByteBufferNano buffer = CodedInputByteBufferNano.newInstance(data); 2110e055f079f53b07de3705838a7b4742ce56839f8Brian Duff try { 2120e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (clazz == String.class) { 2130e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readString()); 2140e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Integer.class) { 2150e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readInt32()); 2160e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Long.class) { 2170e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readInt64()); 2180e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Boolean.class) { 2190e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readBool()); 2200e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Float.class) { 2210e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readFloat()); 2220e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Double.class) { 2230e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readDouble()); 2240e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == byte[].class) { 2250e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(buffer.readBytes()); 2260e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (MessageNano.class.isAssignableFrom(clazz)) { 2270e055f079f53b07de3705838a7b4742ce56839f8Brian Duff try { 2280e055f079f53b07de3705838a7b4742ce56839f8Brian Duff MessageNano message = (MessageNano) clazz.newInstance(); 2290e055f079f53b07de3705838a7b4742ce56839f8Brian Duff buffer.readMessage(message); 2300e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return clazz.cast(message); 2310e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } catch (IllegalAccessException e) { 2320e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException("Error creating instance of class " + clazz, e); 2330e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } catch (InstantiationException e) { 2340e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException("Error creating instance of class " + clazz, e); 2350e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2360e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else { 2370e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException("Unhandled extension field type: " + clazz); 2380e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2390e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } catch (IOException e) { 2400e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException("Error reading extension field", e); 2410e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2420e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2430e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 2440e055f079f53b07de3705838a7b4742ce56839f8Brian Duff public static <T> void setExtension(Extension<T> extension, T value, 2450e055f079f53b07de3705838a7b4742ce56839f8Brian Duff List<UnknownFieldData> unknownFields) { 2460e055f079f53b07de3705838a7b4742ce56839f8Brian Duff // First, remove all unknown fields with this tag. 2470e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (Iterator<UnknownFieldData> i = unknownFields.iterator(); i.hasNext();) { 2480e055f079f53b07de3705838a7b4742ce56839f8Brian Duff UnknownFieldData data = i.next(); 2490e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (extension.fieldNumber == getTagFieldNumber(data.tag)) { 2500e055f079f53b07de3705838a7b4742ce56839f8Brian Duff i.remove(); 2510e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2520e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2530e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (value == null) { 2540e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return; 2550e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2560e055f079f53b07de3705838a7b4742ce56839f8Brian Duff // Repeated field. 2570e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (value instanceof List) { 2580e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (Object item : (List<?>) value) { 2590e055f079f53b07de3705838a7b4742ce56839f8Brian Duff unknownFields.add(write(extension.fieldNumber, item)); 2600e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2610e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else { 2620e055f079f53b07de3705838a7b4742ce56839f8Brian Duff unknownFields.add(write(extension.fieldNumber, value)); 2630e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2640e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 2650e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 2660e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 2670e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Writes extension data and returns an {@link UnknownFieldData} containing 2680e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * bytes and a tag. 2690e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * 2700e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * @throws IllegalArgumentException if an error occurs while writing. 2710e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 2720e055f079f53b07de3705838a7b4742ce56839f8Brian Duff private static UnknownFieldData write(int fieldNumber, Object object) { 2730e055f079f53b07de3705838a7b4742ce56839f8Brian Duff byte[] data; 2740e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int tag; 2750e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Class<?> clazz = object.getClass(); 2760e055f079f53b07de3705838a7b4742ce56839f8Brian Duff try { 2770e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (clazz == String.class) { 2780e055f079f53b07de3705838a7b4742ce56839f8Brian Duff String str = (String) object; 2790e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeStringSizeNoTag(str)]; 2800e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeStringNoTag(str); 2810e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 2820e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Integer.class) { 2830e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Integer integer = (Integer) object; 2840e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeInt32SizeNoTag(integer)]; 2850e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeInt32NoTag(integer); 2860e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_VARINT); 2870e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Long.class) { 2880e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Long longValue = (Long) object; 2890e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeInt64SizeNoTag(longValue)]; 2900e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeInt64NoTag(longValue); 2910e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_VARINT); 2920e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Boolean.class) { 2930e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Boolean boolValue = (Boolean) object; 2940e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeBoolSizeNoTag(boolValue)]; 2950e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeBoolNoTag(boolValue); 2960e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_VARINT); 2970e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Float.class) { 2980e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Float floatValue = (Float) object; 2990e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeFloatSizeNoTag(floatValue)]; 3000e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeFloatNoTag(floatValue); 3010e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_FIXED32); 3020e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == Double.class) { 3030e055f079f53b07de3705838a7b4742ce56839f8Brian Duff Double doubleValue = (Double) object; 3040e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeDoubleSizeNoTag(doubleValue)]; 3050e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeDoubleNoTag(doubleValue); 3060e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_FIXED64); 3070e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (clazz == byte[].class) { 3080e055f079f53b07de3705838a7b4742ce56839f8Brian Duff byte[] byteArrayValue = (byte[]) object; 3090e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[CodedOutputByteBufferNano.computeByteArraySizeNoTag(byteArrayValue)]; 3100e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano.newInstance(data).writeByteArrayNoTag(byteArrayValue); 3110e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 3120e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (MessageNano.class.isAssignableFrom(clazz)) { 3130e055f079f53b07de3705838a7b4742ce56839f8Brian Duff MessageNano messageValue = (MessageNano) object; 3140e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 3150e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int messageSize = messageValue.getSerializedSize(); 3160e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int delimiterSize = CodedOutputByteBufferNano.computeRawVarint32Size(messageSize); 3170e055f079f53b07de3705838a7b4742ce56839f8Brian Duff data = new byte[messageSize + delimiterSize]; 3180e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano buffer = CodedOutputByteBufferNano.newInstance(data); 3190e055f079f53b07de3705838a7b4742ce56839f8Brian Duff buffer.writeRawVarint32(messageSize); 3200e055f079f53b07de3705838a7b4742ce56839f8Brian Duff buffer.writeRawBytes(MessageNano.toByteArray(messageValue)); 3210e055f079f53b07de3705838a7b4742ce56839f8Brian Duff tag = makeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 3220e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else { 3230e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException("Unhandled extension field type: " + clazz); 3240e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3250e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } catch (IOException e) { 3260e055f079f53b07de3705838a7b4742ce56839f8Brian Duff throw new IllegalArgumentException(e); 3270e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3280e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return new UnknownFieldData(tag, data); 3290e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3300e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 3310e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 3320e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Given a set of unknown field data, compute the wire size. 3330e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 3340e055f079f53b07de3705838a7b4742ce56839f8Brian Duff public static int computeWireSize(List<UnknownFieldData> unknownFields) { 3350e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (unknownFields == null) { 3360e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return 0; 3370e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3380e055f079f53b07de3705838a7b4742ce56839f8Brian Duff int size = 0; 3390e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (UnknownFieldData unknownField : unknownFields) { 3400e055f079f53b07de3705838a7b4742ce56839f8Brian Duff size += CodedOutputByteBufferNano.computeRawVarint32Size(unknownField.tag); 3410e055f079f53b07de3705838a7b4742ce56839f8Brian Duff size += unknownField.bytes.length; 3420e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3430e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return size; 3440e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3450e055f079f53b07de3705838a7b4742ce56839f8Brian Duff 3460e055f079f53b07de3705838a7b4742ce56839f8Brian Duff /** 3470e055f079f53b07de3705838a7b4742ce56839f8Brian Duff * Write unknown fields. 3480e055f079f53b07de3705838a7b4742ce56839f8Brian Duff */ 3490e055f079f53b07de3705838a7b4742ce56839f8Brian Duff public static void writeUnknownFields(List<UnknownFieldData> unknownFields, 3500e055f079f53b07de3705838a7b4742ce56839f8Brian Duff CodedOutputByteBufferNano outBuffer) throws IOException { 3510e055f079f53b07de3705838a7b4742ce56839f8Brian Duff if (unknownFields == null) { 3520e055f079f53b07de3705838a7b4742ce56839f8Brian Duff return; 3530e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3540e055f079f53b07de3705838a7b4742ce56839f8Brian Duff for (UnknownFieldData data : unknownFields) { 3550e055f079f53b07de3705838a7b4742ce56839f8Brian Duff outBuffer.writeTag(getTagFieldNumber(data.tag), getTagWireType(data.tag)); 3560e055f079f53b07de3705838a7b4742ce56839f8Brian Duff outBuffer.writeRawBytes(data.bytes); 3570e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 3580e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } 35964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} 360