class ServiceTalkTracingThreadContextMap extends ServiceTalkThreadContextMap {

    @Nullable
    @Override
    public String get(String key) {
        // This Map implementation violates the Map contract in that it provides a "read only" view of the
        // AsyncContextInMemoryScopeManager to include tracing information in log statements. The "read only" portion
        // is because modifications to this MDC map (e.g. put, clear) will not modify the original
        // AsyncContextInMemoryScopeManager storage. The Map contract is therefore violated in other ways such as
        // isEmpty() may return true, but then get(..) may return elements from the trace.
        switch (key) {
            case TRACE_ID_KEY: {
                InMemorySpan span = SCOPE_MANAGER.activeSpan();
                if (span != null) {
                    return span.traceIdHex();
                }
                break;
            }
            case SPAN_ID_KEY: {
                InMemorySpan span = SCOPE_MANAGER.activeSpan();
                if (span != null) {
                    return span.spanIdHex();
                }
                break;
            }
            case PARENT_SPAN_ID_KEY: {
                InMemorySpan span = SCOPE_MANAGER.activeSpan();
                if (span != null) {
                    return span.nonnullParentSpanIdHex();
                }
                break;
            }
            default:
                break;
        }
        return super.get(key);
    }

}