/// <summary> /// Writes the specified property expression to the buffer. /// </summary> /// <param name="buffer">The buffer</param> /// <param name="propertyExpression">The property expression</param> private static void WritePropertyExpressionToBuffer(StringBuilder buffer, LanguageExpression propertyExpression) { ExpressionSerializer.ValidateExpression(expression: propertyExpression); switch (propertyExpression) { case FunctionExpression functionExpression: // Note(majastrz): Functions in properties should be enclosed in brackets ExpressionSerializer.WriteExpressionToBuffer(buffer: buffer, expression: functionExpression, prefix: "[", suffix: "]"); return; case JTokenExpression valueExpression: var value = ExpressionSerializer.GetValueFromValueExpression(valueExpression: valueExpression); switch (value.Type) { case JTokenType.String: var valueStr = value.ToString(); if (ExpressionSerializer.IsIdentifier(value: valueStr)) { // Note(majastrz): The property expression is an identifier. We can serialize it with a leading dot and without any enclosing quotes. buffer.Append(value: '.'); buffer.Append(value: valueStr); } else { // Note(majastrz): The property expression has to be enclosed in brackets because it's not an identifier. ExpressionSerializer.WriteExpressionToBuffer(buffer: buffer, expression: valueExpression, prefix: "[", suffix: "]"); } return; case JTokenType.Integer: // Note(majastrz): Indexes should be enclosed in brackets. buffer.Append(value: '['); buffer.Append(value: value); buffer.Append(value: ']'); return; default: // Note(majastrz): JTokenValue can only be created with string or int value. throw new InvalidOperationException(message: $"JTokenExpression has a value of unexpected type '{value.Type}'."); } default: throw new InvalidOperationException($"Unexpected expression type '{propertyExpression.GetType().Name}'"); } }
/// <summary> /// Serializes a language expression into a string. /// </summary> /// <param name="expression">The expression</param> public string SerializeExpression(LanguageExpression expression) { var buffer = new StringBuilder(); if (!ExpressionSerializer.TryWriteSingleStringToBuffer(buffer: buffer, expression: expression, settings: this.settings)) { // Note(majastrz): The expression is not a single string expression or the single string serialization is disabled // Note(majastrz): Include outer brackets when serializing the expression if feature is enabled ExpressionSerializer.WriteExpressionToBuffer( buffer: buffer, expression: expression, prefix: this.settings.IncludeOuterSquareBrackets ? "[" : null, suffix: this.settings.IncludeOuterSquareBrackets ? "]" : null); } return(buffer.ToString()); }
/// <summary> /// If the expression is a single string JTokenExpression and serialization as string is enabled, it performs the serialization. /// </summary> /// <param name="buffer">The buffer</param> /// <param name="expression">The expression</param> /// <param name="settings">The settings</param> /// <returns>True if expression has been written out to the buffer or false otherwise.</returns> private static bool TryWriteSingleStringToBuffer(StringBuilder buffer, LanguageExpression expression, ExpressionSerializerSettings settings) { if (settings.SingleStringHandling == ExpressionSerializerSingleStringHandling.SerializeAsString && expression is JTokenExpression valueExpression) { var value = ExpressionSerializer.GetValueFromValueExpression(valueExpression: valueExpression); if (value.Type == JTokenType.String) { var valueStr = value.ToString(); // Note(majastrz): Add escape bracket if needed. if (valueStr.Length > 0 && valueStr[0] == '[') { buffer.Append(value: '['); } buffer.Append(value: valueStr); return(true); } } // Note(majastrz): Returning false REQUIRES that buffer not be modified in any way. return(false); }
/// <summary> /// Writes the value expression to the buffer. /// </summary> /// <param name="buffer">The buffer</param> /// <param name="valueExpression">The value expression</param> private static void WriteValueExpressionToBuffer(StringBuilder buffer, JTokenExpression valueExpression) { ExpressionSerializer.ValidateValueExpression(valueExpression: valueExpression); var value = ExpressionSerializer.GetValueFromValueExpression(valueExpression: valueExpression); switch (value.Type) { case JTokenType.Integer: // Note(majastrz): Integers are serialized as-is buffer.Append(value: value); return; case JTokenType.String: WriteEscapedStringLiteral(buffer, value.ToString()); return; default: // Note(majastrz): JTokenValue can only be created with string or int value. throw new InvalidOperationException($"JTokenExpression has a value of unexpected type '{value.Type}'."); } }
/// <summary> /// Validates the specified value expression. Does not perform recursive validation. /// </summary> /// <param name="valueExpression">The value expression</param> private static void ValidateValueExpression(JTokenExpression valueExpression) { ExpressionSerializer.ValidateExpression(expression: valueExpression); }
/// <summary> /// Validates that the specified function expression. Does not perform recursive validation. /// </summary> /// <param name="functionExpression">The function expression</param> private static void ValidateFunctionExpression(FunctionExpression functionExpression) { ExpressionSerializer.ValidateExpression(expression: functionExpression); ExpressionSerializer.ValidateExpressionArray(functionExpression.Parameters); ExpressionSerializer.ValidateExpressionArray(functionExpression.Properties); }