protected virtual TResult Transform(Expression expression)
 {
     return(expression switch
     {
         CallExpression call => Transform(call),
         ConstantExpression constant => Transform(constant),
         AccessorExpression accessor => Transform(accessor),
         AmbientPropertyExpression property => Transform(property),
         LambdaExpression lambda => Transform(lambda),
         ParameterExpression parameter => Transform(parameter),
         IndexerWildcardExpression wildcard => Transform(wildcard),
         ArrayExpression array => Transform(array),
         ObjectExpression obj => Transform(obj),
         IndexerExpression indexer => Transform(indexer),
         IndexOfMatchExpression match => Transform(match),
         null => throw new ArgumentNullException(nameof(expression)),
         // Non-exhaustive because `InternalsVisibleTo` is applied to the assembly.
         _ => throw new NotSupportedException($"{expression} is not supported.")
     });
        protected override ExpressionBody Transform(AmbientPropertyExpression px)
        {
            if (px.IsBuiltIn)
            {
                if (px.PropertyName == BuiltInProperty.Level)
                {
                    return(Splice(context => new ScalarValue(context.Level)));
                }

                if (px.PropertyName == BuiltInProperty.Message)
                {
                    return(Splice(context => new ScalarValue(Intrinsics.RenderMessage(context))));
                }

                if (px.PropertyName == BuiltInProperty.Exception)
                {
                    return(Splice(context => context.Exception == null ? null : new ScalarValue(context.Exception)));
                }

                if (px.PropertyName == BuiltInProperty.Timestamp)
                {
                    return(Splice(context => new ScalarValue(context.Timestamp)));
                }

                if (px.PropertyName == BuiltInProperty.MessageTemplate)
                {
                    return(Splice(context => new ScalarValue(context.MessageTemplate.Text)));
                }

                if (px.PropertyName == BuiltInProperty.Properties)
                {
                    return(Splice(context => new StructureValue(context.Properties.Select(kvp => new LogEventProperty(kvp.Key, kvp.Value)), null)));
                }

                return(LX.Constant(null, typeof(LogEventPropertyValue)));
            }

            var propertyName = px.PropertyName;

            return(Splice(context => Intrinsics.GetPropertyValue(context, propertyName)));
        }
 protected override Expression Transform(AmbientPropertyExpression px)
 {
     return(px);
 }
 protected override IndexerExpression?Transform(AmbientPropertyExpression px)
 {
     return(null);
 }