Пример #1
0
        public void GenerateEnum(ProtoEnum m)
        {
            if (m.OptionExternal)
            {
                cw.Comment("Written elsewhere");
                cw.Comment(m.Comments);
                cw.Comment(m.OptionAccess + " enum " + m.CsType);
                cw.Comment("{");
                foreach (var epair in m.Enums)
                {
                    cw.Summary(epair.Comment);
                    cw.Comment(cw.IndentPrefix + epair.Name + " = " + epair.Value + ",");
                }
                cw.Comment("}");
                return;
            }

            cw.Summary(m.Comments);
            if (m.OptionFlags)
                cw.Attribute("global::System.FlagsAttribute");
            cw.Bracket(m.OptionAccess + " enum " + m.CsType);
            foreach (var epair in m.Enums)
            {
                cw.Summary(epair.Comment);
                cw.WriteLine(epair.Name + " = " + epair.Value + ",");
            }
            cw.EndBracket();
            cw.WriteLine();
        }
Пример #2
0
        static void ParseEnumValue(TokenReader tr, ProtoEnum parent, string name)
        {
            if (tr.ReadNext() != "=")
            {
                throw new ProtoFormatException("Expected: =", tr);
            }

            int id = ParseInt(tr);

            var value = new ProtoEnumValue(name, id, lastComment);

            parent.Enums.Add(value);

            string extra = tr.ReadNext();

            if (extra == ";")
            {
                return;
            }

            if (extra != "[")
            {
                throw new ProtoFormatException("Expected: ; or [", tr);
            }

            ParseEnumValueOptions(tr);
        }
Пример #3
0
        static void ParseEnum(TokenReader tr, ProtoMessage parent, string package)
        {
            ProtoEnum me = new ProtoEnum(parent, package);

            LocalParser.ParseComments(me, lastComment, tr);
            me.ProtoName = tr.ReadNext();

            parent.Enums.Add(me.ProtoName, me); //must be after .ProtoName is read

            if (tr.ReadNext() != "{")
                throw new ProtoFormatException("Expected: {", tr);

            while (true)
            {
                string name = tr.ReadNext();

                if (ParseComment(name))
                    continue;

                if (name == "}")
                    return;

                //Ignore options
                if (name == "option")
                {
                    ParseOption(tr, null);
                    lastComment.Clear();
                    continue;
                }

                ParseEnumValue(tr, me, name);
            }
        }
Пример #4
0
        public void GenerateEnum(ProtoEnum m)
        {
            if (m.OptionExternal)
            {
                cw.Comment("Written elsewhere");
                cw.Comment(m.Comments);
                cw.Comment(m.OptionAccess + " enum " + m.CsType);
                cw.Comment("{");
                foreach (var epair in m.Enums)
                {
                    cw.Summary(epair.Comment);
                    cw.Comment(cw.IndentPrefix + epair.Name + " = " + epair.Value + ",");
                }
                cw.Comment("}");
                return;
            }

            cw.Summary(m.Comments);
            if (m.OptionFlags)
            {
                cw.Attribute("global::System.FlagsAttribute");
            }
            cw.Bracket(m.OptionAccess + " enum " + m.CsType);
            foreach (var epair in m.Enums)
            {
                cw.Summary(epair.Comment);
                cw.WriteLine(epair.Name + " = " + epair.Value + ",");
            }
            cw.EndBracket();
            cw.WriteLine();
        }
Пример #5
0
        static void ParseEnum(TokenReader tr, ProtoMessage parent, string package)
        {
            ProtoEnum me = new ProtoEnum(parent, package);

            LocalParser.ParseComments(me, lastComment, tr);
            me.ProtoName = tr.ReadNext();

            parent.Enums.Add(me.ProtoName, me); //must be after .ProtoName is read

            if (tr.ReadNext() != "{")
                throw new ProtoFormatException("Expected: {", tr);
            
            while (true)
            {
                string name = tr.ReadNext();

                if (ParseComment(name))
                    continue;
                
                if (name == "}")
                    return;
                
                //Ignore options
                if (name == "option")
                {
                    ParseOption(tr, null);
                    lastComment.Clear();
                    continue;
                }

                ParseEnumValue(tr, me, name);
            }
            
        }
