Example #1
0
        private bool TryCreateDeserializationMethod(CodeBuilder builder, string className, List <Field> fields, SyntaxProvider syntaxProvider)
        {
            builder.Line($"var packet = new {className}();");
            foreach (var field in fields)
            {
                string elementType = field.TypeName, elementName = field.Name;
                if (field.IsArray)
                {
                    elementName += "[i]";
                    string lengthProperty;
                    if (field.TypeName.EndsWith("[]"))
                    {
                        lengthProperty = "Length";
                        elementType    = field.TypeName.Substring(0, field.TypeName.Length - 2);
                    }
                    else
                    {
                        lengthProperty = "Count";
                        elementType    = field.TypeName.Substring(5, field.TypeName.Length - 6);
                    }

                    if (field.IsVarLength)
                    {
                        elementType += "_Var";
                    }
                    if (field.IsAbsolute)
                    {
                        elementType += "_Abs";
                    }

                    string countValue;
                    if (field.FixedLength >= 0)
                    {
                        countValue = field.FixedLength.ToString();
                    }
                    else if (field.CountType is not null)
                    {
                        if (!syntaxProvider.ReadMethods.TryGetValue(field.CountType, out string readCountMethod))
                        {
                            // CountType has no read method
                            syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no deserialization method associated with its count type", field.Declaration));
                            return(false);
                        }

                        countValue = $"stream.{readCountMethod}();";
                    }
                    else
                    {
                        countValue = "stream.ReadVarInt()";
                    }
                    builder.Line(field.TypeName.EndsWith("[]") ? $"packet.{field.Name} = new {elementType}[{countValue}];" : $"packet.{field.Name} = new {field.TypeName}({countValue});");

                    builder.Statement($"for (int i = 0; i < packet.{field.Name}.{lengthProperty}; i++)");
                }

                if (TryGetMethod(elementType, syntaxProvider.ReadMethods, out string methodName))
                {
                    methodName = $"stream.{methodName}()";

                    if (field.OriginalType is not null)
                    {
                        if (field.IsGeneric)
                        {
                            string tempName = $"temp{field.Name}";
                            builder.Line($"var {tempName} = {methodName};");
                            methodName = $"System.Runtime.CompilerServices.Unsafe.As<{field.ActualType}, {field.OriginalType}>(ref {tempName})";
                        }
                        else
                        {
                            methodName = $"({field.ActualType}){methodName}";
                        }
                    }

                    builder.Line($"packet.{elementName} = {methodName};");
                }
                else
                {
                    // Creating serialization method failed
#if DEBUG
                    syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no deserialization method associated with it", field.Declaration));
#endif
                    return(false);
                }

                if (field.IsArray)
                {
                    // End the for loop
                    builder.EndScope();
                }
            }
            builder.Line("return packet;");
            return(true);
        }
        private bool CreateDeserializationMethod(StringBuilder builder, string className, List <Field> fields, SyntaxProvider syntaxProvider)
        {
            builder.AppendCode($"var packet = new {className}();");
            foreach (var field in fields)
            {
                string elementType = field.TypeName, elementName = field.Name;
                if (field.IsArray)
                {
                    elementName += "[i]";
                    string lengthProperty;
                    if (field.TypeName.EndsWith("[]"))
                    {
                        lengthProperty = "Length";
                        elementType    = field.TypeName.Substring(0, field.TypeName.Length - 2);
                    }
                    else
                    {
                        lengthProperty = "Count";
                        elementType    = field.TypeName.Substring(5, field.TypeName.Length - 6);
                    }

                    if (field.IsVarLength)
                    {
                        elementType += "_Var";
                    }
                    if (field.IsAbsolute)
                    {
                        elementType += "_Abs";
                    }

                    string countValue = field.FixedLength >= 0 ? field.FixedLength.ToString() : "stream.ReadVarInt()";
                    builder.AppendCode(field.TypeName.EndsWith("[]") ? $"packet.{field.Name} = new {elementType}[{countValue}];" : $"packet.{field.Name} = new {field.TypeName}({countValue});");

                    builder.AppendCode($"for (int i = 0; i < packet.{field.Name}.{lengthProperty}; i++)");
                    builder.AppendCode("{");
                    builder.Append('\t');
                }

                if (TryGetMethod(elementType, syntaxProvider.ReadMethods, out string methodName))
                {
                    methodName = "stream." + methodName;

                    if (field.OriginalType is not null)
                    {
                        if (field.IsGeneric)
                        {
                            methodName = $"({field.ActualType})(object){methodName}";
                        }
                        else
                        {
                            methodName = $"({field.ActualType}){methodName}";
                        }
                    }

                    builder.AppendCode($"packet.{elementName} = {methodName}();");
                }
                else
                {
                    // creating serialization method failed
#if DEBUG
                    syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no deserialization method associated with it", field.Declaration));
#endif
                    return(false);
                }

                if (field.IsArray)
                {
                    // end for loop
                    builder.AppendCode("}");
                }
            }
            builder.AppendCode("return packet;");
            return(true);
        }
