Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
0e122ce8
Commit
0e122ce8
authored
Apr 29, 2015
by
Jisi Liu
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #315 from brianduff/sync_from_aosp
Sync nanoproto from AOSP
parents
5a9863b5
9d546c85
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
703 additions
and
90 deletions
+703
-90
README.md
javanano/README.md
+23
-0
pom.xml
javanano/pom.xml
+12
-3
CodedOutputByteBufferNano.java
...a/com/google/protobuf/nano/CodedOutputByteBufferNano.java
+241
-23
ExtendableMessageNano.java
.../java/com/google/protobuf/nano/ExtendableMessageNano.java
+5
-23
Extension.java
...ano/src/main/java/com/google/protobuf/nano/Extension.java
+26
-7
FieldArray.java
...no/src/main/java/com/google/protobuf/nano/FieldArray.java
+26
-8
FieldData.java
...ano/src/main/java/com/google/protobuf/nano/FieldData.java
+51
-1
InternalNano.java
.../src/main/java/com/google/protobuf/nano/InternalNano.java
+8
-0
MessageNano.java
...o/src/main/java/com/google/protobuf/nano/MessageNano.java
+8
-0
MessageNanoPrinter.java
...ain/java/com/google/protobuf/nano/MessageNanoPrinter.java
+4
-0
UnknownFieldData.java
.../main/java/com/google/protobuf/nano/UnknownFieldData.java
+4
-0
NanoTest.java
...nano/src/test/java/com/google/protobuf/nano/NanoTest.java
+80
-0
unittest_extension_nano.proto
...va/com/google/protobuf/nano/unittest_extension_nano.proto
+4
-0
javanano_enum.cc
src/google/protobuf/compiler/javanano/javanano_enum.cc
+36
-4
javanano_enum_field.cc
src/google/protobuf/compiler/javanano/javanano_enum_field.cc
+28
-4
javanano_enum_field.h
src/google/protobuf/compiler/javanano/javanano_enum_field.h
+1
-0
javanano_extension.cc
src/google/protobuf/compiler/javanano/javanano_extension.cc
+1
-1
javanano_field.h
src/google/protobuf/compiler/javanano/javanano_field.h
+1
-0
javanano_generator.cc
src/google/protobuf/compiler/javanano/javanano_generator.cc
+6
-0
javanano_message.cc
src/google/protobuf/compiler/javanano/javanano_message.cc
+76
-15
javanano_message.h
src/google/protobuf/compiler/javanano/javanano_message.h
+2
-0
javanano_message_field.cc
...ogle/protobuf/compiler/javanano/javanano_message_field.cc
+29
-0
javanano_message_field.h
...oogle/protobuf/compiler/javanano/javanano_message_field.h
+3
-0
javanano_params.h
src/google/protobuf/compiler/javanano/javanano_params.h
+19
-1
javanano_primitive_field.cc
...le/protobuf/compiler/javanano/javanano_primitive_field.cc
+8
-0
javanano_primitive_field.h
...gle/protobuf/compiler/javanano/javanano_primitive_field.h
+1
-0
No files found.
javanano/README.md
View file @
0e122ce8
...
...
@@ -145,6 +145,7 @@ optional_field_style -> default or accessors
enum_style -> c or java
ignore_services -> true or false
parcelable_messages -> true or false
generate_intdefs -> true or false
```
**java_package=\<file-name\>|\<package-name\>**
(no default)
...
...
@@ -302,6 +303,28 @@ parcelable_messages -> true or false
Android-specific option to generate Parcelable messages.
**generate_intdefs={true,false}**
(default: false)
Android-specific option to generate @IntDef annotations for enums.
If turned on, an '@IntDef' annotation (a public @interface) will be
generated for each enum, and every integer parameter and return
value in the generated code meant for this enum will be annotated
with it. This interface is generated with the same name and at the
same place as the enum members' container interfaces described
above under 'enum_style=java', regardless of the enum_style option
used. When this is combined with enum_style=java, the interface
will be both the '@IntDef' annotation and the container of the enum
members; otherwise the interface has an empty body.
Your app must declare a compile-time dependency on the
android-support-annotations library.
For more information on how these @IntDef annotations help with
compile-time type safety, see:
https://sites.google.com/a/android.com/tools/tech-docs/support-annotations
and
https://developer.android.com/reference/android/support/annotation/IntDef.html
To use nano protobufs within the Android repo:
----------------------------------------------
...
...
javanano/pom.xml
View file @
0e122ce8
...
...
@@ -97,19 +97,19 @@
<arg
value=
"src/test/java/com/google/protobuf/nano/map_test.proto"
/>
</exec>
<exec
executable=
"../src/protoc"
>
<arg
value=
"--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources"
/>
<arg
value=
"--javanano_out=store_unknown_fields=true,generate_equals=true
,generate_clone=true
:target/generated-test-sources"
/>
<arg
value=
"--proto_path=src/test/java/com"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_extension_singular_nano.proto"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_extension_repeated_nano.proto"
/>
</exec>
<exec
executable=
"../src/protoc"
>
<arg
value=
"--javanano_out=store_unknown_fields=true:target/generated-test-sources"
/>
<arg
value=
"--javanano_out=store_unknown_fields=true
,generate_clone=true
:target/generated-test-sources"
/>
<arg
value=
"--proto_path=src/test/java/com"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_extension_packed_nano.proto"
/>
</exec>
<exec
executable=
"../src/protoc"
>
<arg
value=
"--javanano_out=java_nano_generate_has=true,generate_equals=true:target/generated-test-sources"
/>
<arg
value=
"--javanano_out=java_nano_generate_has=true,generate_equals=true
,generate_clone=true
:target/generated-test-sources"
/>
<arg
value=
"--proto_path=src/test/java/com"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_has_nano.proto"
/>
</exec>
...
...
@@ -139,6 +139,15 @@
<arg
value=
"--proto_path=src/test/java/com"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto"
/>
</exec>
<exec
executable=
"../src/protoc"
>
<arg
value=
"--javanano_out=
optional_field_style=reftypes_compat_mode,
generate_equals=true,
java_outer_classname=google/protobuf/nano/unittest_reference_types_nano.proto|NanoReferenceTypesCompat
:target/generated-test-sources"
/>
<arg
value=
"--proto_path=src/test/java/com"
/>
<arg
value=
"src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto"
/>
</exec>
</tasks>
<testSourceRoot>
target/generated-test-sources
</testSourceRoot>
</configuration>
...
...
javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
View file @
0e122ce8
...
...
@@ -31,6 +31,9 @@
package
com
.
google
.
protobuf
.
nano
;
import
java.io.IOException
;
import
java.nio.BufferOverflowException
;
import
java.nio.ByteBuffer
;
import
java.nio.ReadOnlyBufferException
;
/**
* Encodes and writes protocol message fields.
...
...
@@ -47,15 +50,17 @@ import java.io.IOException;
* @author kneton@google.com Kenton Varda
*/
public
final
class
CodedOutputByteBufferNano
{
private
final
byte
[]
buffer
;
private
final
int
limit
;
private
int
position
;
/* max bytes per java UTF-16 char in UTF-8 */
private
static
final
int
MAX_UTF8_EXPANSION
=
3
;
private
final
ByteBuffer
buffer
;
private
CodedOutputByteBufferNano
(
final
byte
[]
buffer
,
final
int
offset
,
final
int
length
)
{
this
(
ByteBuffer
.
wrap
(
buffer
,
offset
,
length
));
}
private
CodedOutputByteBufferNano
(
final
ByteBuffer
buffer
)
{
this
.
buffer
=
buffer
;
position
=
offset
;
limit
=
offset
+
length
;
}
/**
...
...
@@ -287,14 +292,213 @@ public final class CodedOutputByteBufferNano {
/** Write a {@code string} field to the stream. */
public
void
writeStringNoTag
(
final
String
value
)
throws
IOException
{
// Unfortunately there does not appear to be any way to tell Java to encode
// UTF-8 directly into our buffer, so we have to let it create its own byte
// array and then copy.
final
byte
[]
bytes
=
value
.
getBytes
(
InternalNano
.
UTF_8
);
writeRawVarint32
(
bytes
.
length
);
writeRawBytes
(
bytes
);
// UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
// and at most 3 times of it. Optimize for the case where we know this length results in a
// constant varint length - saves measuring length of the string.
try
{
final
int
minLengthVarIntSize
=
computeRawVarint32Size
(
value
.
length
());
final
int
maxLengthVarIntSize
=
computeRawVarint32Size
(
value
.
length
()
*
MAX_UTF8_EXPANSION
);
if
(
minLengthVarIntSize
==
maxLengthVarIntSize
)
{
int
oldPosition
=
buffer
.
position
();
// Buffer.position, when passed a position that is past its limit, throws
// IllegalArgumentException, and this class is documented to throw
// OutOfSpaceException instead.
if
(
buffer
.
remaining
()
<
minLengthVarIntSize
)
{
throw
new
OutOfSpaceException
(
oldPosition
+
minLengthVarIntSize
,
buffer
.
limit
());
}
buffer
.
position
(
oldPosition
+
minLengthVarIntSize
);
encode
(
value
,
buffer
);
int
newPosition
=
buffer
.
position
();
buffer
.
position
(
oldPosition
);
writeRawVarint32
(
newPosition
-
oldPosition
-
minLengthVarIntSize
);
buffer
.
position
(
newPosition
);
}
else
{
writeRawVarint32
(
encodedLength
(
value
));
encode
(
value
,
buffer
);
}
}
catch
(
BufferOverflowException
e
)
{
final
OutOfSpaceException
outOfSpaceException
=
new
OutOfSpaceException
(
buffer
.
position
(),
buffer
.
limit
());
outOfSpaceException
.
initCause
(
e
);
throw
outOfSpaceException
;
}
}
// These UTF-8 handling methods are copied from Guava's Utf8 class.
/**
* Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
* this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
* both time and space.
*
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates)
*/
private
static
int
encodedLength
(
CharSequence
sequence
)
{
// Warning to maintainers: this implementation is highly optimized.
int
utf16Length
=
sequence
.
length
();
int
utf8Length
=
utf16Length
;
int
i
=
0
;
// This loop optimizes for pure ASCII.
while
(
i
<
utf16Length
&&
sequence
.
charAt
(
i
)
<
0x80
)
{
i
++;
}
// This loop optimizes for chars less than 0x800.
for
(;
i
<
utf16Length
;
i
++)
{
char
c
=
sequence
.
charAt
(
i
);
if
(
c
<
0x800
)
{
utf8Length
+=
((
0x7f
-
c
)
>>>
31
);
// branch free!
}
else
{
utf8Length
+=
encodedLengthGeneral
(
sequence
,
i
);
break
;
}
}
if
(
utf8Length
<
utf16Length
)
{
// Necessary and sufficient condition for overflow because of maximum 3x expansion
throw
new
IllegalArgumentException
(
"UTF-8 length does not fit in int: "
+
(
utf8Length
+
(
1L
<<
32
)));
}
return
utf8Length
;
}
private
static
int
encodedLengthGeneral
(
CharSequence
sequence
,
int
start
)
{
int
utf16Length
=
sequence
.
length
();
int
utf8Length
=
0
;
for
(
int
i
=
start
;
i
<
utf16Length
;
i
++)
{
char
c
=
sequence
.
charAt
(
i
);
if
(
c
<
0x800
)
{
utf8Length
+=
(
0x7f
-
c
)
>>>
31
;
// branch free!
}
else
{
utf8Length
+=
2
;
// jdk7+: if (Character.isSurrogate(c)) {
if
(
Character
.
MIN_SURROGATE
<=
c
&&
c
<=
Character
.
MAX_SURROGATE
)
{
// Check that we have a well-formed surrogate pair.
int
cp
=
Character
.
codePointAt
(
sequence
,
i
);
if
(
cp
<
Character
.
MIN_SUPPLEMENTARY_CODE_POINT
)
{
throw
new
IllegalArgumentException
(
"Unpaired surrogate at index "
+
i
);
}
i
++;
}
}
}
return
utf8Length
;
}
/**
* Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
* equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
* and space. Bytes are written starting at the current position. This method requires paired
* surrogates, and therefore does not support chunking.
*
* <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
* compute the exact amount needed, or leave room for {@code 3 * sequence.length()}, which is the
* largest possible number of bytes that any input can be encoded to.
*
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates)
* @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
* {@code byteBuffer}'s remaining space.
* @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
*/
private
static
void
encode
(
CharSequence
sequence
,
ByteBuffer
byteBuffer
)
{
if
(
byteBuffer
.
isReadOnly
())
{
throw
new
ReadOnlyBufferException
();
}
else
if
(
byteBuffer
.
hasArray
())
{
try
{
int
encoded
=
encode
(
sequence
,
byteBuffer
.
array
(),
byteBuffer
.
arrayOffset
()
+
byteBuffer
.
position
(),
byteBuffer
.
remaining
());
byteBuffer
.
position
(
encoded
-
byteBuffer
.
arrayOffset
());
}
catch
(
ArrayIndexOutOfBoundsException
e
)
{
BufferOverflowException
boe
=
new
BufferOverflowException
();
boe
.
initCause
(
e
);
throw
boe
;
}
}
else
{
encodeDirect
(
sequence
,
byteBuffer
);
}
}
private
static
void
encodeDirect
(
CharSequence
sequence
,
ByteBuffer
byteBuffer
)
{
int
utf16Length
=
sequence
.
length
();
for
(
int
i
=
0
;
i
<
utf16Length
;
i
++)
{
final
char
c
=
sequence
.
charAt
(
i
);
if
(
c
<
0x80
)
{
// ASCII
byteBuffer
.
put
((
byte
)
c
);
}
else
if
(
c
<
0x800
)
{
// 11 bits, two UTF-8 bytes
byteBuffer
.
put
((
byte
)
((
0xF
<<
6
)
|
(
c
>>>
6
)));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
c
)));
}
else
if
(
c
<
Character
.
MIN_SURROGATE
||
Character
.
MAX_SURROGATE
<
c
)
{
// Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
byteBuffer
.
put
((
byte
)
((
0xF
<<
5
)
|
(
c
>>>
12
)));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
(
c
>>>
6
))));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
c
)));
}
else
{
final
char
low
;
if
(
i
+
1
==
sequence
.
length
()
||
!
Character
.
isSurrogatePair
(
c
,
(
low
=
sequence
.
charAt
(++
i
))))
{
throw
new
IllegalArgumentException
(
"Unpaired surrogate at index "
+
(
i
-
1
));
}
int
codePoint
=
Character
.
toCodePoint
(
c
,
low
);
byteBuffer
.
put
((
byte
)
((
0xF
<<
4
)
|
(
codePoint
>>>
18
)));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
(
codePoint
>>>
12
))));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
(
codePoint
>>>
6
))));
byteBuffer
.
put
((
byte
)
(
0x80
|
(
0x3F
&
codePoint
)));
}
}
}
private
static
int
encode
(
CharSequence
sequence
,
byte
[]
bytes
,
int
offset
,
int
length
)
{
int
utf16Length
=
sequence
.
length
();
int
j
=
offset
;
int
i
=
0
;
int
limit
=
offset
+
length
;
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
for
(
char
c
;
i
<
utf16Length
&&
i
+
j
<
limit
&&
(
c
=
sequence
.
charAt
(
i
))
<
0x80
;
i
++)
{
bytes
[
j
+
i
]
=
(
byte
)
c
;
}
if
(
i
==
utf16Length
)
{
return
j
+
utf16Length
;
}
j
+=
i
;
for
(
char
c
;
i
<
utf16Length
;
i
++)
{
c
=
sequence
.
charAt
(
i
);
if
(
c
<
0x80
&&
j
<
limit
)
{
bytes
[
j
++]
=
(
byte
)
c
;
}
else
if
(
c
<
0x800
&&
j
<=
limit
-
2
)
{
// 11 bits, two UTF-8 bytes
bytes
[
j
++]
=
(
byte
)
((
0xF
<<
6
)
|
(
c
>>>
6
));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
c
));
}
else
if
((
c
<
Character
.
MIN_SURROGATE
||
Character
.
MAX_SURROGATE
<
c
)
&&
j
<=
limit
-
3
)
{
// Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
bytes
[
j
++]
=
(
byte
)
((
0xF
<<
5
)
|
(
c
>>>
12
));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
(
c
>>>
6
)));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
c
));
}
else
if
(
j
<=
limit
-
4
)
{
// Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
final
char
low
;
if
(
i
+
1
==
sequence
.
length
()
||
!
Character
.
isSurrogatePair
(
c
,
(
low
=
sequence
.
charAt
(++
i
))))
{
throw
new
IllegalArgumentException
(
"Unpaired surrogate at index "
+
(
i
-
1
));
}
int
codePoint
=
Character
.
toCodePoint
(
c
,
low
);
bytes
[
j
++]
=
(
byte
)
((
0xF
<<
4
)
|
(
codePoint
>>>
18
));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
(
codePoint
>>>
12
)));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
(
codePoint
>>>
6
)));
bytes
[
j
++]
=
(
byte
)
(
0x80
|
(
0x3F
&
codePoint
));
}
else
{
throw
new
ArrayIndexOutOfBoundsException
(
"Failed writing "
+
c
+
" at index "
+
j
);
}
}
return
j
;
}
// End guava UTF-8 methods
/** Write a {@code group} field to the stream. */
public
void
writeGroupNoTag
(
final
MessageNano
value
)
throws
IOException
{
value
.
writeTo
(
this
);
...
...
@@ -602,9 +806,8 @@ public final class CodedOutputByteBufferNano {
* {@code string} field.
*/
public
static
int
computeStringSizeNoTag
(
final
String
value
)
{
final
byte
[]
bytes
=
value
.
getBytes
(
InternalNano
.
UTF_8
);
return
computeRawVarint32Size
(
bytes
.
length
)
+
bytes
.
length
;
final
int
length
=
encodedLength
(
value
);
return
computeRawVarint32Size
(
length
)
+
length
;
}
/**
...
...
@@ -687,7 +890,7 @@ public final class CodedOutputByteBufferNano {
* Otherwise, throws {@code UnsupportedOperationException}.
*/
public
int
spaceLeft
()
{
return
limit
-
position
;
return
buffer
.
remaining
()
;
}
/**
...
...
@@ -704,6 +907,23 @@ public final class CodedOutputByteBufferNano {
}
}
/**
* Returns the position within the internal buffer.
*/
public
int
position
()
{
return
buffer
.
position
();
}
/**
* Resets the position within the internal buffer to zero.
*
* @see #position
* @see #spaceLeft
*/
public
void
reset
()
{
buffer
.
clear
();
}
/**
* If you create a CodedOutputStream around a simple flat array, you must
* not attempt to write more bytes than the array has space. Otherwise,
...
...
@@ -720,12 +940,12 @@ public final class CodedOutputByteBufferNano {
/** Write a single byte. */
public
void
writeRawByte
(
final
byte
value
)
throws
IOException
{
if
(
position
==
limit
)
{
if
(
!
buffer
.
hasRemaining
()
)
{
// We're writing to a single buffer.
throw
new
OutOfSpaceException
(
position
,
limit
);
throw
new
OutOfSpaceException
(
buffer
.
position
(),
buffer
.
limit
()
);
}
buffer
[
position
++]
=
value
;
buffer
.
put
(
value
)
;
}
/** Write a single byte, represented by an integer value. */
...
...
@@ -741,13 +961,11 @@ public final class CodedOutputByteBufferNano {
/** Write part of an array of bytes. */
public
void
writeRawBytes
(
final
byte
[]
value
,
int
offset
,
int
length
)
throws
IOException
{
if
(
limit
-
position
>=
length
)
{
// We have room in the current buffer.
System
.
arraycopy
(
value
,
offset
,
buffer
,
position
,
length
);
position
+=
length
;
if
(
buffer
.
remaining
()
>=
length
)
{
buffer
.
put
(
value
,
offset
,
length
);
}
else
{
// We're writing to a single buffer.
throw
new
OutOfSpaceException
(
position
,
limit
);
throw
new
OutOfSpaceException
(
buffer
.
position
(),
buffer
.
limit
()
);
}
}
...
...
javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
View file @
0e122ce8
...
...
@@ -160,28 +160,10 @@ public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
return
true
;
}
/**
* Returns whether the stored unknown field data in this message is equivalent to that in the
* other message.
*
* @param other the other message.
* @return whether the two sets of unknown field data are equal.
*/
protected
final
boolean
unknownFieldDataEquals
(
M
other
)
{
if
(
unknownFieldData
==
null
||
unknownFieldData
.
isEmpty
())
{
return
other
.
unknownFieldData
==
null
||
other
.
unknownFieldData
.
isEmpty
();
}
else
{
return
unknownFieldData
.
equals
(
other
.
unknownFieldData
);
}
}
/**
* Computes the hashcode representing the unknown field data stored in this message.
*
* @return the hashcode for the unknown field data.
*/
protected
final
int
unknownFieldDataHashCode
()
{
return
(
unknownFieldData
==
null
||
unknownFieldData
.
isEmpty
()
?
0
:
unknownFieldData
.
hashCode
());
@Override
public
M
clone
()
throws
CloneNotSupportedException
{
M
cloned
=
(
M
)
super
.
clone
();
InternalNano
.
cloneUnknownFieldData
(
this
,
cloned
);
return
cloned
;
}
}
javanano/src/main/java/com/google/protobuf/nano/Extension.java
View file @
0e122ce8
...
...
@@ -79,12 +79,30 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* Should be used by the generated code only.
*
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
* @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
*/
@Deprecated
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
);
}
// Note: these create...() methods take a long for the tag parameter,
// because tags are represented as unsigned ints, and these values exist
// in generated code as long values. However, they can fit in 32-bits, so
// it's safe to cast them to int without loss of precision.
/**
* 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
,
long
tag
)
{
return
new
Extension
<
M
,
T
>(
type
,
clazz
,
(
int
)
tag
,
false
);
}
/**
* Creates a repeated {@code Extension} of the given message type and tag number.
* Should be used by the generated code only.
...
...
@@ -92,8 +110,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @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
);
Extension
<
M
,
T
[]>
createRepeatedMessageTyped
(
int
type
,
Class
<
T
[]>
clazz
,
long
tag
)
{
return
new
Extension
<
M
,
T
[]>(
type
,
clazz
,
(
int
)
tag
,
true
);
}
/**
...
...
@@ -104,8 +122,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @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
);
Extension
<
M
,
T
>
createPrimitiveTyped
(
int
type
,
Class
<
T
>
clazz
,
long
tag
)
{
return
new
PrimitiveExtension
<
M
,
T
>(
type
,
clazz
,
(
int
)
tag
,
false
,
0
,
0
);
}
/**
...
...
@@ -117,8 +135,9 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
*/
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
);
int
type
,
Class
<
T
>
clazz
,
long
tag
,
long
nonPackedTag
,
long
packedTag
)
{
return
new
PrimitiveExtension
<
M
,
T
>(
type
,
clazz
,
(
int
)
tag
,
true
,
(
int
)
nonPackedTag
,
(
int
)
packedTag
);
}
/**
...
...
@@ -136,7 +155,7 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
protected
final
Class
<
T
>
clazz
;
/**
* Tag number of this extension.
* Tag number of this extension.
The data should be viewed as an unsigned 32-bit value.
*/
public
final
int
tag
;
...
...
javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
View file @
0e122ce8
...
...
@@ -35,9 +35,12 @@ package com.google.protobuf.nano;
* A custom version of {@link android.util.SparseArray} with the minimal API
* for storing {@link FieldData} objects.
*
* <p>This class is an internal implementation detail of nano and should not
* be called directly by clients.
*
* Based on {@link android.support.v4.util.SpareArrayCompat}.
*/
class
FieldArray
{
public
final
class
FieldArray
implements
Cloneable
{
private
static
final
FieldData
DELETED
=
new
FieldData
();
private
boolean
mGarbage
=
false
;
...
...
@@ -48,7 +51,7 @@ class FieldArray {
/**
* Creates a new FieldArray containing no fields.
*/
public
FieldArray
()
{
FieldArray
()
{
this
(
10
);
}
...
...
@@ -57,7 +60,7 @@ class FieldArray {
* require any additional memory allocation to store the specified
* number of mappings.
*/
public
FieldArray
(
int
initialCapacity
)
{
FieldArray
(
int
initialCapacity
)
{
initialCapacity
=
idealIntArraySize
(
initialCapacity
);
mFieldNumbers
=
new
int
[
initialCapacity
];
mData
=
new
FieldData
[
initialCapacity
];
...
...
@@ -68,7 +71,7 @@ class FieldArray {
* Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
* if no such mapping has been made.
*/
public
FieldData
get
(
int
fieldNumber
)
{
FieldData
get
(
int
fieldNumber
)
{
int
i
=
binarySearch
(
fieldNumber
);
if
(
i
<
0
||
mData
[
i
]
==
DELETED
)
{
...
...
@@ -81,7 +84,7 @@ class FieldArray {
/**
* Removes the data from the specified fieldNumber, if there was any.
*/
public
void
remove
(
int
fieldNumber
)
{
void
remove
(
int
fieldNumber
)
{
int
i
=
binarySearch
(
fieldNumber
);
if
(
i
>=
0
&&
mData
[
i
]
!=
DELETED
)
{
...
...
@@ -118,7 +121,7 @@ class FieldArray {
* Adds a mapping from the specified fieldNumber to the specified data,
* replacing the previous mapping if there was one.
*/
public
void
put
(
int
fieldNumber
,
FieldData
data
)
{
void
put
(
int
fieldNumber
,
FieldData
data
)
{
int
i
=
binarySearch
(
fieldNumber
);
if
(
i
>=
0
)
{
...
...
@@ -167,7 +170,7 @@ class FieldArray {
* Returns the number of key-value mappings that this FieldArray
* currently stores.
*/
public
int
size
()
{
int
size
()
{
if
(
mGarbage
)
{
gc
();
}
...
...
@@ -184,7 +187,7 @@ class FieldArray {
* the value from the <code>index</code>th key-value mapping that this
* FieldArray stores.
*/
public
FieldData
dataAt
(
int
index
)
{
FieldData
dataAt
(
int
index
)
{
if
(
mGarbage
)
{
gc
();
}
...
...
@@ -270,4 +273,19 @@ class FieldArray {
}
return
true
;
}
@Override
public
final
FieldArray
clone
()
{
// Trigger GC so we compact and don't copy DELETED elements.
int
size
=
size
();
FieldArray
clone
=
new
FieldArray
(
size
);
System
.
arraycopy
(
mFieldNumbers
,
0
,
clone
.
mFieldNumbers
,
0
,
size
);
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
if
(
mData
[
i
]
!=
null
)
{
clone
.
mData
[
i
]
=
mData
[
i
].
clone
();
}
}
clone
.
mSize
=
size
;
return
clone
;
}
}
javanano/src/main/java/com/google/protobuf/nano/FieldData.java
View file @
0e122ce8
...
...
@@ -39,7 +39,7 @@ import java.util.List;
* Stores unknown fields. These might be extensions or fields that the generated API doesn't
* know about yet.
*/
class
FieldData
{
class
FieldData
implements
Cloneable
{
private
Extension
<?,
?>
cachedExtension
;
private
Object
value
;
/** The serialised values for this object. Will be cleared if getValue is called */
...
...
@@ -187,4 +187,54 @@ class FieldData {
return
result
;
}
@Override
public
final
FieldData
clone
()
{
FieldData
clone
=
new
FieldData
();
try
{
clone
.
cachedExtension
=
cachedExtension
;
if
(
unknownFieldData
==
null
)
{
clone
.
unknownFieldData
=
null
;
}
else
{
clone
.
unknownFieldData
.
addAll
(
unknownFieldData
);
}
// Whether we need to deep clone value depends on its type. Primitive reference types
// (e.g. Integer, Long etc.) are ok, since they're immutable. We need to clone arrays
// and messages.
if
(
value
==
null
)
{
// No cloning required.
}
else
if
(
value
instanceof
MessageNano
)
{
clone
.
value
=
((
MessageNano
)
value
).
clone
();
}
else
if
(
value
instanceof
byte
[])
{
clone
.
value
=
((
byte
[])
value
).
clone
();
}
else
if
(
value
instanceof
byte
[][])
{
byte
[][]
valueArray
=
(
byte
[][])
value
;
byte
[][]
cloneArray
=
new
byte
[
valueArray
.
length
][];
clone
.
value
=
cloneArray
;
for
(
int
i
=
0
;
i
<
valueArray
.
length
;
i
++)
{
cloneArray
[
i
]
=
valueArray
[
i
].
clone
();
}
}
else
if
(
value
instanceof
boolean
[])
{
clone
.
value
=
((
boolean
[])
value
).
clone
();
}
else
if
(
value
instanceof
int
[])
{
clone
.
value
=
((
int
[])
value
).
clone
();
}
else
if
(
value
instanceof
long
[])
{
clone
.
value
=
((
long
[])
value
).
clone
();
}
else
if
(
value
instanceof
float
[])
{
clone
.
value
=
((
float
[])
value
).
clone
();
}
else
if
(
value
instanceof
double
[])
{
clone
.
value
=
((
double
[])
value
).
clone
();
}
else
if
(
value
instanceof
MessageNano
[])
{
MessageNano
[]
valueArray
=
(
MessageNano
[])
value
;
MessageNano
[]
cloneArray
=
new
MessageNano
[
valueArray
.
length
];
clone
.
value
=
cloneArray
;
for
(
int
i
=
0
;
i
<
valueArray
.
length
;
i
++)
{
cloneArray
[
i
]
=
valueArray
[
i
].
clone
();
}
}
return
clone
;
}
catch
(
CloneNotSupportedException
e
)
{
throw
new
AssertionError
(
e
);
}
}
}
javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
View file @
0e122ce8
...
...
@@ -536,4 +536,12 @@ public final class InternalNano {
}
return
o
.
hashCode
();
}
// This avoids having to make FieldArray public.
public
static
void
cloneUnknownFieldData
(
ExtendableMessageNano
original
,
ExtendableMessageNano
cloned
)
{
if
(
original
.
unknownFieldData
!=
null
)
{
cloned
.
unknownFieldData
=
(
FieldArray
)
original
.
unknownFieldData
.
clone
();
}
}
}
javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
View file @
0e122ce8
...
...
@@ -187,4 +187,12 @@ public abstract class MessageNano {
public
String
toString
()
{
return
MessageNanoPrinter
.
print
(
this
);
}
/**
* Provides support for cloning. This only works if you specify the generate_clone method.
*/
@Override
public
MessageNano
clone
()
throws
CloneNotSupportedException
{
return
(
MessageNano
)
super
.
clone
();
}
}
javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
View file @
0e122ce8
...
...
@@ -109,6 +109,10 @@ public final class MessageNanoPrinter {
for
(
Field
field
:
clazz
.
getFields
())
{
int
modifiers
=
field
.
getModifiers
();
String
fieldName
=
field
.
getName
();
if
(
"cachedSize"
.
equals
(
fieldName
))
{
// TODO(bduff): perhaps cachedSize should have a more obscure name.
continue
;
}
if
((
modifiers
&
Modifier
.
PUBLIC
)
==
Modifier
.
PUBLIC
&&
(
modifiers
&
Modifier
.
STATIC
)
!=
Modifier
.
STATIC
...
...
javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
View file @
0e122ce8
...
...
@@ -42,6 +42,10 @@ import java.util.Arrays;
final
class
UnknownFieldData
{
final
int
tag
;
/**
* Important: this should be treated as immutable, even though it's possible
* to change the array values.
*/
final
byte
[]
bytes
;
UnknownFieldData
(
int
tag
,
byte
[]
bytes
)
{
...
...
javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
View file @
0e122ce8
...
...
@@ -31,11 +31,13 @@
package
com
.
google
.
protobuf
.
nano
;
import
com.google.protobuf.nano.MapTestProto.TestMap
;
import
com.google.protobuf.nano.CodedOutputByteBufferNano
;
import
com.google.protobuf.nano.MapTestProto.TestMap.MessageValue
;
import
com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors
;
import
com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas
;
import
com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano
;
import
com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano
;
import
com.google.protobuf.nano.NanoReferenceTypesCompat
;
import
com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano
;
import
com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano
;
import
com.google.protobuf.nano.testext.Extensions
;
...
...
@@ -2300,6 +2302,59 @@ public class NanoTest extends TestCase {
}
}
public
void
testDifferentStringLengthsNano
()
throws
Exception
{
// Test string serialization roundtrip using strings of the following lengths,
// with ASCII and Unicode characters requiring different UTF-8 byte counts per
// char, hence causing the length delimiter varint to sometimes require more
// bytes for the Unicode strings than the ASCII string of the same length.
int
[]
lengths
=
new
int
[]
{
0
,
1
,
(
1
<<
4
)
-
1
,
// 1 byte for ASCII and Unicode
(
1
<<
7
)
-
1
,
// 1 byte for ASCII, 2 bytes for Unicode
(
1
<<
11
)
-
1
,
// 2 bytes for ASCII and Unicode
(
1
<<
14
)
-
1
,
// 2 bytes for ASCII, 3 bytes for Unicode
(
1
<<
17
)
-
1
,
// 3 bytes for ASCII and Unicode
};
for
(
int
i
:
lengths
)
{
testEncodingOfString
(
'q'
,
i
);
// 1 byte per char
testEncodingOfString
(
'\
u07FF
'
,
i
);
// 2 bytes per char
testEncodingOfString
(
'\u0981'
,
i
);
// 3 bytes per char
}
}
/** Regression test for https://github.com/google/protobuf/issues/292 */
public
void
testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace
()
throws
Exception
{
String
testCase
=
"Foooooooo"
;
assertEquals
(
CodedOutputByteBufferNano
.
computeRawVarint32Size
(
testCase
.
length
()),
CodedOutputByteBufferNano
.
computeRawVarint32Size
(
testCase
.
length
()
*
3
));
assertEquals
(
11
,
CodedOutputByteBufferNano
.
computeStringSize
(
1
,
testCase
));
// Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
// An array of size 1 will cause a failure when trying to write the varint.
for
(
int
i
=
0
;
i
<
11
;
i
++)
{
CodedOutputByteBufferNano
bufferNano
=
CodedOutputByteBufferNano
.
newInstance
(
new
byte
[
i
]);
try
{
bufferNano
.
writeString
(
1
,
testCase
);
fail
(
"Should have thrown an out of space exception"
);
}
catch
(
CodedOutputByteBufferNano
.
OutOfSpaceException
expected
)
{}
}
}
private
void
testEncodingOfString
(
char
c
,
int
length
)
throws
InvalidProtocolBufferNanoException
{
TestAllTypesNano
testAllTypesNano
=
new
TestAllTypesNano
();
final
String
fullString
=
fullString
(
c
,
length
);
testAllTypesNano
.
optionalString
=
fullString
;
final
TestAllTypesNano
resultNano
=
new
TestAllTypesNano
();
MessageNano
.
mergeFrom
(
resultNano
,
MessageNano
.
toByteArray
(
testAllTypesNano
));
assertEquals
(
fullString
,
resultNano
.
optionalString
);
}
private
String
fullString
(
char
c
,
int
length
)
{
char
[]
result
=
new
char
[
length
];
Arrays
.
fill
(
result
,
c
);
return
new
String
(
result
);
}
public
void
testNanoWithHasParseFrom
()
throws
Exception
{
TestAllTypesNanoHas
msg
=
null
;
// Test false on creation, after clear and upon empty parse.
...
...
@@ -2986,6 +3041,10 @@ public class NanoTest extends TestCase {
assertTrue
(
Arrays
.
equals
(
floats
,
message
.
getExtension
(
RepeatedExtensions
.
repeatedFloat
)));
assertTrue
(
Arrays
.
equals
(
doubles
,
message
.
getExtension
(
RepeatedExtensions
.
repeatedDouble
)));
assertTrue
(
Arrays
.
equals
(
enums
,
message
.
getExtension
(
RepeatedExtensions
.
repeatedEnum
)));
// Clone the message and ensure it's still equal.
Extensions
.
ExtendableMessage
clone
=
message
.
clone
();
assertEquals
(
clone
,
message
);
}
public
void
testNullExtensions
()
throws
Exception
{
...
...
@@ -4345,6 +4404,11 @@ public class NanoTest extends TestCase {
assertMapSet
(
testMap
.
sfixed64ToSfixed64Field
,
int64Values
,
int64Values
);
}
public
void
testRepeatedFieldInitializedInReftypesCompatMode
()
{
NanoReferenceTypesCompat
.
TestAllTypesNano
proto
=
new
NanoReferenceTypesCompat
.
TestAllTypesNano
();
assertNotNull
(
proto
.
repeatedString
);
}
private
void
assertRepeatedPackablesEqual
(
NanoRepeatedPackables
.
NonPacked
nonPacked
,
NanoRepeatedPackables
.
Packed
packed
)
{
// Not using MessageNano.equals() -- that belongs to a separate test.
...
...
@@ -4364,6 +4428,22 @@ public class NanoTest extends TestCase {
assertTrue
(
Arrays
.
equals
(
nonPacked
.
enums
,
packed
.
enums
));
}
public
void
testClone
()
throws
Exception
{
// A simple message.
AnotherMessage
anotherMessage
=
new
AnotherMessage
();
anotherMessage
.
string
=
"Hello"
;
anotherMessage
.
value
=
true
;
anotherMessage
.
integers
=
new
int
[]
{
1
,
2
,
3
};
AnotherMessage
clone
=
anotherMessage
.
clone
();
assertEquals
(
clone
,
anotherMessage
);
// Verify it was a deep clone - changes to the clone shouldn't affect the
// original.
clone
.
integers
[
1
]
=
100
;
assertFalse
(
clone
.
equals
(
anotherMessage
));
}
private
void
assertHasWireData
(
MessageNano
message
,
boolean
expected
)
{
byte
[]
bytes
=
MessageNano
.
toByteArray
(
message
);
int
wireLength
=
bytes
.
length
;
...
...
javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto
View file @
0e122ce8
...
...
@@ -16,11 +16,15 @@ enum AnEnum {
message
AnotherMessage
{
optional
string
string
=
1
;
optional
bool
value
=
2
;
repeated
int32
integers
=
3
;
}
message
ContainerMessage
{
extend
ExtendableMessage
{
optional
bool
another_thing
=
100
;
// The largest permitted field number, per
// https://developers.google.com/protocol-buffers/docs/proto#simple
optional
bool
large_field_number
=
536870911
;
}
}
...
...
src/google/protobuf/compiler/javanano/javanano_enum.cc
View file @
0e122ce8
...
...
@@ -73,13 +73,45 @@ void EnumGenerator::Generate(io::Printer* printer) {
"// enum $classname$
\n
"
,
"classname"
,
descriptor_
->
name
());
const
string
classname
=
RenameJavaKeywords
(
descriptor_
->
name
());
// Start of container interface
// If generating intdefs, we use the container interface as the intdef if
// present. Otherwise, we just make an empty @interface parallel to the
// constants.
bool
use_intdef
=
params_
.
generate_intdefs
();
bool
use_shell_class
=
params_
.
java_enum_style
();
if
(
use_shell_class
)
{
printer
->
Print
(
"public interface $classname$ {
\n
"
,
"classname"
,
RenameJavaKeywords
(
descriptor_
->
name
()));
if
(
use_intdef
)
{
// @IntDef annotation so tools can enforce correctness
// Annotations will be discarded by the compiler
printer
->
Print
(
"@java.lang.annotation.Retention("
"java.lang.annotation.RetentionPolicy.SOURCE)
\n
"
"@android.support.annotation.IntDef({
\n
"
);
printer
->
Indent
();
for
(
int
i
=
0
;
i
<
canonical_values_
.
size
();
i
++
)
{
const
string
constant_name
=
RenameJavaKeywords
(
canonical_values_
[
i
]
->
name
());
if
(
use_shell_class
)
{
printer
->
Print
(
"$classname$.$name$,
\n
"
,
"classname"
,
classname
,
"name"
,
constant_name
);
}
else
{
printer
->
Print
(
"$name$,
\n
"
,
"name"
,
constant_name
);
}
}
printer
->
Outdent
();
printer
->
Print
(
"})
\n
"
);
}
if
(
use_shell_class
||
use_intdef
)
{
printer
->
Print
(
"public $at_for_intdef$interface $classname$ {
\n
"
,
"classname"
,
classname
,
"at_for_intdef"
,
use_intdef
?
"@"
:
""
);
if
(
use_shell_class
)
{
printer
->
Indent
();
}
else
{
printer
->
Print
(
"}
\n\n
"
);
}
}
// Canonical values
...
...
src/google/protobuf/compiler/javanano/javanano_enum_field.cc
View file @
0e122ce8
...
...
@@ -76,6 +76,10 @@ void SetEnumVariables(const Params& params,
internal
::
WireFormatLite
::
MakeTag
(
descriptor
->
number
(),
internal
::
WireFormat
::
WireTypeForFieldType
(
descriptor
->
type
())));
(
*
variables
)[
"message_name"
]
=
descriptor
->
containing_type
()
->
name
();
const
EnumDescriptor
*
enum_type
=
descriptor
->
enum_type
();
(
*
variables
)[
"message_type_intdef"
]
=
"@"
+
ToJavaName
(
params
,
enum_type
->
name
(),
true
,
enum_type
->
containing_type
(),
enum_type
->
file
());
}
void
LoadEnumValues
(
const
Params
&
params
,
...
...
@@ -116,8 +120,10 @@ EnumFieldGenerator::~EnumFieldGenerator() {}
void
EnumFieldGenerator
::
GenerateMembers
(
io
::
Printer
*
printer
,
bool
/* unused lazy_init */
)
const
{
printer
->
Print
(
variables_
,
"public $type$ $name$;
\n
"
);
if
(
params_
.
generate_intdefs
())
{
printer
->
Print
(
variables_
,
"$message_type_intdef$
\n
"
);
}
printer
->
Print
(
variables_
,
"public $type$ $name$;
\n
"
);
if
(
params_
.
generate_has
())
{
printer
->
Print
(
variables_
,
...
...
@@ -256,12 +262,22 @@ AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {}
void
AccessorEnumFieldGenerator
::
GenerateMembers
(
io
::
Printer
*
printer
,
bool
/* unused lazy_init */
)
const
{
printer
->
Print
(
variables_
,
"private int $name$_;
\n
"
);
if
(
params_
.
generate_intdefs
())
{
printer
->
Print
(
variables_
,
"$message_type_intdef$
\n
"
);
}
printer
->
Print
(
variables_
,
"private int $name$_;
\n
"
"public int get$capitalized_name$() {
\n
"
" return $name$_;
\n
"
"}
\n
"
"public $message_name$ set$capitalized_name$(int value) {
\n
"
"public $message_name$ set$capitalized_name$("
);
if
(
params_
.
generate_intdefs
())
{
printer
->
Print
(
variables_
,
"
\n
"
" $message_type_intdef$ "
);
}
printer
->
Print
(
variables_
,
"int value) {
\n
"
" $name$_ = value;
\n
"
" $set_has$;
\n
"
" return this;
\n
"
...
...
@@ -498,6 +514,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}
\n
"
);
}
void
RepeatedEnumFieldGenerator
::
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
"if (this.$name$ != null && this.$name$.length > 0) {
\n
"
" cloned.$name$ = this.$name$.clone();
\n
"
"}
\n
"
);
}
void
RepeatedEnumFieldGenerator
::
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
...
...
src/google/protobuf/compiler/javanano/javanano_enum_field.h
View file @
0e122ce8
...
...
@@ -106,6 +106,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
;
private
:
void
GenerateRepeatedDataSizeCode
(
io
::
Printer
*
printer
)
const
;
...
...
src/google/protobuf/compiler/javanano/javanano_extension.cc
View file @
0e122ce8
...
...
@@ -140,7 +140,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) const {
" com.google.protobuf.nano.Extension.create$repeated$$ext_type$(
\n
"
" com.google.protobuf.nano.Extension.$type$,
\n
"
" $class$.class,
\n
"
" $tag_params$);
\n
"
);
" $tag_params$
L
);
\n
"
);
}
}
// namespace javanano
...
...
src/google/protobuf/compiler/javanano/javanano_field.h
View file @
0e122ce8
...
...
@@ -83,6 +83,7 @@ class FieldGenerator {
virtual
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
=
0
;
virtual
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
=
0
;
virtual
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
=
0
;
virtual
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{}
protected
:
const
Params
&
params_
;
...
...
src/google/protobuf/compiler/javanano/javanano_generator.cc
View file @
0e122ce8
...
...
@@ -152,6 +152,12 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file,
params
.
set_ignore_services
(
option_value
==
"true"
);
}
else
if
(
option_name
==
"parcelable_messages"
)
{
params
.
set_parcelable_messages
(
option_value
==
"true"
);
}
else
if
(
option_name
==
"generate_clone"
)
{
params
.
set_generate_clone
(
option_value
==
"true"
);
}
else
if
(
option_name
==
"generate_intdefs"
)
{
params
.
set_generate_intdefs
(
option_value
==
"true"
);
}
else
if
(
option_name
==
"generate_clear"
)
{
params
.
set_generate_clear
(
option_value
==
"true"
);
}
else
{
*
error
=
"Ignore unknown javanano generator option: "
+
option_name
;
}
...
...
src/google/protobuf/compiler/javanano/javanano_message.cc
View file @
0e122ce8
...
...
@@ -136,21 +136,37 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
if
(
params_
.
store_unknown_fields
()
&&
params_
.
parcelable_messages
())
{
printer
->
Print
(
" com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>
{
\n
"
,
" com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>"
,
"classname"
,
descriptor_
->
name
());
}
else
if
(
params_
.
store_unknown_fields
())
{
printer
->
Print
(
" com.google.protobuf.nano.ExtendableMessageNano<$classname$>
{
\n
"
,
" com.google.protobuf.nano.ExtendableMessageNano<$classname$>"
,
"classname"
,
descriptor_
->
name
());
}
else
if
(
params_
.
parcelable_messages
())
{
printer
->
Print
(
" com.google.protobuf.nano.android.ParcelableMessageNano
{
\n
"
);
" com.google.protobuf.nano.android.ParcelableMessageNano"
);
}
else
{
printer
->
Print
(
" com.google.protobuf.nano.MessageNano {
\n
"
);
" com.google.protobuf.nano.MessageNano"
);
}
if
(
params_
.
generate_clone
())
{
printer
->
Print
(
" implements java.lang.Cloneable {
\n
"
);
}
else
{
printer
->
Print
(
" {
\n
"
);
}
printer
->
Indent
();
if
(
params_
.
parcelable_messages
())
{
printer
->
Print
(
"
\n
"
"// Used by Parcelable
\n
"
"@SuppressWarnings({
\"
unused
\"
})
\n
"
"public static final android.os.Parcelable.Creator<$classname$> CREATOR =
\n
"
" new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<
\n
"
" $classname$>($classname$.class);
\n
"
,
"classname"
,
descriptor_
->
name
());
}
// Nested types and extensions
for
(
int
i
=
0
;
i
<
descriptor_
->
extension_count
();
i
++
)
{
ExtensionGenerator
(
descriptor_
->
extension
(
i
),
params_
).
Generate
(
printer
);
...
...
@@ -288,20 +304,28 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
printer
->
Print
(
"}
\n
"
);
}
else
{
printer
->
Print
(
"
\n
"
"public $classname$() {
\n
"
,
"classname"
,
descriptor_
->
name
());
if
(
params_
.
generate_clear
())
{
printer
->
Print
(
"
\n
"
"public $classname$() {
\n
"
" clear();
\n
"
"}
\n
"
,
"classname"
,
descriptor_
->
name
());
printer
->
Print
(
" clear();
\n
"
);
}
else
{
printer
->
Indent
();
GenerateFieldInitializers
(
printer
);
printer
->
Outdent
();
}
printer
->
Print
(
"}
\n
"
);
}
// Other methods in this class
GenerateClear
(
printer
);
if
(
params_
.
generate_clone
())
{
GenerateClone
(
printer
);
}
if
(
params_
.
generate_equals
())
{
GenerateEquals
(
printer
);
GenerateHashCode
(
printer
);
...
...
@@ -495,6 +519,15 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
"classname"
,
descriptor_
->
name
());
printer
->
Indent
();
GenerateFieldInitializers
(
printer
);
printer
->
Outdent
();
printer
->
Print
(
" return this;
\n
"
"}
\n
"
);
}
void
MessageGenerator
::
GenerateFieldInitializers
(
io
::
Printer
*
printer
)
{
// Clear bit fields.
int
totalInts
=
(
field_generators_
.
total_bits
()
+
31
)
/
32
;
for
(
int
i
=
0
;
i
<
totalInts
;
i
++
)
{
...
...
@@ -520,12 +553,34 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
if
(
params_
.
store_unknown_fields
())
{
printer
->
Print
(
"unknownFieldData = null;
\n
"
);
}
printer
->
Print
(
"cachedSize = -1;
\n
"
);
}
void
MessageGenerator
::
GenerateClone
(
io
::
Printer
*
printer
)
{
printer
->
Print
(
"@Override
\n
"
"public $classname$ clone() {
\n
"
,
"classname"
,
descriptor_
->
name
());
printer
->
Indent
();
printer
->
Print
(
"$classname$ cloned;
\n
"
"try {
\n
"
" cloned = ($classname$) super.clone();
\n
"
"} catch (java.lang.CloneNotSupportedException e) {
\n
"
" throw new java.lang.AssertionError(e);
\n
"
"}
\n
"
,
"classname"
,
descriptor_
->
name
());
for
(
int
i
=
0
;
i
<
descriptor_
->
field_count
();
i
++
)
{
field_generators_
.
get
(
descriptor_
->
field
(
i
)).
GenerateFixClonedCode
(
printer
);
}
printer
->
Outdent
();
printer
->
Print
(
"
cachedSize = -1
;
\n
"
"
return this;
\n
"
"
}
\n
"
);
"
return cloned
;
\n
"
"
}
\n
"
"
\n
"
);
}
void
MessageGenerator
::
GenerateEquals
(
io
::
Printer
*
printer
)
{
...
...
@@ -568,7 +623,11 @@ void MessageGenerator::GenerateEquals(io::Printer* printer) {
if
(
params_
.
store_unknown_fields
())
{
printer
->
Print
(
"return unknownFieldDataEquals(other);
\n
"
);
"if (unknownFieldData == null || unknownFieldData.isEmpty()) {
\n
"
" return other.unknownFieldData == null || other.unknownFieldData.isEmpty();
\n
"
"} else {
\n
"
" return unknownFieldData.equals(other.unknownFieldData);
\n
"
"}"
);
}
else
{
printer
->
Print
(
"return true;
\n
"
);
...
...
@@ -598,7 +657,9 @@ void MessageGenerator::GenerateHashCode(io::Printer* printer) {
if
(
params_
.
store_unknown_fields
())
{
printer
->
Print
(
"result = 31 * result + unknownFieldDataHashCode();
\n
"
);
"result = 31 * result +
\n
"
" (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 :
\n
"
" unknownFieldData.hashCode());
\n
"
);
}
printer
->
Print
(
"return result;
\n
"
);
...
...
src/google/protobuf/compiler/javanano/javanano_message.h
View file @
0e122ce8
...
...
@@ -77,8 +77,10 @@ class MessageGenerator {
const
FieldDescriptor
*
field
);
void
GenerateClear
(
io
::
Printer
*
printer
);
void
GenerateFieldInitializers
(
io
::
Printer
*
printer
);
void
GenerateEquals
(
io
::
Printer
*
printer
);
void
GenerateHashCode
(
io
::
Printer
*
printer
);
void
GenerateClone
(
io
::
Printer
*
printer
);
const
Params
&
params_
;
const
Descriptor
*
descriptor_
;
...
...
src/google/protobuf/compiler/javanano/javanano_message_field.cc
View file @
0e122ce8
...
...
@@ -126,6 +126,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}
\n
"
);
}
void
MessageFieldGenerator
::
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
"if (this.$name$ != null) {
\n
"
" cloned.$name$ = this.$name$.clone();
\n
"
"}
\n
"
);
}
void
MessageFieldGenerator
::
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
...
...
@@ -212,6 +220,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}
\n
"
);
}
void
MessageOneofFieldGenerator
::
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
"if (this.$oneof_name$ != null) {
\n
"
" cloned.$oneof_name$ = this.$oneof_name$.clone();
\n
"
"}
\n
"
);
}
void
MessageOneofFieldGenerator
::
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
{
GenerateOneofFieldEquals
(
descriptor_
,
variables_
,
printer
);
...
...
@@ -312,6 +328,19 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}
\n
"
);
}
void
RepeatedMessageFieldGenerator
::
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
"if (this.$name$ != null && this.$name$.length > 0) {
\n
"
" cloned.$name$ = new $type$[this.$name$.length];
\n
"
" for (int i = 0; i < this.$name$.length; i++) {
\n
"
" if (this.$name$[i] != null) {
\n
"
" cloned.$name$[i] = this.$name$[i].clone();
\n
"
" }
\n
"
" }
\n
"
"}
\n
"
);
}
void
RepeatedMessageFieldGenerator
::
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
...
...
src/google/protobuf/compiler/javanano/javanano_message_field.h
View file @
0e122ce8
...
...
@@ -58,6 +58,7 @@ class MessageFieldGenerator : public FieldGenerator {
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
;
private
:
const
FieldDescriptor
*
descriptor_
;
...
...
@@ -80,6 +81,7 @@ class MessageOneofFieldGenerator : public FieldGenerator {
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
;
private
:
const
FieldDescriptor
*
descriptor_
;
...
...
@@ -102,6 +104,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
;
private
:
const
FieldDescriptor
*
descriptor_
;
...
...
src/google/protobuf/compiler/javanano/javanano_params.h
View file @
0e122ce8
...
...
@@ -66,6 +66,8 @@ class Params {
bool
parcelable_messages_
;
bool
reftypes_primitive_enums_
;
bool
generate_clear_
;
bool
generate_clone_
;
bool
generate_intdefs_
;
public
:
Params
(
const
string
&
base_name
)
:
...
...
@@ -81,7 +83,9 @@ class Params {
ignore_services_
(
false
),
parcelable_messages_
(
false
),
reftypes_primitive_enums_
(
false
),
generate_clear_
(
true
)
{
generate_clear_
(
true
),
generate_clone_
(
false
),
generate_intdefs_
(
false
)
{
}
const
string
&
base_name
()
const
{
...
...
@@ -231,6 +235,20 @@ class Params {
bool
generate_clear
()
const
{
return
generate_clear_
;
}
void
set_generate_clone
(
bool
value
)
{
generate_clone_
=
value
;
}
bool
generate_clone
()
const
{
return
generate_clone_
;
}
void
set_generate_intdefs
(
bool
value
)
{
generate_intdefs_
=
value
;
}
bool
generate_intdefs
()
const
{
return
generate_intdefs_
;
}
};
}
// namespace javanano
...
...
src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
View file @
0e122ce8
...
...
@@ -364,6 +364,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
}
}
void
RepeatedPrimitiveFieldGenerator
::
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
"if (this.$name$ != null && this.$name$.length > 0) {
\n
"
" cloned.$name$ = this.$name$.clone();
\n
"
"}
\n
"
);
}
void
PrimitiveFieldGenerator
::
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
{
// We define equality as serialized form equality. If generate_has(),
...
...
src/google/protobuf/compiler/javanano/javanano_primitive_field.h
View file @
0e122ce8
...
...
@@ -131,6 +131,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
void
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateEqualsCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateHashCodeCode
(
io
::
Printer
*
printer
)
const
;
void
GenerateFixClonedCode
(
io
::
Printer
*
printer
)
const
;
private
:
void
GenerateRepeatedDataSizeCode
(
io
::
Printer
*
printer
)
const
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment