@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.Flow
3838 * The [DataConnectLogging] interface is _not_ stable for inheritance in third-party libraries, as
3939 * new methods might be added to this interface or contracts of the existing methods can be changed.
4040 */
41- public interface DataConnectLogging {
41+ public interface DataConnectLogging < out StateT : DataConnectLogging . State > {
4242
4343 /* *
4444 * The log level use by all [FirebaseDataConnect] instances.
@@ -49,63 +49,76 @@ public interface DataConnectLogging {
4949 */
5050 public var level: LogLevel
5151
52- /* * A [Flow] that can be used to observe the changes to [level ]. */
53- public val flow: Flow <LogLevel >
52+ /* * A [Flow] that can be used to observe changes to [state ]. */
53+ public val flow: Flow <StateT >
5454
5555 /* *
56- * Sets the log level to the given level, as if by setting [level], and returns an object that,
57- * when closed, will restore the log level to the value it was at the time that this method was
58- * invoked.
56+ * The state of the logging facilities.
5957 *
60- * This method can be particularly useful to enable debug logging only for a small section of
61- * code, without having to manually keep track of the original state. Unit tests and small chunks
62- * of code that require debugging are the intended use cases for this function .
58+ * A caller may wish to save the value of this property into a local variable, make some changes
59+ * to the public properties of [DataConnectLogging] (for example, change [level]), run some code,
60+ * then restore the original state by calling [DataConnectLogging.State.restore] .
6361 *
6462 * For an example in Firebase Data Connect's own Android test suite, see https://goo.gle/3ZuRug5.
65- *
66- * Note that when a log level is "popped" it does not interact with any other pushed log levels.
67- * In particular, if there are nested calls to [push] then they are expected to be popped in
68- * reverse order; otherwise, the "original" log level may not be properly restored.
6963 */
70- public fun push ( level : LogLevel ): LogLevelStackFrame
64+ public val state : StateT
7165
7266 /* *
73- * A "stack frame" that saves the state of the logging facilities in response to a call to [push] .
67+ * A snapshot of the state of the logging facilities, that can be later restored .
7468 *
7569 * ### Safe for Concurrent Use
7670 *
77- * All methods and properties of [LogLevelStackFrame ] are thread-safe and may be safely called
78- * and/or accessed concurrently from multiple threads and/or coroutines.
71+ * All methods and properties of [State ] are thread-safe and may be safely called and/or accessed
72+ * concurrently from multiple threads and/or coroutines.
7973 *
8074 * ### Not Stable for Inheritance
8175 *
82- * The [LogLevelStackFrame] interface is _not_ stable for inheritance in third-party libraries, as
83- * new methods might be added to this interface or contracts of the existing methods can be
84- * changed.
76+ * The [State] interface is _not_ stable for inheritance in third-party libraries, as new methods
77+ * might be added to this interface or contracts of the existing methods can be changed.
78+ *
79+ * @see state
8580 */
86- public interface LogLevelStackFrame : AutoCloseable {
81+ public interface State {
8782
88- /* * The log level that was in place when this frame was pushed . */
89- public val originalLevel : LogLevel
83+ /* * The log level. */
84+ public val level : LogLevel
9085
91- /* * The log level that was set when this frame was pushed . */
92- public val newLevel : LogLevel
86+ /* * Restores the state from this object into the [DataConnectLogging] that created it . */
87+ public fun restore ()
9388
9489 /* *
95- * Pops this frame off of the log level stack, restoring the log level to the state it was in at
96- * the time that this frame was pushed onto the stack.
90+ * Compares this object with another object for equality.
9791 *
98- * This method may be safely called multiple times. Subsequent invocations will do nothing and
99- * return as if successful. Subsequent invocations will _block_ until the state is restored by
100- * the thread that is actually doing the restoring.
92+ * @param other The object to compare to this for equality.
93+ * @return true if, and only if, the other object is an instance of the same implementation of
94+ * [State] whose public properties compare equal using the `==` operator to the corresponding
95+ * properties of this object.
10196 */
102- override fun close ()
97+ override fun equals ( other : Any? ): Boolean
10398
10499 /* *
105- * Does the exact same thing as [close], except that it _suspends_ rather than _blocks_ if
106- * another thread is in the process of restoring the original log level.
100+ * Calculates and returns the hash code for this object.
101+ *
102+ * The hash code is _not_ guaranteed to be stable across application restarts.
103+ *
104+ * @return the hash code for this object, that incorporates the values of this object's public
105+ * properties.
107106 */
108- public suspend fun suspendingClose ()
107+ override fun hashCode (): Int
108+
109+ /* *
110+ * Returns a string representation of this object, useful for debugging.
111+ *
112+ * The string representation is _not_ guaranteed to be stable and may change without notice at
113+ * any time. Therefore, the only recommended usage of the returned string is debugging and/or
114+ * logging. Namely, parsing the returned string or storing the returned string in non-volatile
115+ * storage should generally be avoided in order to be robust in case that the string
116+ * representation changes.
117+ *
118+ * @return a string representation of this object, which includes the class name and the values
119+ * of all public properties.
120+ */
121+ override fun toString (): String
109122 }
110123}
111124
@@ -126,5 +139,12 @@ public interface DataConnectLogging {
126139 * inline.
127140 * @return whatever the given block returns.
128141 */
129- public inline fun <T > DataConnectLogging.withLevel (level : LogLevel , block : () -> T ): T =
130- push(level).use { block() }
142+ public inline fun <T > DataConnectLogging <* >.withLevel (level : LogLevel , block : () -> T ): T {
143+ val savedState = state
144+ this .level = level
145+ return try {
146+ block()
147+ } finally {
148+ savedState.restore()
149+ }
150+ }
0 commit comments