Пример #6
0
 public static void GenerateEnum(ProtoEnum me, CodeWriter cw)
 {
     cw.Bracket("public class " + me.CsNamespace + "_" + me.CsType + "Enum");
     foreach (var epair in me.Enums)
     {
         cw.Summary(epair.Comment);
         cw.WriteLine("public const int " + epair.Name + " = " + epair.Value + ";");
     }
     cw.EndBracket();
     cw.WriteLine();
 }
Пример #7
0
 public static void GenerateEnum(ProtoEnum me, CodeWriter cw)
 {
     cw.Bracket("public class " + me.CsNamespace + "_" + me.CsType + "Enum");
     foreach (var epair in me.Enums)
     {
         cw.Summary(epair.Comment);
         cw.WriteLine("public const int " + epair.Name + " = " + epair.Value + ";");
     }
     cw.EndBracket();
     cw.WriteLine();
 }
Пример #8
0
 public void GenerateEnum(ProtoEnum me)
 {
     cw.Bracket("public enum " + me.CsType);
     foreach (var epair in me.Enums)
     {
         cw.Summary(epair.Comment);
         cw.WriteLine(epair.Name + " = " + epair.Value + ",");
     }
     cw.EndBracket();
     cw.WriteLine();
 }
Пример #9
0
 public void GenerateEnum(ProtoEnum me)
 {
     cw.Bracket("public enum " + me.CsType);
     foreach (var epair in me.Enums)
     {
         cw.Summary(epair.Comment);
         cw.WriteLine(epair.Name + " = " + epair.Value + ",");
     }
     cw.EndBracket();
     cw.WriteLine();
 }
Пример #10
0
 public static void GenerateEnum(ProtoEnum me, CodeWriter cw)
 {
     cw.Bracket("public enum " + me.CsType);
     foreach (var epair in me.Enums)
     {
         if (me.EnumsComments.ContainsKey(epair.Key))
             cw.Summary(me.EnumsComments [epair.Key]);
         cw.WriteLine(epair.Key + " = " + epair.Value + ",");
     }
     cw.EndBracket();
     cw.WriteLine();
 }
Пример #11
0
 static void ParseEnumFlags(ProtoEnum message, string flag)
 {
     switch (flag)
     {
         case "external":
             message.OptionExternal = true;
             break;
         case "flags":
             message.OptionFlags = true;
             break;
         default:
             throw new NotImplementedException("Unknown option: " + flag);
     }
 }
Пример #12
0
        static void ParseEnumFlags(ProtoEnum message, string flag)
        {
            switch (flag)
            {
            case "external":
                message.OptionExternal = true;
                break;

            case "flags":
                message.OptionFlags = true;
                break;

            default:
                throw new NotImplementedException("Unknown option: " + flag);
            }
        }
Пример #13
0
 static void ParseEnumOption(ProtoEnum message, string key, string value)
 {
     //Parse value
     switch (key)
     {
         /* This could be supported if the code generation handles the scope when generating the code for the enum.
         case "namespace":
             message.OptionNamespace = value;
             break;*/
         case "access":
             message.OptionAccess = value;
             break;
         default:
             throw new NotImplementedException("Unknown option: " + key);
     }
 }
Пример #14
0
        static void ParseEnumOption(ProtoEnum message, string key, string value)
        {
            //Parse value
            switch (key)
            {
            /* This could be supported if the code generation handles the scope when generating the code for the enum.
             * case "namespace":
             *  message.OptionNamespace = value;
             *  break;*/
            case "access":
                message.OptionAccess = value;
                break;

            default:
                throw new NotImplementedException("Unknown option: " + key);
            }
        }