Example #3
0
        private bool TryCreateSerializationMethod(CodeBuilder builder, List <Field> fields, SyntaxProvider syntaxProvider)
        {
            builder.Line("using var packetStream = new MinecraftStream();");
            foreach (var field in fields)
            {
                string elementType = field.TypeName, elementName = field.Name;
                if (field.IsArray)
                {
                    elementName += "[i]";
                    string lengthProperty;
                    if (field.TypeName.EndsWith("[]"))
                    {
                        lengthProperty = "Length";
                        elementType    = field.TypeName.Substring(0, field.TypeName.Length - 2);
                    }
                    else
                    {
                        lengthProperty = "Count";
                        elementType    = field.TypeName.Substring(5, field.TypeName.Length - 6);
                    }

                    if (field.IsVarLength)
                    {
                        elementType += "_Var";
                    }
                    if (field.IsAbsolute)
                    {
                        elementType += "_Abs";
                    }

                    if (field.FixedLength < 0)
                    {
                        if (field.CountType is null)
                        {
                            builder.Line($"packetStream.WriteVarInt({field.Name}.{lengthProperty});");
                        }
                        else
                        {
                            if (!syntaxProvider.WriteMethods.TryGetValue(field.CountType, out string writeCountMethod))
                            {
                                // CountType has no write method
                                syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no serialization method associated with its count type", field.Declaration));
                                return(false);
                            }

                            builder.Line($"packetStream.{writeCountMethod}(({field.CountType}){field.Name}.{lengthProperty});");
                        }
                    }

                    builder.Statement($"for (int i = 0; i < {field.Name}.{lengthProperty}; i++)");
                }

                if (field.OriginalType is not null)
                {
                    if (field.IsGeneric)
                    {
                        string tempName = $"temp{field.Name}";
                        builder.Line($"var {tempName} = {elementName};");
                        elementName = $"System.Runtime.CompilerServices.Unsafe.As<{field.ActualType}, {field.OriginalType}>(ref {tempName})";
                    }
                    else
                    {
                        elementName = $"({field.OriginalType}){elementName}";
                    }
                }

                if (TryGetMethod(elementType, syntaxProvider.WriteMethods, out string methodName))
                {
                    builder.Line($"packetStream.{methodName}({elementName});");
                }
                else
                {
                    // Creating serialization method failed
#if DEBUG
                    syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no serialization method associated with it", field.Declaration));
#endif
                    return(false);
                }

                if (field.IsArray)
                {
                    // End the for loop
                    builder.EndScope();
                }
            }
            builder.Line("stream.Lock.Wait();");
            builder.Line("stream.WriteVarInt(Id.GetVarIntLength() + (int)packetStream.Length);");
            builder.Line("stream.WriteVarInt(Id);");
            builder.Line("packetStream.Position = 0;");
            builder.Line("packetStream.CopyTo(stream);");
            builder.Line("stream.Lock.Release();");
            return(true);
        }
        private bool CreateSerializationMethod(StringBuilder builder, List <Field> fields, SyntaxProvider syntaxProvider)
        {
            builder.AppendCode("using var packetStream = new MinecraftStream();");
            foreach (var field in fields)
            {
                string elementType = field.TypeName, elementName = field.Name;
                if (field.IsArray)
                {
                    elementName += "[i]";
                    string lengthProperty;
                    if (field.TypeName.EndsWith("[]"))
                    {
                        lengthProperty = "Length";
                        elementType    = field.TypeName.Substring(0, field.TypeName.Length - 2);
                    }
                    else
                    {
                        lengthProperty = "Count";
                        elementType    = field.TypeName.Substring(5, field.TypeName.Length - 6);
                    }

                    if (field.IsVarLength)
                    {
                        elementType += "_Var";
                    }
                    if (field.IsAbsolute)
                    {
                        elementType += "_Abs";
                    }

                    if (field.FixedLength < 0)
                    {
                        builder.AppendCode($"packetStream.WriteVarInt({field.Name}.{lengthProperty});");
                    }

                    builder.AppendCode($"for (int i = 0; i < {field.Name}.{lengthProperty}; i++)");
                    builder.AppendCode("{");
                    builder.Append('\t');
                }

                if (field.OriginalType is not null)
                {
                    if (field.IsGeneric)
                    {
                        elementName = $"({field.OriginalType})(object){elementName}";
                    }
                    else
                    {
                        elementName = $"({field.OriginalType}){elementName}";
                    }
                }

                if (TryGetMethod(elementType, syntaxProvider.WriteMethods, out string methodName))
                {
                    builder.AppendCode($"packetStream.{methodName}({elementName});");
                }
                else
                {
                    // creating serialization method failed
#if DEBUG
                    syntaxProvider.Context.ReportDiagnostic(DiagnosticDescriptors.Create(DiagnosticSeverity.Warning, $"{field.Name} ({field.TypeName})({elementType}) has no serialization method associated with it", field.Declaration));
#endif
                    return(false);
                }

                if (field.IsArray)
                {
                    // end for loop
                    builder.AppendCode("}");
                }
            }
            builder.AppendCode("stream.Lock.Wait();");
            builder.AppendCode("stream.WriteVarInt(Id.GetVarIntLength() + (int)packetStream.Length);");
            builder.AppendCode("stream.WriteVarInt(Id);");
            builder.AppendCode("packetStream.Position = 0;");
            builder.AppendCode("packetStream.CopyTo(stream);");
            builder.AppendCode("stream.Lock.Release();");
            return(true);
        }