Skip to content

Commit 055297b

Browse files
Automated rollback of commit 6d2f6fc.
PiperOrigin-RevId: 731383560
1 parent 365ae12 commit 055297b

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

java/core/src/main/java/com/google/protobuf/TextFormat.java

+45-8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ private TextFormat() {}
3838

3939
private static final Logger logger = Logger.getLogger(TextFormat.class.getName());
4040

41+
private static final String DEBUG_STRING_SILENT_MARKER = " \t ";
42+
4143
private static final String REDACTED_MARKER = "[REDACTED]";
4244

4345
/**
@@ -998,6 +1000,15 @@ private static final class Tokenizer {
9981000
private int previousLine = 0;
9991001
private int previousColumn = 0;
10001002

1003+
/**
1004+
* {@link containsSilentMarkerAfterCurrentToken} indicates if there is a silent marker after the
1005+
* current token. This value is moved to {@link containsSilentMarkerAfterPrevToken} every time
1006+
* the next token is parsed.
1007+
*/
1008+
private boolean containsSilentMarkerAfterCurrentToken = false;
1009+
1010+
private boolean containsSilentMarkerAfterPrevToken = false;
1011+
10011012
/** Construct a tokenizer that parses tokens from the given text. */
10021013
private Tokenizer(final CharSequence text) {
10031014
this.text = text;
@@ -1021,6 +1032,14 @@ int getColumn() {
10211032
return column;
10221033
}
10231034

1035+
boolean getContainsSilentMarkerAfterCurrentToken() {
1036+
return containsSilentMarkerAfterCurrentToken;
1037+
}
1038+
1039+
boolean getContainsSilentMarkerAfterPrevToken() {
1040+
return containsSilentMarkerAfterPrevToken;
1041+
}
1042+
10241043
/** Are we at the end of the input? */
10251044
boolean atEnd() {
10261045
return currentToken.length() == 0;
@@ -1709,6 +1728,19 @@ public static <T extends Message> T parse(
17091728
* control the parser behavior.
17101729
*/
17111730
public static class Parser {
1731+
1732+
/**
1733+
* A valid silent marker appears between a field name and its value. If there is a ":" in
1734+
* between, the silent marker will only appear after the colon. This is called after a field
1735+
* name is parsed, and before the ":" if it exists. If the current token is ":", then
1736+
* containsSilentMarkerAfterCurrentToken indicates if there is a valid silent marker. Otherwise,
1737+
* the current token is part of the field value, so the silent marker is indicated by
1738+
* containsSilentMarkerAfterPrevToken.
1739+
*/
1740+
private void detectSilentMarker(
1741+
Tokenizer tokenizer, Descriptor immediateMessageType, String fieldName) {
1742+
}
1743+
17121744
/**
17131745
* Determines if repeated values for non-repeated fields and oneofs are permitted. For example,
17141746
* given required/optional field "foo" and a oneof containing "baz" and "moo":
@@ -2081,12 +2113,14 @@ private void mergeField(
20812113

20822114
// Skips unknown fields.
20832115
if (field == null) {
2116+
detectSilentMarker(tokenizer, type, name);
20842117
guessFieldTypeAndSkip(tokenizer, type, recursionLimit);
20852118
return;
20862119
}
20872120

20882121
// Handle potential ':'.
20892122
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
2123+
detectSilentMarker(tokenizer, type, field.getFullName());
20902124
tokenizer.tryConsume(":"); // optional
20912125
if (parseTreeBuilder != null) {
20922126
TextFormatParseInfoTree.Builder childParseTreeBuilder =
@@ -2112,6 +2146,7 @@ private void mergeField(
21122146
recursionLimit);
21132147
}
21142148
} else {
2149+
detectSilentMarker(tokenizer, type, field.getFullName());
21152150
tokenizer.consume(":"); // required
21162151
consumeFieldValues(
21172152
tokenizer,
@@ -2135,26 +2170,26 @@ private void mergeField(
21352170
}
21362171
}
21372172

2138-
private void consumeFullTypeName(Tokenizer tokenizer) throws ParseException {
2173+
private String consumeFullTypeName(Tokenizer tokenizer) throws ParseException {
21392174
// If there is not a leading `[`, this is just a type name.
21402175
if (!tokenizer.tryConsume("[")) {
2141-
tokenizer.consumeIdentifier();
2142-
return;
2176+
return tokenizer.consumeIdentifier();
21432177
}
21442178

21452179
// Otherwise, this is an extension or google.protobuf.Any type URL: we consume proto path
21462180
// elements until we've addressed the type.
2147-
tokenizer.consumeIdentifier();
2181+
String name = tokenizer.consumeIdentifier();
21482182
while (tokenizer.tryConsume(".")) {
2149-
tokenizer.consumeIdentifier();
2183+
name += "." + tokenizer.consumeIdentifier();
21502184
}
21512185
if (tokenizer.tryConsume("/")) {
2152-
tokenizer.consumeIdentifier();
2186+
name += "/" + tokenizer.consumeIdentifier();
21532187
while (tokenizer.tryConsume(".")) {
2154-
tokenizer.consumeIdentifier();
2188+
name += "." + tokenizer.consumeIdentifier();
21552189
}
21562190
}
21572191
tokenizer.consume("]");
2192+
return name;
21582193
}
21592194

21602195
/**
@@ -2400,6 +2435,7 @@ private void mergeAnyFieldValue(
24002435
throw tokenizer.parseExceptionPreviousToken("Expected a valid type URL.");
24012436
}
24022437
}
2438+
detectSilentMarker(tokenizer, anyDescriptor, typeUrlBuilder.toString());
24032439
tokenizer.tryConsume(":");
24042440
final String anyEndToken;
24052441
if (tokenizer.tryConsume("<")) {
@@ -2444,7 +2480,8 @@ private void mergeAnyFieldValue(
24442480
/** Skips the next field including the field's name and value. */
24452481
private void skipField(Tokenizer tokenizer, Descriptor type, int recursionLimit)
24462482
throws ParseException {
2447-
consumeFullTypeName(tokenizer);
2483+
String name = consumeFullTypeName(tokenizer);
2484+
detectSilentMarker(tokenizer, type, name);
24482485
guessFieldTypeAndSkip(tokenizer, type, recursionLimit);
24492486

24502487
// For historical reasons, fields may optionally be separated by commas or

0 commit comments

Comments
 (0)