Skip to content

Commit

Permalink
[api] Context nullable annotations (#5850)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch authored Sep 24, 2024
1 parent 3a09a91 commit 2097f47
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 52 deletions.
42 changes: 21 additions & 21 deletions src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
#nullable enable
~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.AsyncLocalRuntimeContextSlot(string name) -> void
~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Value.get -> object
~OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Value.set -> void
~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.get -> object
~OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.set -> void
~OpenTelemetry.Context.RuntimeContextSlot<T>.Name.get -> string
~OpenTelemetry.Context.RuntimeContextSlot<T>.RuntimeContextSlot(string name) -> void
~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.ThreadLocalRuntimeContextSlot(string name) -> void
~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Value.get -> object
~OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Value.set -> void
~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type
~static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void
~static OpenTelemetry.Context.RuntimeContext.GetSlot<T>(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot<T>
~static OpenTelemetry.Context.RuntimeContext.GetValue(string slotName) -> object
~static OpenTelemetry.Context.RuntimeContext.GetValue<T>(string slotName) -> T
~static OpenTelemetry.Context.RuntimeContext.RegisterSlot<T>(string slotName) -> OpenTelemetry.Context.RuntimeContextSlot<T>
~static OpenTelemetry.Context.RuntimeContext.SetValue(string slotName, object value) -> void
~static OpenTelemetry.Context.RuntimeContext.SetValue<T>(string slotName, T value) -> void
static OpenTelemetry.Context.RuntimeContext.ContextSlotType.get -> System.Type!
static OpenTelemetry.Context.RuntimeContext.ContextSlotType.set -> void
static OpenTelemetry.Context.RuntimeContext.GetSlot<T>(string! slotName) -> OpenTelemetry.Context.RuntimeContextSlot<T>!
static OpenTelemetry.Context.RuntimeContext.GetValue(string! slotName) -> object?
static OpenTelemetry.Context.RuntimeContext.GetValue<T>(string! slotName) -> T?
static OpenTelemetry.Context.RuntimeContext.RegisterSlot<T>(string! slotName) -> OpenTelemetry.Context.RuntimeContextSlot<T>!
static OpenTelemetry.Context.RuntimeContext.SetValue(string! slotName, object? value) -> void
static OpenTelemetry.Context.RuntimeContext.SetValue<T>(string! slotName, T value) -> void
abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Extract<T>(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func<T, string!, System.Collections.Generic.IEnumerable<string!>?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext
abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Fields.get -> System.Collections.Generic.ISet<string!>?
abstract OpenTelemetry.Context.Propagation.TextMapPropagator.Inject<T>(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action<T, string!, string!>! setter) -> void
abstract OpenTelemetry.Context.RuntimeContextSlot<T>.Get() -> T
abstract OpenTelemetry.Context.RuntimeContextSlot<T>.Get() -> T?
abstract OpenTelemetry.Context.RuntimeContextSlot<T>.Set(T value) -> void
abstract OpenTelemetry.Logs.LoggerProviderBuilder.AddInstrumentation<TInstrumentation>(System.Func<TInstrumentation>! instrumentationFactory) -> OpenTelemetry.Logs.LoggerProviderBuilder!
abstract OpenTelemetry.Metrics.MeterProviderBuilder.AddInstrumentation<TInstrumentation>(System.Func<TInstrumentation>! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder!
Expand All @@ -46,7 +36,12 @@ OpenTelemetry.BaseProvider.~BaseProvider() -> void
OpenTelemetry.BaseProvider.BaseProvider() -> void
OpenTelemetry.BaseProvider.Dispose() -> void
OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>
OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.AsyncLocalRuntimeContextSlot(string! name) -> void
OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Value.get -> object?
OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Value.set -> void
OpenTelemetry.Context.IRuntimeContextSlotValueAccessor
OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.get -> object?
OpenTelemetry.Context.IRuntimeContextSlotValueAccessor.Value.set -> void
OpenTelemetry.Context.Propagation.B3Propagator
OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator() -> void
OpenTelemetry.Context.Propagation.B3Propagator.B3Propagator(bool singleHeader) -> void
Expand All @@ -68,7 +63,12 @@ OpenTelemetry.Context.Propagation.TraceContextPropagator.TraceContextPropagator(
OpenTelemetry.Context.RuntimeContext
OpenTelemetry.Context.RuntimeContextSlot<T>
OpenTelemetry.Context.RuntimeContextSlot<T>.Dispose() -> void
OpenTelemetry.Context.RuntimeContextSlot<T>.Name.get -> string!
OpenTelemetry.Context.RuntimeContextSlot<T>.RuntimeContextSlot(string! name) -> void
OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>
OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.ThreadLocalRuntimeContextSlot(string! name) -> void
OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Value.get -> object?
OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Value.set -> void
OpenTelemetry.Logs.IDeferredLoggerProviderBuilder
OpenTelemetry.Logs.IDeferredLoggerProviderBuilder.Configure(System.Action<System.IServiceProvider!, OpenTelemetry.Logs.LoggerProviderBuilder!>! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder!
OpenTelemetry.Logs.LoggerProvider
Expand Down Expand Up @@ -165,7 +165,7 @@ OpenTelemetry.Trace.TracerProviderBuilder
OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void
override OpenTelemetry.Baggage.Equals(object? obj) -> bool
override OpenTelemetry.Baggage.GetHashCode() -> int
override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Get() -> T
override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Get() -> T?
override OpenTelemetry.Context.AsyncLocalRuntimeContextSlot<T>.Set(T value) -> void
override OpenTelemetry.Context.Propagation.B3Propagator.Extract<T>(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func<T, string!, System.Collections.Generic.IEnumerable<string!>?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext
override OpenTelemetry.Context.Propagation.B3Propagator.Fields.get -> System.Collections.Generic.ISet<string!>!
Expand All @@ -182,7 +182,7 @@ override OpenTelemetry.Context.Propagation.TraceContextPropagator.Extract<T>(Ope
override OpenTelemetry.Context.Propagation.TraceContextPropagator.Fields.get -> System.Collections.Generic.ISet<string!>!
override OpenTelemetry.Context.Propagation.TraceContextPropagator.Inject<T>(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action<T, string!, string!>! setter) -> void
override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Dispose(bool disposing) -> void
override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Get() -> T
override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Get() -> T?
override OpenTelemetry.Context.ThreadLocalRuntimeContextSlot<T>.Set(T value) -> void
override OpenTelemetry.Trace.Link.Equals(object? obj) -> bool
override OpenTelemetry.Trace.Link.GetHashCode() -> int
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
~OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.RemotingRuntimeContextSlot(string name) -> void
~OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Value.get -> object
~OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Value.set -> void
OpenTelemetry.Context.RemotingRuntimeContextSlot<T>
override OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Get() -> T
OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.RemotingRuntimeContextSlot(string! name) -> void
OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Value.get -> object?
OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Value.set -> void
override OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Get() -> T?
override OpenTelemetry.Context.RemotingRuntimeContextSlot<T>.Set(T value) -> void
18 changes: 15 additions & 3 deletions src/OpenTelemetry.Api/Context/AsyncLocalRuntimeContextSlot.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable enable

using System.Runtime.CompilerServices;

namespace OpenTelemetry.Context;
Expand All @@ -24,15 +26,25 @@ public AsyncLocalRuntimeContextSlot(string name)
}

/// <inheritdoc/>
public object Value
public object? Value
{
get => this.slot.Value;
set => this.slot.Value = (T)value;
set
{
if (typeof(T).IsValueType && value is null)
{
this.slot.Value = default!;
}
else
{
this.slot.Value = (T)value!;
}
}
}

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
public override T? Get()
{
return this.slot.Value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable enable

namespace OpenTelemetry.Context;

/// <summary>
Expand All @@ -11,5 +13,5 @@ public interface IRuntimeContextSlotValueAccessor
/// <summary>
/// Gets or sets the value of the slot as an <see cref="object"/>.
/// </summary>
object Value { get; set; }
object? Value { get; set; }
}
30 changes: 23 additions & 7 deletions src/OpenTelemetry.Api/Context/RemotingRuntimeContextSlot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0

#if NETFRAMEWORK
#nullable enable

using System.Collections;
using System.Reflection;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -38,25 +40,39 @@ public RemotingRuntimeContextSlot(string name)
}

/// <inheritdoc/>
public object Value
public object? Value
{
get => this.Get();
set => this.Set((T)value);
set
{
if (typeof(T).IsValueType && value is null)
{
this.Set(default!);
}
else
{
this.Set((T)value!);
}
}
}

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
public override T? Get()
{
if (!(CallContext.LogicalGetData(this.Name) is BitArray wrapper))
if (CallContext.LogicalGetData(this.Name) is not BitArray wrapper)
{
return default;
}

var value = WrapperField.GetValue(wrapper);
return value is T t
? t
: default;

if (typeof(T).IsValueType && value is null)
{
return default;
}

return (T)value;
}

/// <inheritdoc/>
Expand Down
30 changes: 20 additions & 10 deletions src/OpenTelemetry.Api/Context/RuntimeContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable enable

using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using OpenTelemetry.Internal;
Expand Down Expand Up @@ -56,7 +58,8 @@ public static Type ContextSlotType
public static RuntimeContextSlot<T> RegisterSlot<T>(string slotName)
{
Guard.ThrowIfNullOrEmpty(slotName);
RuntimeContextSlot<T> slot = null;

RuntimeContextSlot<T>? slot = null;

lock (Slots)
{
Expand All @@ -80,6 +83,10 @@ public static RuntimeContextSlot<T> RegisterSlot<T>(string slotName)
slot = new RemotingRuntimeContextSlot<T>(slotName);
}
#endif
else
{
throw new NotSupportedException($"ContextSlotType '{ContextSlotType}' is not supported");
}

Slots[slotName] = slot;
return slot;
Expand All @@ -95,9 +102,10 @@ public static RuntimeContextSlot<T> RegisterSlot<T>(string slotName)
public static RuntimeContextSlot<T> GetSlot<T>(string slotName)
{
Guard.ThrowIfNullOrEmpty(slotName);

var slot = GuardNotFound(slotName);
var contextSlot = Guard.ThrowIfNotOfType<RuntimeContextSlot<T>>(slot);
return contextSlot;

return Guard.ThrowIfNotOfType<RuntimeContextSlot<T>>(slot);
}

/*
Expand Down Expand Up @@ -143,7 +151,7 @@ public static void SetValue<T>(string slotName, T value)
/// <typeparam name="T">The type of the value.</typeparam>
/// <returns>The value retrieved from the context slot.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetValue<T>(string slotName)
public static T? GetValue<T>(string slotName)
{
return GetSlot<T>(slotName).Get();
}
Expand All @@ -153,25 +161,27 @@ public static T GetValue<T>(string slotName)
/// </summary>
/// <param name="slotName">The name of the context slot.</param>
/// <param name="value">The value to be set.</param>
public static void SetValue(string slotName, object value)
public static void SetValue(string slotName, object? value)
{
Guard.ThrowIfNullOrEmpty(slotName);

var slot = GuardNotFound(slotName);
var runtimeContextSlotValueAccessor = Guard.ThrowIfNotOfType<IRuntimeContextSlotValueAccessor>(slot);
runtimeContextSlotValueAccessor.Value = value;

Guard.ThrowIfNotOfType<IRuntimeContextSlotValueAccessor>(slot).Value = value;
}

/// <summary>
/// Gets the value from a registered slot.
/// </summary>
/// <param name="slotName">The name of the context slot.</param>
/// <returns>The value retrieved from the context slot.</returns>
public static object GetValue(string slotName)
public static object? GetValue(string slotName)
{
Guard.ThrowIfNullOrEmpty(slotName);

var slot = GuardNotFound(slotName);
var runtimeContextSlotValueAccessor = Guard.ThrowIfNotOfType<IRuntimeContextSlotValueAccessor>(slot);
return runtimeContextSlotValueAccessor.Value;

return Guard.ThrowIfNotOfType<IRuntimeContextSlotValueAccessor>(slot).Value;
}

// For testing purpose
Expand Down
8 changes: 7 additions & 1 deletion src/OpenTelemetry.Api/Context/RuntimeContextSlot.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable enable

using OpenTelemetry.Internal;

namespace OpenTelemetry.Context;

/// <summary>
Expand All @@ -15,6 +19,8 @@ public abstract class RuntimeContextSlot<T> : IDisposable
/// <param name="name">The name of the context slot.</param>
protected RuntimeContextSlot(string name)
{
Guard.ThrowIfNullOrEmpty(name);

this.Name = name;
}

Expand All @@ -27,7 +33,7 @@ protected RuntimeContextSlot(string name)
/// Get the value from the context slot.
/// </summary>
/// <returns>The value retrieved from the context slot.</returns>
public abstract T Get();
public abstract T? Get();

/// <summary>
/// Set the value to the context slot.
Expand Down
18 changes: 15 additions & 3 deletions src/OpenTelemetry.Api/Context/ThreadLocalRuntimeContextSlot.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable enable

using System.Runtime.CompilerServices;

namespace OpenTelemetry.Context;
Expand All @@ -25,15 +27,25 @@ public ThreadLocalRuntimeContextSlot(string name)
}

/// <inheritdoc/>
public object Value
public object? Value
{
get => this.slot.Value;
set => this.slot.Value = (T)value;
set
{
if (typeof(T).IsValueType && value is null)
{
this.slot.Value = default!;
}
else
{
this.slot.Value = (T)value!;
}
}
}

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override T Get()
public override T? Get()
{
return this.slot.Value;
}
Expand Down
Loading

0 comments on commit 2097f47

Please sign in to comment.