-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement a mechanism to control the output format of Message.toStrin…
…g within a Runnable instance. PiperOrigin-RevId: 665539414
- Loading branch information
1 parent
8bb789e
commit 737803e
Showing
6 changed files
with
182 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
java/core/src/main/java/com/google/protobuf/ProtobufToStringOutput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.google.protobuf; | ||
|
||
/** | ||
* ProtobufToStringOutput controls the output format of {@link Message#toString()}. Specifically, for | ||
* the Runnable object passed to `callWithDebugFormat` and `callWithTextFormat`, Message.toString() | ||
* will always output the specified format unless ProtobufToStringOutput is used again to change the | ||
* output format. | ||
*/ | ||
public final class ProtobufToStringOutput { | ||
private enum OutputMode { | ||
DEBUG_FORMAT, | ||
TEXT_FORMAT | ||
} | ||
|
||
private static final ThreadLocal<OutputMode> outputMode = | ||
new ThreadLocal<OutputMode>() { | ||
@Override | ||
protected OutputMode initialValue() { | ||
return OutputMode.TEXT_FORMAT; | ||
} | ||
}; | ||
|
||
private ProtobufToStringOutput() {} | ||
|
||
@CanIgnoreReturnValue | ||
private static OutputMode setOutputMode(OutputMode newMode) { | ||
OutputMode oldMode = outputMode.get(); | ||
outputMode.set(newMode); | ||
return oldMode; | ||
} | ||
|
||
private static void callWithSpecificFormat(Runnable impl, OutputMode mode) { | ||
OutputMode oldMode = setOutputMode(mode); | ||
try { | ||
impl.run(); | ||
} finally { | ||
OutputMode unused = setOutputMode(oldMode); | ||
} | ||
} | ||
|
||
public static void callWithDebugFormat(Runnable impl) { | ||
callWithSpecificFormat(impl, OutputMode.DEBUG_FORMAT); | ||
} | ||
|
||
public static void callWithTextFormat(Runnable impl) { | ||
callWithSpecificFormat(impl, OutputMode.TEXT_FORMAT); | ||
} | ||
|
||
public static boolean shouldOutputDebugFormat() { | ||
return outputMode.get() == OutputMode.DEBUG_FORMAT; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
java/core/src/test/java/com/google/protobuf/ProtobufToStringOutputTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package com.google.protobuf; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
|
||
import protobuf_unittest.UnittestProto.RedactedFields; | ||
import protobuf_unittest.UnittestProto.TestNestedMessageRedaction; | ||
import java.util.ArrayList; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.JUnit4; | ||
|
||
@RunWith(JUnit4.class) | ||
public final class ProtobufToStringOutputTest extends DebugFormatTest { | ||
RedactedFields message; | ||
|
||
@Before | ||
public void setupTest() { | ||
message = | ||
RedactedFields.newBuilder() | ||
.setOptionalUnredactedString("foo") | ||
.setOptionalRedactedString("bar") | ||
.setOptionalRedactedMessage( | ||
TestNestedMessageRedaction.newBuilder().setOptionalUnredactedNestedString("foobar")) | ||
.build(); | ||
} | ||
|
||
@Test | ||
public void toStringFormat_defaultFormat() { | ||
assertThat(message.toString()) | ||
.matches( | ||
"optional_redacted_string: \"bar\"\n" | ||
+ "optional_unredacted_string: \"foo\"\n" | ||
+ "optional_redacted_message \\{\n" | ||
+ " optional_unredacted_nested_string: \"foobar\"\n" | ||
+ "\\}\n"); | ||
} | ||
|
||
@Test | ||
public void toStringFormat_testDebugFormat() { | ||
ProtobufToStringOutput.callWithDebugFormat( | ||
() -> | ||
assertThat(message.toString()) | ||
.matches( | ||
String.format( | ||
"%soptional_redacted_string: %s\n" | ||
+ "optional_unredacted_string: \"foo\"\n" | ||
+ "optional_redacted_message \\{\n" | ||
+ " %s\n" | ||
+ "\\}\n", | ||
UNSTABLE_PREFIX_MULTILINE, REDACTED_REGEX, REDACTED_REGEX))); | ||
} | ||
|
||
@Test | ||
public void toStringFormat_testTextFormat() { | ||
ProtobufToStringOutput.callWithTextFormat( | ||
() -> { | ||
assertThat(message.toString()) | ||
.matches( | ||
"optional_redacted_string: \"bar\"\n" | ||
+ "optional_unredacted_string: \"foo\"\n" | ||
+ "optional_redacted_message \\{\n" | ||
+ " optional_unredacted_nested_string: \"foobar\"\n" | ||
+ "\\}\n"); | ||
}); | ||
} | ||
|
||
@Test | ||
public void toStringFormat_testProtoWrapperWithDebugFormat() { | ||
ProtobufToStringOutput.callWithDebugFormat( | ||
() -> { | ||
ArrayList<RedactedFields> list = new ArrayList<>(); | ||
list.add(message); | ||
assertThat(list.toString()) | ||
.matches( | ||
String.format( | ||
"\\[%soptional_redacted_string: %s\n" | ||
+ "optional_unredacted_string: \"foo\"\n" | ||
+ "optional_redacted_message \\{\n" | ||
+ " %s\n" | ||
+ "\\}\n" | ||
+ "\\]", | ||
UNSTABLE_PREFIX_MULTILINE, REDACTED_REGEX, REDACTED_REGEX)); | ||
}); | ||
} | ||
|
||
@Test | ||
public void toStringFormat_testProtoWrapperWithTextFormat() { | ||
ProtobufToStringOutput.callWithTextFormat( | ||
() -> { | ||
ArrayList<RedactedFields> list = new ArrayList<>(); | ||
list.add(message); | ||
assertThat(list.toString()) | ||
.matches( | ||
"\\[optional_redacted_string: \"bar\"\n" | ||
+ "optional_unredacted_string: \"foo\"\n" | ||
+ "optional_redacted_message \\{\n" | ||
+ " optional_unredacted_nested_string: \"foobar\"\n" | ||
+ "\\}\n" | ||
+ "\\]"); | ||
}); | ||
} | ||
} |