@ -30,85 +30,659 @@
package com.google.protobuf.nano ;
import java.lang.reflect.ParameterizedType ;
import java.lang.reflect.Type ;
import java.io.IOException ;
import java.lang.reflect.Array ;
import java.util.ArrayList ;
import java.util.List ;
/ * *
* Represents an extension .
*
* @author bduff @google.com ( Brian Duff )
* @param < T > the type of the extension .
* @author maxtroy @google.com ( Max Cai )
* @param < M > the type of the extendable message this extension is for .
* @param < T > the Java type of the extension ; see { @link # clazz } .
* /
public class Extension < T > {
public final int fieldNumber ;
public boolean isRepeatedField ;
public Class < T > fieldType ;
public Class < T > listType ;
private Extension ( int fieldNumber , TypeLiteral < T > type ) {
this . fieldNumber = fieldNumber ;
isRepeatedField = type . isList ( ) ;
fieldType = type . getTargetClass ( ) ;
listType = isRepeatedField ? type . getListType ( ) : null ;
}
/ * *
* Creates a new instance of { @code Extension } for the specified { @code fieldNumber } and
* { @code type } .
* /
public static < T > Extension < T > create ( int fieldNumber , TypeLiteral < T > type ) {
return new Extension < T > ( fieldNumber , type ) ;
}
/ * *
* Creates a new instance of { @code Extension } for the specified { @code fieldNumber } and
* { @code type } . This version is used for repeated fields .
* /
public static < T > Extension < List < T > > createRepeated ( int fieldNumber , TypeLiteral < List < T > > type ) {
return new Extension < List < T > > ( fieldNumber , type ) ;
}
/ * *
* Represents a generic type literal . We can ' t typesafely reference a
* Class & lt ; List & lt ; Foo > > . class in Java , so we use this instead .
* See : http : //gafter.blogspot.com/2006/12/super-type-tokens.html
*
* < p > Somewhat specialized because we only ever have a Foo or a List & lt ; Foo > .
* /
public static abstract class TypeLiteral < T > {
private final Type type ;
protected TypeLiteral ( ) {
Type superclass = getClass ( ) . getGenericSuperclass ( ) ;
if ( superclass instanceof Class ) {
throw new RuntimeException ( "Missing type parameter" ) ;
}
this . type = ( ( ParameterizedType ) superclass ) . getActualTypeArguments ( ) [ 0 ] ;
public class Extension < M extends ExtendableMessageNano < M > , T > {
/ *
* Because we typically only define message - typed extensions , the Extension class hierarchy is
* designed as follows , to allow a big amount of code in this file to be removed by ProGuard :
*
* Extension // ready to use for message/group typed extensions
* Δ
* |
* PrimitiveExtension // for primitive/enum typed extensions
* /
public static final int TYPE_DOUBLE = 1 ;
public static final int TYPE_FLOAT = 2 ;
public static final int TYPE_INT64 = 3 ;
public static final int TYPE_UINT64 = 4 ;
public static final int TYPE_INT32 = 5 ;
public static final int TYPE_FIXED64 = 6 ;
public static final int TYPE_FIXED32 = 7 ;
public static final int TYPE_BOOL = 8 ;
public static final int TYPE_STRING = 9 ;
public static final int TYPE_GROUP = 10 ;
public static final int TYPE_MESSAGE = 11 ;
public static final int TYPE_BYTES = 12 ;
public static final int TYPE_UINT32 = 13 ;
public static final int TYPE_ENUM = 14 ;
public static final int TYPE_SFIXED32 = 15 ;
public static final int TYPE_SFIXED64 = 16 ;
public static final int TYPE_SINT32 = 17 ;
public static final int TYPE_SINT64 = 18 ;
/ * *
* Creates an { @code Extension } of the given message type and tag number .
* Should be used by the generated code only .
*
* @param type { @link # TYPE_MESSAGE } or { @link # TYPE_GROUP }
* /
public static < M extends ExtendableMessageNano < M > , T extends MessageNano >
Extension < M , T > createMessageTyped ( int type , Class < T > clazz , int tag ) {
return new Extension < M , T > ( type , clazz , tag , false ) ;
}
/ * *
* Creates a repeated { @code Extension } of the given message type and tag number .
* Should be used by the generated code only .
*
* @param type { @link # TYPE_MESSAGE } or { @link # TYPE_GROUP }
* /
public static < M extends ExtendableMessageNano < M > , T extends MessageNano >
Extension < M , T [ ] > createRepeatedMessageTyped ( int type , Class < T [ ] > clazz , int tag ) {
return new Extension < M , T [ ] > ( type , clazz , tag , true ) ;
}
/ * *
* Creates an { @code Extension } of the given primitive type and tag number .
* Should be used by the generated code only .
*
* @param type one of { @code TYPE_ * } , except { @link # TYPE_MESSAGE } and { @link # TYPE_GROUP }
* @param clazz the boxed Java type of this extension
* /
public static < M extends ExtendableMessageNano < M > , T >
Extension < M , T > createPrimitiveTyped ( int type , Class < T > clazz , int tag ) {
return new PrimitiveExtension < M , T > ( type , clazz , tag , false , 0 , 0 ) ;
}
/ * *
* Creates a repeated { @code Extension } of the given primitive type and tag number .
* Should be used by the generated code only .
*
* @param type one of { @code TYPE_ * } , except { @link # TYPE_MESSAGE } and { @link # TYPE_GROUP }
* @param clazz the Java array type of this extension , with an unboxed component type
* /
public static < M extends ExtendableMessageNano < M > , T >
Extension < M , T > createRepeatedPrimitiveTyped (
int type , Class < T > clazz , int tag , int nonPackedTag , int packedTag ) {
return new PrimitiveExtension < M , T > ( type , clazz , tag , true , nonPackedTag , packedTag ) ;
}
/ * *
* Protocol Buffer type of this extension ; one of the { @code TYPE_ } constants .
* /
protected final int type ;
/ * *
* Java type of this extension . For a singular extension , this is the boxed Java type for the
* Protocol Buffer { @link # type } ; for a repeated extension , this is an array type whose
* component type is the unboxed Java type for { @link # type } . For example , for a singular
* { @code int32 } / { @link # TYPE_INT32 } extension , this equals { @code Integer . class } ; for a
* repeated { @code int32 } extension , this equals { @code int [ ] . class } .
* /
protected final Class < T > clazz ;
/ * *
* Tag number of this extension .
* /
protected final int tag ;
/ * *
* Whether this extension is repeated .
* /
protected final boolean repeated ;
private Extension ( int type , Class < T > clazz , int tag , boolean repeated ) {
this . type = type ;
this . clazz = clazz ;
this . tag = tag ;
this . repeated = repeated ;
}
protected boolean isMatch ( int unknownDataTag ) {
// This implementation is for message/group extensions.
return unknownDataTag = = tag ;
}
/ * *
* Returns the value of this extension stored in the given list of unknown fields , or
* { @code null } if no unknown fields matches this extension .
* /
final T getValueFrom ( List < UnknownFieldData > unknownFields ) {
if ( unknownFields = = null ) {
return null ;
}
if ( repeated ) {
// For repeated extensions, read all matching unknown fields in their original order.
List < Object > resultList = new ArrayList < Object > ( ) ;
for ( int i = 0 ; i < unknownFields . size ( ) ; i + + ) {
UnknownFieldData data = unknownFields . get ( i ) ;
if ( isMatch ( data . tag ) & & data . bytes . length ! = 0 ) {
readDataInto ( data , resultList ) ;
}
}
int resultSize = resultList . size ( ) ;
if ( resultSize = = 0 ) {
return null ;
}
T result = clazz . cast ( Array . newInstance ( clazz . getComponentType ( ) , resultSize ) ) ;
for ( int i = 0 ; i < resultSize ; i + + ) {
Array . set ( result , i , resultList . get ( i ) ) ;
}
return result ;
} else {
// For singular extensions, get the last piece of data stored under this extension.
UnknownFieldData lastData = null ;
for ( int i = unknownFields . size ( ) - 1 ; lastData = = null & & i > = 0 ; i - - ) {
UnknownFieldData data = unknownFields . get ( i ) ;
if ( isMatch ( data . tag ) & & data . bytes . length ! = 0 ) {
lastData = data ;
}
}
if ( lastData = = null ) {
return null ;
}
return clazz . cast ( readData ( CodedInputByteBufferNano . newInstance ( lastData . bytes ) ) ) ;
}
}
protected Object readData ( CodedInputByteBufferNano input ) {
// This implementation is for message/group extensions.
Class < ? > messageType = repeated ? clazz . getComponentType ( ) : clazz ;
try {
switch ( type ) {
case TYPE_GROUP :
MessageNano group = ( MessageNano ) messageType . newInstance ( ) ;
input . readGroup ( group , WireFormatNano . getTagFieldNumber ( tag ) ) ;
return group ;
case TYPE_MESSAGE :
MessageNano message = ( MessageNano ) messageType . newInstance ( ) ;
input . readMessage ( message ) ;
return message ;
default :
throw new IllegalArgumentException ( "Unknown type " + type ) ;
}
} catch ( InstantiationException e ) {
throw new IllegalArgumentException (
"Error creating instance of class " + messageType , e ) ;
} catch ( IllegalAccessException e ) {
throw new IllegalArgumentException (
"Error creating instance of class " + messageType , e ) ;
} catch ( IOException e ) {
throw new IllegalArgumentException ( "Error reading extension field" , e ) ;
}
}
protected void readDataInto ( UnknownFieldData data , List < Object > resultList ) {
// This implementation is for message/group extensions.
resultList . add ( readData ( CodedInputByteBufferNano . newInstance ( data . bytes ) ) ) ;
}
/ * *
* If the generic type is a list , returns { @code true } .
* Sets the value of this extension to the given list of unknown fields . This removes any
* previously stored data matching this extension .
*
* @param value The value of this extension , or { @code null } to clear this extension from the
* unknown fields .
* @return The same { @code unknownFields } list , or a new list storing the extension value if
* the argument was null .
* /
private boolean isList ( ) {
return type instanceof ParameterizedType ;
final List < UnknownFieldData > setValueTo ( T value , List < UnknownFieldData > unknownFields ) {
if ( unknownFields ! = null ) {
// Delete all data matching this extension
for ( int i = unknownFields . size ( ) - 1 ; i > = 0 ; i - - ) {
if ( isMatch ( unknownFields . get ( i ) . tag ) ) {
unknownFields . remove ( i ) ;
}
}
}
if ( value ! = null ) {
if ( unknownFields = = null ) {
unknownFields = new ArrayList < UnknownFieldData > ( ) ;
}
if ( repeated ) {
writeDataInto ( value , unknownFields ) ;
} else {
unknownFields . add ( writeData ( value ) ) ;
}
}
// After deletion or no-op addition (due to 'value' being an array of empty or
// null-only elements), unknownFields may be empty. Discard the ArrayList if so.
return ( unknownFields . size ( ) = = 0 ) ? null : unknownFields ;
}
@SuppressWarnings ( "unchecked" )
private Class < T > getListType ( ) {
return ( Class < T > ) ( ( ParameterizedType ) type ) . getRawType ( ) ;
protected UnknownFieldData writeData ( Object value ) {
// This implementation is for message/group extensions.
byte [ ] data ;
try {
switch ( type ) {
case TYPE_GROUP :
MessageNano groupValue = ( MessageNano ) value ;
int fieldNumber = WireFormatNano . getTagFieldNumber ( tag ) ;
data = new byte [ CodedOutputByteBufferNano . computeGroupSizeNoTag ( groupValue )
+ CodedOutputByteBufferNano . computeTagSize ( fieldNumber ) ] ;
CodedOutputByteBufferNano out = CodedOutputByteBufferNano . newInstance ( data ) ;
out . writeGroupNoTag ( groupValue ) ;
// The endgroup tag must be included in the data payload.
out . writeTag ( fieldNumber , WireFormatNano . WIRETYPE_END_GROUP ) ;
break ;
case TYPE_MESSAGE :
MessageNano messageValue = ( MessageNano ) value ;
data = new byte [
CodedOutputByteBufferNano . computeMessageSizeNoTag ( messageValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeMessageNoTag ( messageValue ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown type " + type ) ;
}
} catch ( IOException e ) {
// Should not happen
throw new IllegalStateException ( e ) ;
}
return new UnknownFieldData ( tag , data ) ;
}
protected void writeDataInto ( T array , List < UnknownFieldData > unknownFields ) {
// This implementation is for non-packed extensions.
int arrayLength = Array . getLength ( array ) ;
for ( int i = 0 ; i < arrayLength ; i + + ) {
Object element = Array . get ( array , i ) ;
if ( element ! = null ) {
unknownFields . add ( writeData ( element ) ) ;
}
}
}
/ * *
* If the generic type is a list , returns the type of element in the list . Otherwise ,
* returns the actual type .
* Represents an extension of a primitive ( including enum ) type . If there is no primitive
* extensions , this subclass will be removable by ProGuard .
* /
@SuppressWarnings ( "unchecked" )
private Class < T > getTargetClass ( ) {
if ( isList ( ) ) {
return ( Class < T > ) ( ( ParameterizedType ) type ) . getActualTypeArguments ( ) [ 0 ] ;
}
return ( Class < T > ) type ;
private static class PrimitiveExtension < M extends ExtendableMessageNano < M > , T >
extends Extension < M , T > {
/ * *
* Tag of a piece of non - packed data from the wire compatible with this extension .
* /
private final int nonPackedTag ;
/ * *
* Tag of a piece of packed data from the wire compatible with this extension .
* 0 if the type of this extension is not packable .
* /
private final int packedTag ;
public PrimitiveExtension ( int type , Class < T > clazz , int tag , boolean repeated ,
int nonPackedTag , int packedTag ) {
super ( type , clazz , tag , repeated ) ;
this . nonPackedTag = nonPackedTag ;
this . packedTag = packedTag ;
}
@Override
protected boolean isMatch ( int unknownDataTag ) {
if ( repeated ) {
return unknownDataTag = = nonPackedTag | | unknownDataTag = = packedTag ;
} else {
return unknownDataTag = = tag ;
}
}
@Override
protected Object readData ( CodedInputByteBufferNano input ) {
try {
switch ( type ) {
case TYPE_DOUBLE :
return input . readDouble ( ) ;
case TYPE_FLOAT :
return input . readFloat ( ) ;
case TYPE_INT64 :
return input . readInt64 ( ) ;
case TYPE_UINT64 :
return input . readUInt64 ( ) ;
case TYPE_INT32 :
return input . readInt32 ( ) ;
case TYPE_FIXED64 :
return input . readFixed64 ( ) ;
case TYPE_FIXED32 :
return input . readFixed32 ( ) ;
case TYPE_BOOL :
return input . readBool ( ) ;
case TYPE_STRING :
return input . readString ( ) ;
case TYPE_BYTES :
return input . readBytes ( ) ;
case TYPE_UINT32 :
return input . readUInt32 ( ) ;
case TYPE_ENUM :
return input . readEnum ( ) ;
case TYPE_SFIXED32 :
return input . readSFixed32 ( ) ;
case TYPE_SFIXED64 :
return input . readSFixed64 ( ) ;
case TYPE_SINT32 :
return input . readSInt32 ( ) ;
case TYPE_SINT64 :
return input . readSInt64 ( ) ;
default :
throw new IllegalArgumentException ( "Unknown type " + type ) ;
}
} catch ( IOException e ) {
throw new IllegalArgumentException ( "Error reading extension field" , e ) ;
}
}
@Override
protected void readDataInto ( UnknownFieldData data , List < Object > resultList ) {
// This implementation is for primitive typed extensions,
// which can read both packed and non-packed data.
if ( data . tag = = nonPackedTag ) {
resultList . add ( readData ( CodedInputByteBufferNano . newInstance ( data . bytes ) ) ) ;
} else {
CodedInputByteBufferNano buffer = CodedInputByteBufferNano . newInstance ( data . bytes ) ;
try {
buffer . pushLimit ( buffer . readRawVarint32 ( ) ) ; // length limit
} catch ( IOException e ) {
throw new IllegalArgumentException ( "Error reading extension field" , e ) ;
}
while ( ! buffer . isAtEnd ( ) ) {
resultList . add ( readData ( buffer ) ) ;
}
}
}
@Override
protected final UnknownFieldData writeData ( Object value ) {
byte [ ] data ;
try {
switch ( type ) {
case TYPE_DOUBLE :
Double doubleValue = ( Double ) value ;
data = new byte [
CodedOutputByteBufferNano . computeDoubleSizeNoTag ( doubleValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeDoubleNoTag ( doubleValue ) ;
break ;
case TYPE_FLOAT :
Float floatValue = ( Float ) value ;
data = new byte [
CodedOutputByteBufferNano . computeFloatSizeNoTag ( floatValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeFloatNoTag ( floatValue ) ;
break ;
case TYPE_INT64 :
Long int64Value = ( Long ) value ;
data = new byte [
CodedOutputByteBufferNano . computeInt64SizeNoTag ( int64Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeInt64NoTag ( int64Value ) ;
break ;
case TYPE_UINT64 :
Long uint64Value = ( Long ) value ;
data = new byte [
CodedOutputByteBufferNano . computeUInt64SizeNoTag ( uint64Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeUInt64NoTag ( uint64Value ) ;
break ;
case TYPE_INT32 :
Integer int32Value = ( Integer ) value ;
data = new byte [
CodedOutputByteBufferNano . computeInt32SizeNoTag ( int32Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeInt32NoTag ( int32Value ) ;
break ;
case TYPE_FIXED64 :
Long fixed64Value = ( Long ) value ;
data = new byte [
CodedOutputByteBufferNano . computeFixed64SizeNoTag ( fixed64Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeFixed64NoTag ( fixed64Value ) ;
break ;
case TYPE_FIXED32 :
Integer fixed32Value = ( Integer ) value ;
data = new byte [
CodedOutputByteBufferNano . computeFixed32SizeNoTag ( fixed32Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeFixed32NoTag ( fixed32Value ) ;
break ;
case TYPE_BOOL :
Boolean boolValue = ( Boolean ) value ;
data = new byte [ CodedOutputByteBufferNano . computeBoolSizeNoTag ( boolValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeBoolNoTag ( boolValue ) ;
break ;
case TYPE_STRING :
String stringValue = ( String ) value ;
data = new byte [
CodedOutputByteBufferNano . computeStringSizeNoTag ( stringValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeStringNoTag ( stringValue ) ;
break ;
case TYPE_BYTES :
byte [ ] bytesValue = ( byte [ ] ) value ;
data = new byte [
CodedOutputByteBufferNano . computeBytesSizeNoTag ( bytesValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeBytesNoTag ( bytesValue ) ;
break ;
case TYPE_UINT32 :
Integer uint32Value = ( Integer ) value ;
data = new byte [
CodedOutputByteBufferNano . computeUInt32SizeNoTag ( uint32Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeUInt32NoTag ( uint32Value ) ;
break ;
case TYPE_ENUM :
Integer enumValue = ( Integer ) value ;
data = new byte [ CodedOutputByteBufferNano . computeEnumSizeNoTag ( enumValue ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeEnumNoTag ( enumValue ) ;
break ;
case TYPE_SFIXED32 :
Integer sfixed32Value = ( Integer ) value ;
data = new byte [
CodedOutputByteBufferNano . computeSFixed32SizeNoTag ( sfixed32Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data )
. writeSFixed32NoTag ( sfixed32Value ) ;
break ;
case TYPE_SFIXED64 :
Long sfixed64Value = ( Long ) value ;
data = new byte [
CodedOutputByteBufferNano . computeSFixed64SizeNoTag ( sfixed64Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data )
. writeSFixed64NoTag ( sfixed64Value ) ;
break ;
case TYPE_SINT32 :
Integer sint32Value = ( Integer ) value ;
data = new byte [
CodedOutputByteBufferNano . computeSInt32SizeNoTag ( sint32Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeSInt32NoTag ( sint32Value ) ;
break ;
case TYPE_SINT64 :
Long sint64Value = ( Long ) value ;
data = new byte [
CodedOutputByteBufferNano . computeSInt64SizeNoTag ( sint64Value ) ] ;
CodedOutputByteBufferNano . newInstance ( data ) . writeSInt64NoTag ( sint64Value ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown type " + type ) ;
}
} catch ( IOException e ) {
// Should not happen
throw new IllegalStateException ( e ) ;
}
return new UnknownFieldData ( tag , data ) ;
}
@Override
protected void writeDataInto ( T array , List < UnknownFieldData > unknownFields ) {
if ( tag = = nonPackedTag ) {
// Use base implementation for non-packed data
super . writeDataInto ( array , unknownFields ) ;
} else if ( tag = = packedTag ) {
// Packed. Note that the array element type is guaranteed to be primitive, so there
// won't be any null elements, so no null check in this block. First get data size.
int arrayLength = Array . getLength ( array ) ;
int dataSize = 0 ;
switch ( type ) {
case TYPE_BOOL :
// Bools are stored as int32 but just as 0 or 1, so 1 byte each.
dataSize = arrayLength ;
break ;
case TYPE_FIXED32 :
case TYPE_SFIXED32 :
case TYPE_FLOAT :
dataSize = arrayLength * CodedOutputByteBufferNano . LITTLE_ENDIAN_32_SIZE ;
break ;
case TYPE_FIXED64 :
case TYPE_SFIXED64 :
case TYPE_DOUBLE :
dataSize = arrayLength * CodedOutputByteBufferNano . LITTLE_ENDIAN_64_SIZE ;
break ;
case TYPE_INT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeInt32SizeNoTag (
Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_SINT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeSInt32SizeNoTag (
Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_UINT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeUInt32SizeNoTag (
Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_INT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeInt64SizeNoTag (
Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_SINT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeSInt64SizeNoTag (
Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_UINT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeUInt64SizeNoTag (
Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_ENUM :
for ( int i = 0 ; i < arrayLength ; i + + ) {
dataSize + = CodedOutputByteBufferNano . computeEnumSizeNoTag (
Array . getInt ( array , i ) ) ;
}
break ;
default :
throw new IllegalArgumentException ( "Unexpected non-packable type " + type ) ;
}
// Then construct payload.
int payloadSize =
dataSize + CodedOutputByteBufferNano . computeRawVarint32Size ( dataSize ) ;
byte [ ] data = new byte [ payloadSize ] ;
CodedOutputByteBufferNano output = CodedOutputByteBufferNano . newInstance ( data ) ;
try {
output . writeRawVarint32 ( dataSize ) ;
switch ( type ) {
case TYPE_BOOL :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeBoolNoTag ( Array . getBoolean ( array , i ) ) ;
}
break ;
case TYPE_FIXED32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeFixed32NoTag ( Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_SFIXED32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeSFixed32NoTag ( Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_FLOAT :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeFloatNoTag ( Array . getFloat ( array , i ) ) ;
}
break ;
case TYPE_FIXED64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeFixed64NoTag ( Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_SFIXED64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeSFixed64NoTag ( Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_DOUBLE :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeDoubleNoTag ( Array . getDouble ( array , i ) ) ;
}
break ;
case TYPE_INT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeInt32NoTag ( Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_SINT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeSInt32NoTag ( Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_UINT32 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeUInt32NoTag ( Array . getInt ( array , i ) ) ;
}
break ;
case TYPE_INT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeInt64NoTag ( Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_SINT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeSInt64NoTag ( Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_UINT64 :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeUInt64NoTag ( Array . getLong ( array , i ) ) ;
}
break ;
case TYPE_ENUM :
for ( int i = 0 ; i < arrayLength ; i + + ) {
output . writeEnumNoTag ( Array . getInt ( array , i ) ) ;
}
break ;
default :
throw new IllegalArgumentException ( "Unpackable type " + type ) ;
}
} catch ( IOException e ) {
// Should not happen.
throw new IllegalStateException ( e ) ;
}
unknownFields . add ( new UnknownFieldData ( tag , data ) ) ;
} else {
throw new IllegalArgumentException ( "Unexpected repeated extension tag " + tag
+ ", unequal to both non-packed variant " + nonPackedTag
+ " and packed variant " + packedTag ) ;
}
}
}
}
}