@@ -1753,15 +1753,37 @@ public String toString() {
17531753private final Descriptor extensionScope ;
17541754private final boolean isProto3Optional ;
17551755
1756- private enum Sensitivity {
1757- UNKNOWN ,
1758- SENSITIVE ,
1759- NOT_SENSITIVE
1756+ static final class RedactionState {
1757+ private static final RedactionState FALSE_FALSE =new RedactionState (false ,false );
1758+ private static final RedactionState FALSE_TRUE =new RedactionState (false ,true );
1759+ private static final RedactionState TRUE_FALSE =new RedactionState (true ,false );
1760+ private static final RedactionState TRUE_TRUE =new RedactionState (true ,true );
1761+
1762+ final boolean redact ;
1763+ final boolean report ;
1764+
1765+ private RedactionState (boolean redact ,boolean report ) {
1766+ this .redact =redact ;
1767+ this .report =report ;
1768+ }
1769+
1770+ private static RedactionState of (boolean redact ) {
1771+ return of (redact ,false );
1772+ }
1773+
1774+ private static RedactionState of (boolean redact ,boolean report ) {
1775+ if (redact ) {
1776+ return report ?TRUE_TRUE :TRUE_FALSE ;
1777+ }
1778+ return report ?FALSE_TRUE :FALSE_FALSE ;
1779+ }
1780+
1781+ private static RedactionState combine (RedactionState lhs ,RedactionState rhs ) {
1782+ return of (lhs .redact ||rhs .redact ,rhs .report );
1783+ }
17601784 }
17611785
1762- // Caches the result of isSensitive() for performance reasons.
1763- private volatile Sensitivity sensitivity =Sensitivity .UNKNOWN ;
1764- private volatile boolean isReportable =false ;
1786+ private volatile RedactionState redactionState ;
17651787
17661788// Possibly initialized during cross-linking.
17671789private Type type ;
@@ -1937,73 +1959,68 @@ private FieldDescriptor(
19371959 }
19381960
19391961@ SuppressWarnings ("unchecked" )// List<EnumValueDescriptor> guaranteed by protobuf runtime.
1940- private List < Boolean > isOptionSensitive (FieldDescriptor field ,Object value ) {
1962+ private static RedactionState isOptionSensitive (FieldDescriptor field ,Object value ) {
19411963if (field .getType () ==Descriptors .FieldDescriptor .Type .ENUM ) {
19421964if (field .isRepeated ()) {
19431965for (EnumValueDescriptor v : (List <EnumValueDescriptor >)value ) {
19441966if (v .getOptions ().getDebugRedact ()) {
1945- return Arrays . asList (true ,false );
1967+ return RedactionState . of (true ,false );
19461968 }
19471969 }
19481970 }else {
19491971if (((EnumValueDescriptor )value ).getOptions ().getDebugRedact ()) {
1950- return Arrays . asList (true ,false );
1972+ return RedactionState . of (true ,false );
19511973 }
19521974 }
19531975 }else if (field .getJavaType () ==Descriptors .FieldDescriptor .JavaType .MESSAGE ) {
19541976if (field .isRepeated ()) {
19551977for (Message m : (List <Message >)value ) {
19561978for (Map .Entry <FieldDescriptor ,Object >entry :m .getAllFields ().entrySet ()) {
1957- List < Boolean > result =isOptionSensitive (entry .getKey (),entry .getValue ());
1958- if (result . get ( 0 ) ) {
1959- return result ;
1979+ RedactionState state =isOptionSensitive (entry .getKey (),entry .getValue ());
1980+ if (state . redact ) {
1981+ return state ;
19601982 }
19611983 }
19621984 }
19631985 }else {
19641986for (Map .Entry <FieldDescriptor ,Object >entry :
19651987 ((Message )value ).getAllFields ().entrySet ()) {
1966- List < Boolean > result =isOptionSensitive (entry .getKey (),entry .getValue ());
1967- if (result . get ( 0 ) ) {
1968- return result ;
1988+ RedactionState state =isOptionSensitive (entry .getKey (),entry .getValue ());
1989+ if (state . redact ) {
1990+ return state ;
19691991 }
19701992 }
19711993 }
19721994 }
1973- return Arrays . asList ( false , false );
1995+ return RedactionState . of ( false );
19741996 }
19751997
1976- // Lazily calculates if the field is marked as sensitive, and caches results.
1977- private List <Boolean >calculateSensitivityData () {
1978- if (sensitivity ==Sensitivity .UNKNOWN ) {
1998+ // Lazily calculates the redact state of the field, caching the result.
1999+ RedactionState getRedactionState () {
2000+ RedactionState state =redactionState ;
2001+ if (state ==null ) {
19792002// If the field is directly marked with debug_redact=true, then it is sensitive.
19802003synchronized (this ) {
1981- if (sensitivity ==Sensitivity .UNKNOWN ) {
1982- boolean isSensitive =proto .getOptions ().getDebugRedact ();
2004+ state =redactionState ;
2005+ if (state ==null ) {
2006+ FieldOptions options =getOptions ();
2007+ state =RedactionState .of (options .getDebugRedact ());
19832008// Check if the FieldOptions contain any enums that are marked as debug_redact=true,
19842009// either directly or indirectly via a message option.
19852010for (Map .Entry <Descriptors .FieldDescriptor ,Object >entry :
1986- proto . getOptions () .getAllFields ().entrySet ()) {
1987- List < Boolean > result = isOptionSensitive ( entry . getKey (), entry . getValue ());
1988- isSensitive = isSensitive || result . get ( 0 );
1989- isReportable = result . get ( 1 );
1990- if (isSensitive ) {
2011+ options .getAllFields ().entrySet ()) {
2012+ state =
2013+ RedactionState . combine (
2014+ state , isOptionSensitive ( entry . getKey (), entry . getValue ()) );
2015+ if (state . redact ) {
19912016break ;
19922017 }
19932018 }
1994- sensitivity =isSensitive ? Sensitivity . SENSITIVE : Sensitivity . NOT_SENSITIVE ;
2019+ redactionState =state ;
19952020 }
19962021 }
19972022 }
1998- return Arrays .asList (sensitivity ==Sensitivity .SENSITIVE ,isReportable );
1999- }
2000-
2001- boolean isSensitive () {
2002- return calculateSensitivityData ().get (0 );
2003- }
2004-
2005- boolean isReportable () {
2006- return calculateSensitivityData ().get (1 );
2023+ return state ;
20072024 }
20082025
20092026/** See {@link FileDescriptor#resolveAllFeatures}. */