@@ -1753,15 +1753,37 @@ public String toString() {
17531753 private final Descriptor extensionScope ;
17541754 private 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.
17671789 private 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 ) {
19411963 if (field .getType () == Descriptors .FieldDescriptor .Type .ENUM ) {
19421964 if (field .isRepeated ()) {
19431965 for (EnumValueDescriptor v : (List <EnumValueDescriptor >) value ) {
19441966 if (v .getOptions ().getDebugRedact ()) {
1945- return Arrays . asList (true , false );
1967+ return RedactionState . of (true , false );
19461968 }
19471969 }
19481970 } else {
19491971 if (((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 ) {
19541976 if (field .isRepeated ()) {
19551977 for (Message m : (List <Message >) value ) {
19561978 for (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 {
19641986 for (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.
19802003 synchronized (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.
19852010 for (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 ) {
19912016 break ;
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}. */
0 commit comments