Пример #15
0
        static void GenerateDefaults(ProtoMessage m, CodeWriter cw, Options options)
        {
            foreach (Field f in m.Fields.Values)
            {
                if (f.Rule == FieldRule.Repeated)
                {
                    //Initialize lists of the custom DateTime or TimeSpan type.
                    string csType = f.ProtoType.FullCsType;
                    if (f.OptionCodeType != null)
                    {
                        csType = f.OptionCodeType;
                    }

                    cw.WriteLine("if (instance." + f.CsName + " == null)");
                    cw.WriteIndent("instance." + f.CsName + " = Pool.GetList<" + csType + ">();");
                }
                else if (f.OptionDefault != null)
                {
                    if (options.Properties)
                    {
                        if (f.ProtoType is ProtoEnum)
                        {
                            cw.WriteLine("instance." + f.CsName + " = " + f.ProtoType.FullCsType + "." +
                                         f.OptionDefault + ";");
                        }
                        else
                        {
                            cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";");
                        }
                    }
                }
                else if (f.Rule == FieldRule.Optional)
                {
                    if (f.ProtoType is ProtoEnum)
                    {
                        ProtoEnum pe = f.ProtoType as ProtoEnum;
                        //the default value is the first value listed in the enum's type definition
                        foreach (var kvp in pe.Enums)
                        {
                            cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";");
                            break;
                        }
                    }
                }
            }
        }
Пример #16
0
        public void GenerateEnum(ProtoEnum m)
        {
            if (options.NoGenerateImported && m.IsImported)
            {
                Console.Error.WriteLine("Skipping imported enum " + m.FullProtoName);
                return;
            }

            cw.Summary(m.Comments);
            if (m.OptionFlags)
            {
                cw.Attribute("System.FlagsAttribute");
            }
            cw.Bracket("public enum " + m.CsType);
            foreach (var epair in m.Enums)
            {
                cw.Summary(epair.Comment);
                cw.WriteLine(epair.Name + " = " + epair.Value + ",");
            }
            cw.EndBracket();
            cw.WriteLine();
        }
Пример #17
0
        private void GenerateDefaults(ProtoMessage m)
        {
            //Prepare List<> and default values
            foreach (Field f in m.Fields.Values)
            {
                if (f.Rule == FieldRule.Repeated)
                {
                    if (f.OptionReadOnly == false)
                    {
                        //Initialize lists of the custom DateTime or TimeSpan type.
                        string csType = f.ProtoType.FullCsType;
                        if (f.OptionCodeType != null)
                        {
                            csType = f.OptionCodeType;
                        }

                        cw.WriteLine("if (instance." + f.CsName + " == null)");
                        cw.WriteIndent("instance." + f.CsName + " = new List<" + csType + ">();");
                    }
                }
                else if (f.OptionDefault != null)
                {
                    cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";");
                }
                else if ((f.Rule == FieldRule.Optional) && !options.Nullable)
                {
                    if (f.ProtoType is ProtoEnum)
                    {
                        ProtoEnum pe = f.ProtoType as ProtoEnum;
                        //the default value is the first value listed in the enum's type definition
                        foreach (var kvp in pe.Enums)
                        {
                            cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";");
                            break;
                        }
                    }
                }
            }
        }
Пример #18
0
        static void ParseEnumValue(TokenReader tr, ProtoEnum parent, string name)
        {
            if (tr.ReadNext() != "=")
                throw new ProtoFormatException("Expected: =", tr);

            int id = int.Parse(tr.ReadNext());

            var value = new ProtoEnumValue(name, id, lastComment);
            parent.Enums.Add(value);

            string extra = tr.ReadNext();

            if (extra == ";")
                return;

            if (extra != "[")
                throw new ProtoFormatException("Expected: ; or [", tr);

            ParseEnumValueOptions(tr, value);
        }
