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
190edd7e
Commit
190edd7e
authored
Nov 15, 2013
by
Max Cai
Committed by
Gerrit Code Review
Nov 15, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Update MessageNano#toString() to return mostly valid TextFormat."
parents
558af242
904c81ee
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
40 deletions
+84
-40
MessageNano.java
java/src/main/java/com/google/protobuf/nano/MessageNano.java
+4
-1
MessageNanoPrinter.java
...ain/java/com/google/protobuf/nano/MessageNanoPrinter.java
+55
-17
NanoTest.java
java/src/test/java/com/google/protobuf/NanoTest.java
+25
-22
No files found.
java/src/main/java/com/google/protobuf/nano/MessageNano.java
View file @
190edd7e
...
...
@@ -139,7 +139,10 @@ public abstract class MessageNano {
}
/**
* Intended for debugging purposes only. It does not use ASCII protobuf formatting.
* 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.
*/
@Override
public
String
toString
()
{
...
...
java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
View file @
190edd7e
...
...
@@ -47,20 +47,22 @@ public final class MessageNanoPrinter {
private
static
final
int
MAX_STRING_LEN
=
200
;
/**
* Returns an text representation of a MessageNano suitable for debugging.
* Returns an text representation of a MessageNano suitable for debugging. The returned string
* is mostly compatible with Protocol Buffer's TextFormat (as provided by non-nano protocol
* buffers) -- groups (which are deprecated) are output with an underscore name (e.g. foo_bar
* instead of FooBar) and will thus not parse.
*
* <p>Employs Java reflection on the given object and recursively prints primitive fields,
* groups, and messages.</p>
*/
public
static
<
T
extends
MessageNano
>
String
print
(
T
message
)
{
if
(
message
==
null
)
{
return
"
null
"
;
return
""
;
}
StringBuffer
buf
=
new
StringBuffer
();
try
{
print
(
message
.
getClass
().
getSimpleName
(),
message
.
getClass
(),
message
,
new
StringBuffer
(),
buf
);
print
(
null
,
message
.
getClass
(),
message
,
new
StringBuffer
(),
buf
);
}
catch
(
IllegalAccessException
e
)
{
return
"Error printing proto: "
+
e
.
getMessage
();
}
...
...
@@ -70,21 +72,30 @@ public final class MessageNanoPrinter {
/**
* Function that will print the given message/class into the StringBuffer.
* Meant to be called recursively.
*
* @param identifier the identifier to use, or {@code null} if this is the root message to
* print.
* @param clazz the class of {@code message}.
* @param message the value to print. May in fact be a primitive value or byte array and not a
* message.
* @param indentBuf the indentation each line should begin with.
* @param buf the output buffer.
*/
private
static
void
print
(
String
identifier
,
Class
<?>
clazz
,
Object
message
,
StringBuffer
indentBuf
,
StringBuffer
buf
)
throws
IllegalAccessException
{
if
(
MessageNano
.
class
.
isAssignableFrom
(
clazz
))
{
// Nano proto message
buf
.
append
(
indentBuf
).
append
(
identifier
);
// If null, just print it and return
if
(
message
==
null
)
{
buf
.
append
(
": "
).
append
(
message
).
append
(
"\n"
);
return
;
if
(
message
==
null
)
{
// This can happen if...
// - we're about to print a message, String, or byte[], but it not present;
// - we're about to print a primitive, but "reftype" optional style is enabled, and
// the field is unset.
// In both cases the appropriate behavior is to output nothing.
}
else
if
(
MessageNano
.
class
.
isAssignableFrom
(
clazz
))
{
// Nano proto message
int
origIndentBufLength
=
indentBuf
.
length
();
if
(
identifier
!=
null
)
{
buf
.
append
(
indentBuf
).
append
(
deCamelCaseify
(
identifier
)).
append
(
" <\n"
);
indentBuf
.
append
(
INDENT
);
}
indentBuf
.
append
(
INDENT
);
buf
.
append
(
" <\n"
);
for
(
Field
field
:
clazz
.
getFields
())
{
// Proto fields are public, non-static variables that do not begin or end with '_'
int
modifiers
=
field
.
getModifiers
();
...
...
@@ -115,15 +126,19 @@ public final class MessageNanoPrinter {
print
(
fieldName
,
fieldType
,
value
,
indentBuf
,
buf
);
}
}
indentBuf
.
delete
(
indentBuf
.
length
()
-
INDENT
.
length
(),
indentBuf
.
length
());
buf
.
append
(
indentBuf
).
append
(
">\n"
);
if
(
identifier
!=
null
)
{
indentBuf
.
setLength
(
origIndentBufLength
);
buf
.
append
(
indentBuf
).
append
(
">\n"
);
}
}
else
{
//
P
rimitive value
//
Non-null p
rimitive value
identifier
=
deCamelCaseify
(
identifier
);
buf
.
append
(
indentBuf
).
append
(
identifier
).
append
(
": "
);
if
(
message
instanceof
String
)
{
String
stringMessage
=
sanitizeString
((
String
)
message
);
buf
.
append
(
"\""
).
append
(
stringMessage
).
append
(
"\""
);
}
else
if
(
message
instanceof
byte
[])
{
appendQuotedBytes
((
byte
[])
message
,
buf
);
}
else
{
buf
.
append
(
message
);
}
...
...
@@ -176,4 +191,27 @@ public final class MessageNanoPrinter {
}
return
b
.
toString
();
}
/**
* Appends a quoted byte array to the provided {@code StringBuffer}.
*/
private
static
void
appendQuotedBytes
(
byte
[]
bytes
,
StringBuffer
builder
)
{
if
(
bytes
==
null
)
{
builder
.
append
(
"\"\""
);
return
;
}
builder
.
append
(
'"'
);
for
(
int
i
=
0
;
i
<
bytes
.
length
;
++
i
)
{
int
ch
=
bytes
[
i
];
if
(
ch
==
'\\'
||
ch
==
'"'
)
{
builder
.
append
(
'\\'
).
append
((
char
)
ch
);
}
else
if
(
ch
>=
32
&&
ch
<
127
)
{
builder
.
append
((
char
)
ch
);
}
else
{
builder
.
append
(
String
.
format
(
"\\%03o"
,
ch
));
}
}
builder
.
append
(
'"'
);
}
}
java/src/test/java/com/google/protobuf/NanoTest.java
View file @
190edd7e
...
...
@@ -2490,14 +2490,14 @@ public class NanoTest extends TestCase {
msg
.
optionalInt32
=
14
;
msg
.
optionalFloat
=
42.3f
;
msg
.
optionalString
=
"String \"with' both quotes"
;
msg
.
optionalBytes
=
new
byte
[
5
]
;
msg
.
optionalBytes
=
new
byte
[
]
{
'"'
,
'\0'
,
1
,
8
}
;
msg
.
optionalGroup
=
new
TestAllTypesNano
.
OptionalGroup
();
msg
.
optionalGroup
.
a
=
15
;
msg
.
repeatedInt64
=
new
long
[
2
];
msg
.
repeatedInt64
[
0
]
=
1L
;
msg
.
repeatedInt64
[
1
]
=
-
1L
;
msg
.
repeatedBytes
=
new
byte
[
2
][];
msg
.
repeatedBytes
[
1
]
=
new
byte
[
5
]
;
msg
.
repeatedBytes
[
1
]
=
new
byte
[
]
{
'h'
,
'e'
,
'l'
,
'l'
,
'o'
}
;
msg
.
repeatedGroup
=
new
TestAllTypesNano
.
RepeatedGroup
[
2
];
msg
.
repeatedGroup
[
0
]
=
new
TestAllTypesNano
.
RepeatedGroup
();
msg
.
repeatedGroup
[
0
].
a
=
-
27
;
...
...
@@ -2514,28 +2514,31 @@ public class NanoTest extends TestCase {
msg
.
repeatedNestedEnum
=
new
int
[
2
];
msg
.
repeatedNestedEnum
[
0
]
=
TestAllTypesNano
.
BAR
;
msg
.
repeatedNestedEnum
[
1
]
=
TestAllTypesNano
.
FOO
;
msg
.
repeatedStringPiece
=
new
String
[]
{
null
,
"world"
};
String
protoPrint
=
msg
.
toString
();
assertTrue
(
protoPrint
.
contains
(
"TestAllTypesNano <"
));
assertTrue
(
protoPrint
.
contains
(
" optional_int32: 14"
));
assertTrue
(
protoPrint
.
contains
(
" optional_float: 42.3"
));
assertTrue
(
protoPrint
.
contains
(
" optional_double: 0.0"
));
assertTrue
(
protoPrint
.
contains
(
" optional_string: \"String \\u0022with\\u0027 both quotes\""
));
assertTrue
(
protoPrint
.
contains
(
" optional_bytes: [B@"
));
assertTrue
(
protoPrint
.
contains
(
" optionalGroup <\n a: 15\n >"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_int64: 1"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_int64: -1"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_bytes: null\n repeated_bytes: [B@"
));
assertTrue
(
protoPrint
.
contains
(
" repeatedGroup <\n a: -27\n >\n"
+
" repeatedGroup <\n a: -72\n >"
));
assertTrue
(
protoPrint
.
contains
(
" optionalNestedMessage <\n bb: 7\n >"
));
assertTrue
(
protoPrint
.
contains
(
" repeatedNestedMessage <\n bb: 77\n >\n"
+
" repeatedNestedMessage <\n bb: 88\n >"
));
assertTrue
(
protoPrint
.
contains
(
" optional_nested_enum: 3"
));
assertTrue
(
protoPrint
.
contains
(
" repeated_nested_enum: 2\n repeated_nested_enum: 1"
));
assertTrue
(
protoPrint
.
contains
(
" default_int32: 41"
));
assertTrue
(
protoPrint
.
contains
(
" default_string: \"hello\""
));
assertTrue
(
protoPrint
.
contains
(
"optional_int32: 14"
));
assertTrue
(
protoPrint
.
contains
(
"optional_float: 42.3"
));
assertTrue
(
protoPrint
.
contains
(
"optional_double: 0.0"
));
assertTrue
(
protoPrint
.
contains
(
"optional_string: \"String \\u0022with\\u0027 both quotes\""
));
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"
));
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"
+
"repeated_group <\n a: -72\n>"
));
assertTrue
(
protoPrint
.
contains
(
"optional_nested_message <\n bb: 7\n>"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_nested_message <\n bb: 77\n>\n"
+
"repeated_nested_message <\n bb: 88\n>"
));
assertTrue
(
protoPrint
.
contains
(
"optional_nested_enum: 3"
));
assertTrue
(
protoPrint
.
contains
(
"repeated_nested_enum: 2\nrepeated_nested_enum: 1"
));
assertTrue
(
protoPrint
.
contains
(
"default_int32: 41"
));
assertTrue
(
protoPrint
.
contains
(
"default_string: \"hello\""
));
assertFalse
(
protoPrint
.
contains
(
"repeated_string_piece: \"\""
));
// null should be dropped
assertTrue
(
protoPrint
.
contains
(
"repeated_string_piece: \"world\""
));
}
public
void
testExtensions
()
throws
Exception
{
...
...
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