public AutoGeneratedMemberReturnValuesIfSelectorElement([NotNull] XmlElement xmlElement,
                                                         [NotNull] IAutoGeneratedServiceMethodElement parentAutoGeneratedServiceMethodElement,
                                                         [NotNull] ISettingValueInitializerHelper settingValueInitializerHelper,
                                                         [NotNull] IDeserializedFromStringValueInitializerHelper deserializedFromStringValueInitializerHelper,
                                                         [NotNull] IClassMemberValueInitializerHelper classMemberValueInitializerHelper) : base(xmlElement, parentAutoGeneratedServiceMethodElement)
 {
     _settingValueInitializerHelper = settingValueInitializerHelper;
     _deserializedFromStringValueInitializerHelper = deserializedFromStringValueInitializerHelper;
     _classMemberValueInitializerHelper            = classMemberValueInitializerHelper;
 }
        private void AddMethodBodyForNonImplementedMethodWithSimilarImplementedMethod([NotNull] IDynamicAssemblyBuilder dynamicAssemblyBuilder,
                                                                                      [NotNull] MethodInfo methodInfo, [NotNull] IAutoGeneratedServiceMethodElement similarAutoGeneratedServiceMethodElement,
                                                                                      [NotNull] StringBuilder classStrBldr)
        {
            var autoimplementedMethodInfo = similarAutoGeneratedServiceMethodElement.ImplementedMehodInfo;

            classStrBldr.Append($"=>(({autoimplementedMethodInfo.DeclaringType.GetTypeNameInCSharpClass()})this).");
            classStrBldr.Append($"{autoimplementedMethodInfo.Name}(");

            var parameters = methodInfo.GetParameters();

            for (var i = 0; i < parameters.Length; ++i)
            {
                if (i > 0)
                {
                    classStrBldr.Append(", ");
                }

                var parameterInfo = parameters[i];

                if (parameterInfo.IsOut)
                {
                    classStrBldr.Append("out ");
                }
                else if (parameterInfo.ParameterType.IsByRef)
                {
                    classStrBldr.Append("ref ");
                }
                else if (parameterInfo.IsIn)
                {
                    classStrBldr.Append("in ");
                }

                classStrBldr.Append(parameterInfo.Name);
            }

            classStrBldr.Append(");");
        }
        private void AddMethodBodyForImplementedMethod([NotNull] IDynamicAssemblyBuilder dynamicAssemblyBuilder,
                                                       [NotNull] IAutoGeneratedServiceMethodElement autoGeneratedServiceMethodElement,
                                                       [NotNull] StringBuilder classStrBldr,
                                                       [NotNull] StringBuilder classMembersStrBldr)
        {
            IDeserializedValue getDeserializedValue(IValueInitializer valueInitializer)
            {
                if (valueInitializer is IDeserializedValue deserializedValue)
                {
                    return(deserializedValue);
                }

                if (valueInitializer is IValueInitializerElementDecorator valueInitializerElementDecorator)
                {
                    return(valueInitializerElementDecorator.DecoratedValueInitializerElement as IDeserializedValue);
                }

                return(null);
            }

            void addReturnedValueCSharp(IAutoGeneratedMemberReturnValuesSelectorElement autoGeneratedMemberReturnValuesSelector)
            {
                // For now only one return value is supported
                var returnedValueElement = autoGeneratedMemberReturnValuesSelector.ReturnedValueElements[0];

                var isDeserializedValueInitializer = getDeserializedValue(returnedValueElement) != null;

                if (autoGeneratedServiceMethodElement.ReuseReturnedValue || isDeserializedValueInitializer)
                {
                    var returnedVariableName = $"_{autoGeneratedServiceMethodElement.ImplementedMehodInfo.Name}_Returned_{GlobalsCoreAmbientContext.Context.GenerateUniqueId()}";
                    classMembersStrBldr.Append($"private {autoGeneratedServiceMethodElement.ValueTypeInfo.TypeCSharpFullName} {returnedVariableName}");

                    if (isDeserializedValueInitializer ||
                        // If ReuseReturnedValue is true, we always pre-store the returned value, if the value type is a struct,
                        // since we cannot compare the value with null
                        returnedValueElement.ValueTypeInfo.Type.IsValueType)
                    {
                        classMembersStrBldr.Append($"={returnedValueElement.GenerateValueCSharp(dynamicAssemblyBuilder)}");
                    }
                    else
                    {
                        // If we didn't already set the value of variable in stored the variable, lets check for null first.
                        classStrBldr.AppendLine($"if ({returnedVariableName} == null)");
                        classStrBldr.AppendLine($"{returnedVariableName} = {returnedValueElement.GenerateValueCSharp(dynamicAssemblyBuilder)};");
                    }

                    classMembersStrBldr.AppendLine(";");

                    classStrBldr.AppendLine($"return {returnedVariableName};");
                }
                else
                {
                    classStrBldr.AppendLine($"return {returnedValueElement.GenerateValueCSharp(dynamicAssemblyBuilder)};");
                }
            }

            void addParameterValueCSharp(ParameterInfo parameterInfo, IValueInitializer valueInitializer)
            {
                var deserializedValue = getDeserializedValue(valueInitializer);

                if (deserializedValue != null)
                {
                    var variableName = $"_{autoGeneratedServiceMethodElement.ImplementedMehodInfo.Name}_{GlobalsCoreAmbientContext.Context.GenerateUniqueId()}";

                    classMembersStrBldr.Append($"private {parameterInfo.ParameterType.GetTypeNameInCSharpClass()} {variableName}=");
                    classMembersStrBldr.Append(valueInitializer.GenerateValueCSharp(dynamicAssemblyBuilder));
                    classMembersStrBldr.AppendLine(";");

                    classStrBldr.Append(variableName);
                }
                else
                {
                    if (parameterInfo.ParameterType != valueInitializer.ValueTypeInfo.Type)
                    {
                        classStrBldr.Append($"({parameterInfo.ParameterType.GetTypeNameInCSharpClass()})");
                    }

                    classStrBldr.Append(valueInitializer.GenerateValueCSharp(dynamicAssemblyBuilder));
                }
            }

            classStrBldr.AppendLine();
            classStrBldr.AppendLine("{");

            var methodParameters = autoGeneratedServiceMethodElement.ImplementedMehodInfo.GetParameters();

            foreach (var returnedValueSelectorsForIfCase in autoGeneratedServiceMethodElement.ReturnedValueSelectorsForIfCase)
            {
                classStrBldr.Append("if(");
                for (var i = 0; i < returnedValueSelectorsForIfCase.ParameterValueInitializers.Count; ++i)
                {
                    if (i > 0)
                    {
                        classStrBldr.Append(" && ");
                    }

                    var parameterValueInitializer = returnedValueSelectorsForIfCase.ParameterValueInitializers[i];
                    var parameterInfo             = methodParameters[parameterValueInitializer.ParameterIndex];

                    if (returnedValueSelectorsForIfCase.ParameterValueInitializers.Count > 1)
                    {
                        classStrBldr.Append("(");
                    }

                    if (!parameterInfo.ParameterType.IsValueType)
                    {
                        classStrBldr.Append($"{parameterInfo.Name}!=null && ");
                    }

                    classStrBldr.Append($"{parameterInfo.Name}");

                    if (IsEqualsOperatorUsedInIfStatment(parameterInfo.ParameterType))
                    {
                        classStrBldr.Append("==");

                        addParameterValueCSharp(parameterInfo, parameterValueInitializer.ValueInitializer);
                    }
                    else
                    {
                        classStrBldr.Append(".Equals(");
                        addParameterValueCSharp(parameterInfo, parameterValueInitializer.ValueInitializer);
                        classStrBldr.Append(")");
                    }

                    if (returnedValueSelectorsForIfCase.ParameterValueInitializers.Count > 1)
                    {
                        classStrBldr.Append(")");
                    }
                }

                classStrBldr.AppendLine(")");
                classStrBldr.AppendLine("{");

                addReturnedValueCSharp(returnedValueSelectorsForIfCase);
                classStrBldr.AppendLine("}");
            }

            if (autoGeneratedServiceMethodElement.ReturnedValueSelectorsForDefaultCase != null)
            {
                addReturnedValueCSharp(autoGeneratedServiceMethodElement.ReturnedValueSelectorsForDefaultCase);
            }
            else
            {
                // We should never get here, however lets consider this case, in case we make the default element optional.
                classStrBldr.AppendLine($"return default({autoGeneratedServiceMethodElement.ImplementedMehodInfo.ReturnType.GetTypeNameInCSharpClass()})");
            }

            classStrBldr.AppendLine("}");
        }
 public AutoGeneratedMemberReturnValuesSelectorElement([NotNull] XmlElement xmlElement, [NotNull] IAutoGeneratedServiceMethodElement parentAutoGeneratedServiceMethodElement) : base(xmlElement, parentAutoGeneratedServiceMethodElement)
 {
     ParentAutoGeneratedServiceMethodElement = parentAutoGeneratedServiceMethodElement;
 }