Пример #19
0
        static void GenerateReader(ProtoMessage m, CodeWriter cw)
        {
            #region Helper Deserialize Methods
            string refstr = (m.OptionType == "struct") ? "ref " : "";
            if (m.OptionType != "interface")
            {
                cw.Summary("Helper: create a new instance to deserializing into");
                cw.Bracket(m.OptionAccess + " static " + m.CsType + " Deserialize(Stream stream)");
                cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();");
                cw.WriteLine("Deserialize(stream, " + refstr + "instance);");
                cw.WriteLine("return instance;");
                cw.EndBracketSpace();

                cw.Summary("Helper: create a new instance to deserializing into");
                cw.Bracket(m.OptionAccess + " static " + m.CsType + " DeserializeLengthDelimited(Stream stream)");
                cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();");
                cw.WriteLine("DeserializeLengthDelimited(stream, " + refstr + "instance);");
                cw.WriteLine("return instance;");
                cw.EndBracketSpace();

                cw.Summary("Helper: create a new instance to deserializing into");
                cw.Bracket(m.OptionAccess + " static " + m.CsType + " DeserializeLength(Stream stream, int length)");
                cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();");
                cw.WriteLine("DeserializeLength(stream, length, " + refstr + "instance);");
                cw.WriteLine("return instance;");
                cw.EndBracketSpace();

                cw.Summary("Helper: put the buffer into a MemoryStream and create a new instance to deserializing into");
                cw.Bracket(m.OptionAccess + " static " + m.CsType + " Deserialize(byte[] buffer)");
                cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();");
                cw.WriteLine("using (var ms = new MemoryStream(buffer))");
                cw.WriteIndent("Deserialize(ms, " + refstr + "instance);");
                cw.WriteLine("return instance;");
                cw.EndBracketSpace();
            }

            cw.Summary("Helper: put the buffer into a MemoryStream before deserializing");
            cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " Deserialize(byte[] buffer, " + refstr + m.FullCsType + " instance)");
            cw.WriteLine("using (var ms = new MemoryStream(buffer))");
            cw.WriteIndent("Deserialize(ms, " + refstr + "instance);");
            cw.WriteLine("return instance;");
            cw.EndBracketSpace();
            #endregion

            string[] methods = new string[]
            {
                "Deserialize",                //Default old one
                "DeserializeLengthDelimited", //Start by reading length prefix and stay within that limit
                "DeserializeLength",          //Read at most length bytes given by argument
            };

            //Main Deserialize
            foreach (string method in methods)
            {
                if (method == "Deserialize")
                {
                    cw.Summary("Takes the remaining content of the stream and deserialze it into the instance.");
                    cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, " + refstr + m.FullCsType + " instance)");
                }
                else if (method == "DeserializeLengthDelimited")
                {
                    cw.Summary("Read the VarInt length prefix and the given number of bytes from the stream and deserialze it into the instance.");
                    cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, " + refstr + m.FullCsType + " instance)");
                }
                else if (method == "DeserializeLength")
                {
                    cw.Summary("Read the given number of bytes from the stream and deserialze it into the instance.");
                    cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, int length, " + refstr + m.FullCsType + " instance)");
                }
                else
                {
                    throw new NotImplementedException();
                }

                if (m.IsUsingBinaryWriter)
                {
                    cw.WriteLine("BinaryReader br = new BinaryReader(stream);");
                }

                //Prepare List<> and default values
                foreach (Field f in m.Fields.Values)
                {
                    if (f.Rule == FieldRule.Repeated)
                    {
                        if (f.OptionReadOnly == false)
                        {
                            //Initialize lists of the custom DateTime or TimeSpan type.
                            string csType = f.ProtoType.FullCsType;
                            if (f.OptionCodeType != null)
                            {
                                csType = f.OptionCodeType;
                            }

                            cw.WriteLine("if (instance." + f.CsName + " == null)");
                            cw.WriteIndent("instance." + f.CsName + " = new List<" + csType + ">();");
                        }
                    }
                    else if (f.OptionDefault != null)
                    {
                        cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";");
                    }
                    else if (f.Rule == FieldRule.Optional)
                    {
                        if (f.ProtoType is ProtoEnum)
                        {
                            ProtoEnum pe = f.ProtoType as ProtoEnum;
                            //the default value is the first value listed in the enum's type definition
                            foreach (var kvp in pe.Enums)
                            {
                                cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";");
                                break;
                            }
                        }
                    }
                }

                if (method == "DeserializeLengthDelimited")
                {
                    //Important to read stream position after we have read the length field
                    cw.WriteLine("long limit = global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadUInt32(stream);");
                    cw.WriteLine("limit += stream.Position;");
                }
                if (method == "DeserializeLength")
                {
                    //Important to read stream position after we have read the length field
                    cw.WriteLine("long limit = stream.Position + length;");
                }

                cw.WhileBracket("true");

                if (method == "DeserializeLengthDelimited" || method == "DeserializeLength")
                {
                    cw.IfBracket("stream.Position >= limit");
                    cw.WriteLine("if (stream.Position == limit)");
                    cw.WriteIndent("break;");
                    cw.WriteLine("else");
                    cw.WriteIndent("throw new global::SilentOrbit.ProtocolBuffers.ProtocolBufferException(\"Read past max limit\");");
                    cw.EndBracket();
                }

                cw.WriteLine("int keyByte = stream.ReadByte();");
                cw.WriteLine("if (keyByte == -1)");
                if (method == "Deserialize")
                {
                    cw.WriteIndent("break;");
                }
                else
                {
                    cw.WriteIndent("throw new System.IO.EndOfStreamException();");
                }

                //Determine if we need the lowID optimization
                bool hasLowID = false;
                foreach (Field f in m.Fields.Values)
                {
                    if (f.ID < 16)
                    {
                        hasLowID = true;
                        break;
                    }
                }

                if (hasLowID)
                {
                    cw.Comment("Optimized reading of known fields with field ID < 16");
                    cw.Switch("keyByte");
                    foreach (Field f in m.Fields.Values)
                    {
                        if (f.ID >= 16)
                        {
                            continue;
                        }
                        cw.Dedent();
                        cw.Comment("Field " + f.ID + " " + f.WireType);
                        cw.Indent();
                        cw.Case(((f.ID << 3) | (int)f.WireType));
                        if (FieldSerializer.FieldReader(f, cw))
                        {
                            cw.WriteLine("continue;");
                        }
                    }
                    cw.SwitchEnd();
                    cw.WriteLine();
                }
                cw.WriteLine("var key = global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadKey((byte)keyByte, stream);");

                cw.WriteLine();

                cw.Comment("Reading field ID > 16 and unknown field ID/wire type combinations");
                cw.Switch("key.Field");
                cw.Case(0);
                cw.WriteLine("throw new global::SilentOrbit.ProtocolBuffers.ProtocolBufferException(\"Invalid field id: 0, something went wrong in the stream\");");
                foreach (Field f in m.Fields.Values)
                {
                    if (f.ID < 16)
                    {
                        continue;
                    }
                    cw.Case(f.ID);
                    //Makes sure we got the right wire type
                    cw.WriteLine("if(key.WireType != global::SilentOrbit.ProtocolBuffers.Wire." + f.WireType + ")");
                    cw.WriteIndent("break;"); //This can be changed to throw an exception for unknown formats.
                    if (FieldSerializer.FieldReader(f, cw))
                    {
                        cw.WriteLine("continue;");
                    }
                }
                cw.CaseDefault();
                if (m.OptionPreserveUnknown)
                {
                    cw.WriteLine("if (instance.PreservedFields == null)");
                    cw.WriteIndent("instance.PreservedFields = new List<global::SilentOrbit.ProtocolBuffers.KeyValue>();");
                    cw.WriteLine("instance.PreservedFields.Add(new global::SilentOrbit.ProtocolBuffers.KeyValue(key, global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadValueBytes(stream, key)));");
                }
                else
                {
                    cw.WriteLine("global::SilentOrbit.ProtocolBuffers.ProtocolParser.SkipKey(stream, key);");
                }
                cw.WriteLine("break;");
                cw.SwitchEnd();
                cw.EndBracket();
                cw.WriteLine();

                if (m.OptionTriggers)
                {
                    cw.WriteLine("instance.AfterDeserialize();");
                }
                cw.WriteLine("return instance;");
                cw.EndBracket();
                cw.WriteLine();
            }

            return;
        }