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
0c0f8c7e
Commit
0c0f8c7e
authored
Dec 19, 2013
by
Andrew Flynn
Committed by
Gerrit Code Review
Dec 19, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Fix MessageNanoPrinter for accessors"
parents
b3bc6095
02a9ea00
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
102 additions
and
25 deletions
+102
-25
MessageNano.java
java/src/main/java/com/google/protobuf/nano/MessageNano.java
+2
-1
MessageNanoPrinter.java
...ain/java/com/google/protobuf/nano/MessageNanoPrinter.java
+63
-22
NanoTest.java
java/src/test/java/com/google/protobuf/NanoTest.java
+37
-2
No files found.
java/src/main/java/com/google/protobuf/nano/MessageNano.java
View file @
0c0f8c7e
...
...
@@ -142,7 +142,8 @@ public abstract class MessageNano {
* Returns a string that is (mostly) compatible with ProtoBuffer's TextFormat. Note that groups
* (which are deprecated) are not serialized with the correct field name.
*
* <p>This is implemented using reflection, so it is not especially fast.
* <p>This is implemented using reflection, so it is not especially fast nor is it guaranteed
* to find all fields if you have method removal turned on for proguard.
*/
@Override
public
String
toString
()
{
...
...
java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
View file @
0c0f8c7e
...
...
@@ -32,6 +32,8 @@ package com.google.protobuf.nano;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
/**
...
...
@@ -65,6 +67,8 @@ public final class MessageNanoPrinter {
print
(
null
,
message
,
new
StringBuffer
(),
buf
);
}
catch
(
IllegalAccessException
e
)
{
return
"Error printing proto: "
+
e
.
getMessage
();
}
catch
(
InvocationTargetException
e
)
{
return
"Error printing proto: "
+
e
.
getMessage
();
}
return
buf
.
toString
();
}
...
...
@@ -81,7 +85,8 @@ public final class MessageNanoPrinter {
* @param buf the output buffer.
*/
private
static
void
print
(
String
identifier
,
Object
object
,
StringBuffer
indentBuf
,
StringBuffer
buf
)
throws
IllegalAccessException
{
StringBuffer
indentBuf
,
StringBuffer
buf
)
throws
IllegalAccessException
,
InvocationTargetException
{
if
(
object
==
null
)
{
// This can happen if...
// - we're about to print a message, String, or byte[], but it not present;
...
...
@@ -94,35 +99,71 @@ public final class MessageNanoPrinter {
buf
.
append
(
indentBuf
).
append
(
deCamelCaseify
(
identifier
)).
append
(
" <\n"
);
indentBuf
.
append
(
INDENT
);
}
Class
<?>
clazz
=
object
.
getClass
();
for
(
Field
field
:
object
.
getClass
().
getFields
())
{
// Proto fields are public, non-static variables that do not begin or end with '_'
// Proto fields follow one of two formats:
//
// 1) Public, non-static variables that do not begin or end with '_'
// Find and print these using declared public fields
for
(
Field
field
:
clazz
.
getFields
())
{
int
modifiers
=
field
.
getModifiers
();
String
fieldName
=
field
.
getName
();
if
((
modifiers
&
Modifier
.
PUBLIC
)
!=
Modifier
.
PUBLIC
||
(
modifiers
&
Modifier
.
STATIC
)
==
Modifier
.
STATIC
||
fieldName
.
startsWith
(
"_"
)
||
fieldName
.
endsWith
(
"_"
))
{
continue
;
}
Class
<?>
fieldType
=
field
.
getType
();
Object
value
=
field
.
get
(
object
);
if
((
modifiers
&
Modifier
.
PUBLIC
)
==
Modifier
.
PUBLIC
&&
(
modifiers
&
Modifier
.
STATIC
)
!=
Modifier
.
STATIC
&&
!
fieldName
.
startsWith
(
"_"
)
&&
!
fieldName
.
endsWith
(
"_"
))
{
Class
<?>
fieldType
=
field
.
getType
();
Object
value
=
field
.
get
(
object
);
if
(
fieldType
.
isArray
())
{
Class
<?>
arrayType
=
fieldType
.
getComponentType
();
if
(
fieldType
.
isArray
())
{
Class
<?>
arrayType
=
fieldType
.
getComponentType
();
// bytes is special since it's not repeated, but is represented by an array
if
(
arrayType
==
byte
.
class
)
{
print
(
fieldName
,
value
,
indentBuf
,
buf
);
}
else
{
int
len
=
value
==
null
?
0
:
Array
.
getLength
(
value
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Object
elem
=
Array
.
get
(
value
,
i
);
print
(
fieldName
,
elem
,
indentBuf
,
buf
);
// bytes is special since it's not repeated, but is represented by an array
if
(
arrayType
==
byte
.
class
)
{
print
(
fieldName
,
value
,
indentBuf
,
buf
);
}
else
{
int
len
=
value
==
null
?
0
:
Array
.
getLength
(
value
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Object
elem
=
Array
.
get
(
value
,
i
);
print
(
fieldName
,
elem
,
indentBuf
,
buf
);
}
}
}
else
{
print
(
fieldName
,
value
,
indentBuf
,
buf
);
}
}
else
{
print
(
fieldName
,
value
,
indentBuf
,
buf
);
}
}
// 2) Fields that are accessed via getter methods (when accessors
// mode is turned on)
// Find and print these using getter methods.
for
(
Method
method
:
clazz
.
getMethods
())
{
String
name
=
method
.
getName
();
// Check for the setter accessor method since getters and hazzers both have
// non-proto-field name collisions (hashCode() and getSerializedSize())
if
(
name
.
startsWith
(
"set"
))
{
String
subfieldName
=
name
.
substring
(
3
);
Method
hazzer
=
null
;
try
{
hazzer
=
clazz
.
getMethod
(
"has"
+
subfieldName
);
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
// If hazzer does't exist or returns false, no need to continue
if
(!(
Boolean
)
hazzer
.
invoke
(
object
))
{
continue
;
}
Method
getter
=
null
;
try
{
getter
=
clazz
.
getMethod
(
"get"
+
subfieldName
);
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
print
(
subfieldName
,
getter
.
invoke
(
object
),
indentBuf
,
buf
);
}
}
if
(
identifier
!=
null
)
{
...
...
java/src/test/java/com/google/protobuf/NanoTest.java
View file @
0c0f8c7e
...
...
@@ -2553,8 +2553,7 @@ public class NanoTest extends TestCase {
assertTrue
(
protoPrint
.
contains
(
"optional_bytes: \"\\\"\\000\\001\\010\""
));
assertTrue
(
protoPrint
.
contains
(
"optional_group <\n a: 15\n>"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_int64: 1"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_int64: -1"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_int64: 1\nrepeated_int64: -1"
));
assertFalse
(
protoPrint
.
contains
(
"repeated_bytes: \"\""
));
// null should be dropped
assertTrue
(
protoPrint
.
contains
(
"repeated_bytes: \"hello\""
));
assertTrue
(
protoPrint
.
contains
(
"repeated_group <\n a: -27\n>\n"
...
...
@@ -2570,6 +2569,42 @@ public class NanoTest extends TestCase {
assertTrue
(
protoPrint
.
contains
(
"repeated_string_piece: \"world\""
));
}
public
void
testMessageNanoPrinterAccessors
()
throws
Exception
{
TestNanoAccessors
msg
=
new
TestNanoAccessors
();
msg
.
setOptionalInt32
(
13
);
msg
.
setOptionalString
(
"foo"
);
msg
.
setOptionalBytes
(
new
byte
[]
{
'"'
,
'\0'
,
1
,
8
});
msg
.
optionalNestedMessage
=
new
TestNanoAccessors
.
NestedMessage
();
msg
.
optionalNestedMessage
.
setBb
(
7
);
msg
.
setOptionalNestedEnum
(
TestNanoAccessors
.
BAZ
);
msg
.
repeatedInt32
=
new
int
[]
{
1
,
-
1
};
msg
.
repeatedString
=
new
String
[]
{
"Hello"
,
"world"
};
msg
.
repeatedBytes
=
new
byte
[
2
][];
msg
.
repeatedBytes
[
1
]
=
new
byte
[]
{
'h'
,
'e'
,
'l'
,
'l'
,
'o'
};
msg
.
repeatedNestedMessage
=
new
TestNanoAccessors
.
NestedMessage
[
2
];
msg
.
repeatedNestedMessage
[
0
]
=
new
TestNanoAccessors
.
NestedMessage
();
msg
.
repeatedNestedMessage
[
0
].
setBb
(
5
);
msg
.
repeatedNestedMessage
[
1
]
=
new
TestNanoAccessors
.
NestedMessage
();
msg
.
repeatedNestedMessage
[
1
].
setBb
(
6
);
msg
.
repeatedNestedEnum
=
new
int
[]
{
TestNanoAccessors
.
FOO
,
TestNanoAccessors
.
BAR
};
msg
.
id
=
33
;
String
protoPrint
=
msg
.
toString
();
assertTrue
(
protoPrint
.
contains
(
"optional_int32: 13"
));
assertTrue
(
protoPrint
.
contains
(
"optional_string: \"foo\""
));
assertTrue
(
protoPrint
.
contains
(
"optional_bytes: \"\\\"\\000\\001\\010\""
));
assertTrue
(
protoPrint
.
contains
(
"optional_nested_message <\n bb: 7\n>"
));
assertTrue
(
protoPrint
.
contains
(
"optional_nested_enum: 3"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_int32: 1\nrepeated_int32: -1"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_string: \"Hello\"\nrepeated_string: \"world\""
));
assertFalse
(
protoPrint
.
contains
(
"repeated_bytes: \"\""
));
// null should be dropped
assertTrue
(
protoPrint
.
contains
(
"repeated_bytes: \"hello\""
));
assertTrue
(
protoPrint
.
contains
(
"repeated_nested_message <\n bb: 5\n>\n"
+
"repeated_nested_message <\n bb: 6\n>"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_nested_enum: 1\nrepeated_nested_enum: 2"
));
assertTrue
(
protoPrint
.
contains
(
"id: 33"
));
}
public
void
testExtensions
()
throws
Exception
{
Extensions
.
ExtendableMessage
message
=
new
Extensions
.
ExtendableMessage
();
message
.
field
=
5
;
...
...
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