public ProtoCollection Import(IEnumerable<string> inputProto)
        {
            var collection = new ProtoCollection();

            //Files from command line arguments, all import statements will be followed
            var basePath = Path.Combine(Path.GetFullPath(Directory.GetCurrentDirectory()), "dummy"); 
            foreach (string rawPath in inputProto)
            {
                string protoPath = GetFullPath(basePath, rawPath);
                var proto = Import(protoPath);
                collection.Merge(proto);

                //Include non public imports for the first level
                foreach (var path in proto.Import)
                    toImport.Add(GetFullPath(protoPath, path));
            }

            //Read imported files, nested
            while (toImport.Count != 0)
            {
                var path = toImport[0];
                toImport.RemoveAt(0);

                var c = Import(path);
                if (c != null)
                {
                    //Mark imported
                    c.MarkImported();

                    collection.Merge(c);
                }
            }
            return collection;
        }
Exemple #2
0
        public ProtoCollection Import(IEnumerable <string> inputProto)
        {
            var collection = new ProtoCollection();

            //Files from command line arguments, all import statements will be followed
            var basePath = Path.Combine(Path.GetFullPath(Directory.GetCurrentDirectory()), "dummy");

            foreach (string rawPath in inputProto)
            {
                string protoPath = GetFullPath(basePath, rawPath);
                var    proto     = Import(protoPath);
                collection.Merge(proto);

                //Include non public imports for the first level
                foreach (var path in proto.Import)
                {
                    toImport.Add(GetFullPath(protoPath, path));
                }
            }

            //Read imported files, nested
            while (toImport.Count != 0)
            {
                var path = toImport[0];
                toImport.RemoveAt(0);

                var c = Import(path);
                if (c != null)
                {
                    collection.Merge(c);
                }
            }
            return(collection);
        }
Exemple #3
0
        /// <summary>
        /// Parse a single .proto file.
        /// Return true if successful/no errors.
        /// </summary>
        public static void Parse(string path, ProtoCollection p)
        {
            //Preparation for parsing
            //Real parsing is done in ParseMessages
            lastComment.Clear();

            //Read entire file and pass it into a TokenReader
            string t = "";

            using (TextReader reader = new StreamReader(path, Encoding.UTF8))
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    t += line + "\n";
                }
            }
            TokenReader tr = new TokenReader(t, path);

            try
            {
                ParseMessages(tr, p);
            }
            catch (EndOfStreamException)
            {
                return;
            }
        }
        ProtoCollection Import(string protoPath)
        {
            if (imported.ContainsKey(protoPath))
                return null; //Already imported
                
            var proto = new ProtoCollection();

            try
            {
                Console.WriteLine("Parsing " + protoPath);
                ProtoParser.Parse(protoPath, proto);
            }
            catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                throw;
            }

            foreach (var path in proto.ImportPublic)
                toImport.Add(GetFullPath(protoPath, path));

            imported.Add(protoPath, proto);

            return proto;
        }
Exemple #5
0
        ProtoCollection Import(string protoPath)
        {
            if (imported.ContainsKey(protoPath))
            {
                return(null); //Already imported
            }
            var proto = new ProtoCollection();

            try
            {
                Console.WriteLine("Parsing " + protoPath);
                ProtoParser.Parse(protoPath, proto);
            }
            catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                throw;
            }

            foreach (var path in proto.ImportPublic)
            {
                toImport.Add(GetFullPath(protoPath, path));
            }

            imported.Add(protoPath, proto);

            return(proto);
        }
Exemple #6
0
        /// <summary>
        /// Parse a single .proto file.
        /// Return true if successful/no errors.
        /// </summary>
        public static void Parse(string path, ProtoCollection p)
        {
            //Preparation for parsing
            //Real parsing is done in ParseMessages
            lastComment.Clear();

            //Read entire file and pass it into a TokenReader
            string t = "";
            using (TextReader reader = new StreamReader(path, Encoding.UTF8))
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null)
                        break;

                    t += line + "\n";
                }
            }
            TokenReader tr = new TokenReader(t, path);

            try
            {
                ParseMessages(tr, p);
            }
            catch (EndOfStreamException)
            {
                return;
            }
        }
Exemple #7
0
        /// <summary>
        /// Parse a single .proto file.
        /// Return true if successful/no errors.
        /// </summary>
        public static void Parse(string path, ProtoCollection p, bool fixComments)
        {
            //Preparation for parsing
            //Real parsing is done in ParseMessages
            lastComment.Clear();

            TextReader reader = null;

            if (fixComments)
            {
                var text = File.ReadAllLines(path).ToList();
                for (int i = 0; i < text.Count; i++)
                {
                    if (!text[i].TrimStart().StartsWith("//") && text[i].Contains("//"))
                    {
                        var splitted = text[i].Split(new [] { "//" }, StringSplitOptions.None);
                        text[i] = splitted[0];
                        text.Insert(i, "//" + splitted[1]);
                        if (splitted.Length > 2)
                        {
                            Console.WriteLine("More then 2 comments in line " + i);
                            throw new Exception();
                        }

                        i--;
                    }
                    reader = new StringReader(string.Join("\n", text));
                }
            }
            else
            {
                reader = new StreamReader(path, Encoding.UTF8);
            }

            //Read entire file and pass it into a TokenReader
            string t = "";

            while (true)
            {
                string line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }

                t += line + "\n";
            }
            reader.Close();
            TokenReader tr = new TokenReader(t, path);

            try
            {
                ParseMessages(tr, p);
            }
            catch (EndOfStreamException)
            {
                return;
            }
        }
Exemple #8
0
        static void ParseMessages(TokenReader tr, ProtoCollection p)
        {
            string package = "Example";

            while (true)
            {
                string token = tr.ReadNext();
                if (ParseComment(token))
                {
                    continue;
                }

                try
                {
                    switch (token)
                    {
                    case ";":
                        lastComment.Clear();
                        continue;

                    case "message":
                        ParseMessage(tr, p, package);
                        break;

                    case "enum":
                        ParseEnum(tr, p, package);
                        break;

                    case "option":
                        //Save options
                        ParseOption(tr, p);
                        break;

                    case "import":     //Ignored
                        tr.ReadNext();
                        tr.ReadNextOrThrow(";");
                        break;

                    case "package":
                        package = tr.ReadNext();
                        tr.ReadNextOrThrow(";");
                        break;

                    case "extend":
                        ParseExtend(tr, p, package);
                        break;

                    default:
                        throw new ProtoFormatException("Unexpected/not implemented: " + token, tr);
                    }
                } catch (EndOfStreamException)
                {
                    throw new ProtoFormatException("Unexpected EOF", tr);
                }
            }
        }
        static void ParseMessages(TokenReader tr, ProtoCollection p)
        {
            string package = "Example";

            while (true)
            {
                string token = tr.ReadNextComment();
                if (ParseComment(token))
                    continue;

                try
                {
                    switch (token)
                    {
                        case ";":
                            break;
                        case "message":
                            ParseMessage(tr, p, package);
                            break;
                        case "enum":
                            ParseEnum(tr, p, package);
                            break;
                        case "option":
                            //Save options
                            ParseOption(tr, p);
                            break;
                        case "import":
                            ParseImport(tr, p);
                            break;
                        case "package":
                            package = tr.ReadNext();
                            tr.ReadNextOrThrow(";");
                            break;
                        case "syntax": //This is not a supported protobuf keyword, used in Google internally
                            tr.ReadNextOrThrow("=");
                            tr.ReadNext();
                            tr.ReadNextOrThrow(";");
                            break;
                        case "extend":
                            ParseExtend(tr, p, package);
                            break;
                        default:
                            throw new ProtoFormatException("Unexpected/not implemented: " + token, tr);
                    }
                    lastComment.Clear();
                }
                catch (EndOfStreamException)
                {
                    throw new ProtoFormatException("Unexpected EOF", tr);
                }
            }
        }
 public void Merge(ProtoCollection proto)
 {
     foreach (var m in proto.Messages.Values)
     {
         Messages.Add(m.ProtoName, m);
         m.Parent = this;
     }
     foreach (var e in proto.Enums.Values)
     {
         Enums.Add(e.ProtoName, e);
         e.Parent = this;
     }
 }
Exemple #11
0
 public void Merge(ProtoCollection proto)
 {
     foreach (var m in proto.Messages.Values)
     {
         Messages.Add(m.ProtoName, m);
         m.Parent = this;
     }
     foreach (var e in proto.Enums.Values)
     {
         Enums.Add(e.ProtoName, e);
         e.Parent = this;
     }
 }
Exemple #12
0
 public void Merge(ProtoCollection proto)
 {
     foreach (var m in proto.Messages.Values)
     {
         Messages.Add(m.ProtoName, m);
         m.Parent = this;
     }
     foreach (var e in proto.Enums.Values)
     {
         Enums.Add(e.ProtoName, e);
         e.Parent = this;
     }
     Comments = Comments == null ? proto.Comments : Comments + "\n" + proto.Comments;
 }
Exemple #13
0
        public static int Main(string[] args)
        {
            var options = Options.Parse(args);

            if (options == null)
            {
                return(-1);
            }

            ProtoCollection collection = new ProtoCollection();

            foreach (string protoPath in options.InputProto)
            {
                try
                {
                    Console.WriteLine("Parsing " + protoPath);

                    var proto = new ProtoCollection();
                    ProtoParser.Parse(protoPath, proto);
                    collection.Merge(proto);
                }
                catch (ProtoFormatException pfe)
                {
                    Console.WriteLine();
                    Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                    return(-1);
                }
            }

            Console.WriteLine(collection);

            //Interpret and reformat
            try
            {
                var pp = new ProtoPrepare(options);
                pp.Prepare(collection);
            }
            catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                return(-1);
            }

            //Generate code
            ProtoCode.Save(collection, options);
            Console.WriteLine("Saved: " + options.OutputPath);
            return(0);
        }
        public void Prepare(ProtoCollection file)
        {
            foreach (ProtoMessage m in file.Messages.Values)
            {
                if (m.OptionNamespace == null)
                    m.OptionNamespace = GetCamelCase(m.Package);
                PrepareMessage(m);
            }

            foreach (ProtoEnum e in file.Enums.Values)
            {
                if (e.OptionNamespace == null)
                    e.OptionNamespace = GetCamelCase(e.Package);
                e.CsType = GetCamelCase(e.ProtoName);
            }
        }
Exemple #15
0
        public static int Main(string[] args)
        {
            var options = Options.Parse(args);
            if(options == null)
                return -1;

            ProtoCollection collection = new ProtoCollection();

            foreach(string protoPath in options.InputProto)
            {
                try
                {
                    Console.WriteLine("Parsing " + protoPath);

                    var proto = new ProtoCollection();
                    ProtoParser.Parse(protoPath, proto);
                    collection.Merge(proto);
                }
                catch (ProtoFormatException pfe)
                {
                    Console.WriteLine();
                    Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                    return -1;
                }
            }

            Console.WriteLine(collection);

            //Interpret and reformat
            try
            {
                var pp = new ProtoPrepare(options);
                pp.Prepare(collection);
            }
            catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                return -1;
            }

            //Generate code
            ProtoCode.Save(collection, options);
            Console.WriteLine("Saved: " + options.OutputPath);
            return 0;
        }
Exemple #16
0
        static public void Prepare(ProtoCollection file)
        {
            foreach (ProtoMessage m in file.Messages.Values)
            {
                if (m.OptionNamespace == null)
                {
                    m.OptionNamespace = GetCamelCase(m.Package);
                }
                PrepareMessage(m);
            }

            foreach (ProtoEnum e in file.Enums.Values)
            {
                if (e.OptionNamespace == null)
                {
                    e.OptionNamespace = GetCamelCase(e.Package);
                }
                e.CsType = GetCamelCase(e.ProtoName);
            }
        }
Exemple #17
0
        static void ParseImport(TokenReader tr, ProtoCollection collection)
        {
            string path         = tr.ReadNext();
            bool   publicImport = path == "public";

            if (publicImport)
            {
                path = tr.ReadNext();
            }
            tr.ReadNextOrThrow(";");

            if (publicImport)
            {
                collection.ImportPublic.Add(path);
            }
            else
            {
                collection.Import.Add(path);
            }
        }
Exemple #18
0
        /// <summary>
        /// Parse a single .proto file.
        /// Return true if successful/no errors.
        /// </summary>
        public static void Parse(string path, ProtoCollection p)
        {
            //Preparation for parsing
            //Real parsing is done in ParseMessages
            lastComment.Clear();

            var codeFile = Path.GetExtension(path).ToLower().Equals(".cs");

            //Read entire file and pass it into a TokenReader
            string t = "";

            using (TextReader reader = new StreamReader(path, Encoding.UTF8))
            {
                if (codeFile)
                {
                    t = ReadAllLinesCodeFile(reader);
                }
                else
                {
                    t = ReadAllLinesProto(reader);
                }
            }

            if (t.Length == 0)
            {
                return;
            }

            Console.WriteLine("Parsing " + path);

            TokenReader tr = new TokenReader(t, path);

            try
            {
                ParseMessages(tr, p);
            }
            catch (EndOfStreamException)
            {
                return;
            }
        }
Exemple #19
0
        public static void Build(Options options)
        {
            ProtoCollection collection = new ProtoCollection();

            foreach (string protoPath in options.InputProto)
            {
                try
                {
                    var proto = new ProtoCollection();
                    ProtoParser.Parse(protoPath, proto);
                    collection.Merge(proto);
                }
                catch (ProtoFormatException pfe)
                {
                    Console.WriteLine();
                    Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                    throw;
                }
            }

            Console.WriteLine(collection);

            //Interpret and reformat
            try
            {
                var pp = new ProtoPrepare(options);
                pp.Prepare(collection);
            }
            catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                throw;
            }

            //Generate code
            ProtoCode.Save(collection, options);
            Console.WriteLine("Saved: " + options.OutputPath);
        }
Exemple #20
0
        /// <summary>
        /// Generate code for reading and writing protocol buffer messages
        /// </summary>
        public static void Save(ProtoCollection file, string csPath)
        {
            string ext    = Path.GetExtension(csPath);
            string prefix = csPath.Substring(0, csPath.Length - ext.Length);

            string csDir = Path.GetDirectoryName(csPath);

            if (Directory.Exists(csDir) == false)
            {
                Directory.CreateDirectory(csDir);
            }

            //Basic structures
            using (var cw = new CodeWriter(csPath))
            {
                cw.Comment(@"Classes and structures being serialized");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
- a pure c# code generation implementation of protocol buffers
Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.
To make custom modifications, edit the .proto file and add //:external before the message line
then write the code and the changes in a separate file.");

                //cw.WriteLine("using System;");
                //cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                //string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {/*
                  * if (ns != m.CsNamespace)
                  * {
                  *     if (ns != null) //First time
                  *         cw.EndBracket();
                  *     cw.Bracket("namespace " + m.CsNamespace);
                  *     ns = m.CsNamespace;
                  * }*/
                    MessageCode.GenerateClass(m, cw);
                    cw.WriteLine();
                }

                foreach (ProtoEnum e in file.Enums.Values)
                {/*
                  * if (ns != e.CsNamespace)
                  * {
                  *     if (ns != null) //First time
                  *         cw.EndBracket();
                  *     cw.Bracket("namespace " + e.CsNamespace);
                  *     ns = e.CsNamespace;
                  * }*/
                    MessageCode.GenerateEnum(e, cw);
                    cw.WriteLine();
                }

                //cw.EndBracket();
            }

            //.Serializer.cs
            //Code for Reading/Writing
            using (var cw = new CodeWriter(prefix + ".Serializer" + ext))
            {
                cw.Comment(@"This is the backend code for reading and writing");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
- a pure c# code generation implementation of protocol buffers
Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.");

                //cw.WriteLine("using System;");
                //cw.WriteLine("using System.IO;");
                cw.WriteLine();

                //string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    //if (ns != m.CsNamespace)
                    //{
                    //    if (ns != null) //First time
                    //        cw.EndBracket();
                    //    cw.Bracket("namespace " + m.CsNamespace);
                    //    ns = m.CsNamespace;
                    //}
                    MessageSerializer.GenerateClassSerializer(m, cw);
                }
                //cw.EndBracket();
            }

            string libPath = Path.Combine(Path.GetDirectoryName(csPath), "ProtocolParser.cs");

            using (TextWriter codeWriter = new StreamWriter(libPath, false, Encoding.UTF8))
            {
                ReadCode(codeWriter, "ProtocolParser", true);
                ReadCode(codeWriter, "ProtocolParserFixed", false);
                ReadCode(codeWriter, "ProtocolParserKey", false);
                ReadCode(codeWriter, "ProtocolParserVarInt", false);
            }

            string output1 = File.ReadAllText(libPath);
            string output2 = File.ReadAllText(csPath);
            string output3 = File.ReadAllText(prefix + ".Serializer" + ext);

            File.WriteAllText(prefix + ".Serializer" + ".ci.cs", output1 + output2 + output3);
        }
Exemple #21
0
        /// <summary>
        /// Generate code for reading and writing protocol buffer messages
        /// </summary>
        public static void Save(ProtoCollection file, Options options)
        {
            string csPath = options.OutputPath;

            CodeWriter.DefaultIndentPrefix = options.UseTabs ? "\t" : "    ";

            string ext    = Path.GetExtension(csPath);
            string prefix = csPath.Substring(0, csPath.Length - ext.Length);

            string csDir = Path.GetDirectoryName(csPath);

            if (Directory.Exists(csDir) == false)
            {
                Directory.CreateDirectory(csDir);
            }

            //Basic structures
            using (var cw = new CodeWriter(csPath))
            {
                if (string.IsNullOrWhiteSpace(file.Comments) == false)
                {
                    cw.Comment(file.Comments);
                    cw.WriteLine();
                }

                cw.Comment(@"Classes and structures being serialized");
                cw.WriteLine();
                cw.Comment(Disclamer);
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.
To make custom modifications, edit the .proto file and add //:external before the message line
then write the code and the changes in a separate file.");

                cw.WriteLine();
                cw.Comment("ReSharper disable InconsistentNaming");
                cw.WriteLine();

                cw.WriteLine("using System;");
                cw.WriteLine("using System.Collections.Generic;");
                if (options.DataContractAttributes)
                {
                    cw.WriteLine("using System.Runtime.Serialization;");
                }
                cw.WriteLine();

                var messageCode = new MessageCode(cw, options);

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }
                        cw.Bracket("namespace " + m.CsNamespace);
                        ns = m.CsNamespace;
                    }
                    messageCode.GenerateClass(m);
                    cw.WriteLine();
                }

                foreach (ProtoEnum e in file.Enums.Values)
                {
                    if (ns != e.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }
                        cw.Bracket("namespace " + e.CsNamespace);
                        ns = e.CsNamespace;
                    }
                    messageCode.GenerateEnum(e);
                    cw.WriteLine();
                }

                if (ns != null)
                {
                    cw.EndBracket();
                }
            }

            //.Serializer.cs
            //Code for Reading/Writing
            using (var cw = new CodeWriter(prefix + ".Serializer" + ext))
            {
                if (string.IsNullOrWhiteSpace(file.Comments) == false)
                {
                    cw.Comment(file.Comments);
                    cw.WriteLine();
                }

                cw.Comment(@"This is the backend code for reading and writing");
                cw.WriteLine();
                cw.Comment(Disclamer);
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.");

                cw.WriteLine();
                cw.Comment("ReSharper disable InconsistentNaming");
                cw.WriteLine();

                cw.WriteLine("using System;");
                cw.WriteLine("using System.IO;");
                cw.WriteLine("using System.Text;");
                cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }
                        cw.Bracket("namespace " + m.CsNamespace);
                        ns = m.CsNamespace;
                    }
                    var messageSerializer = new MessageSerializer(cw, options);
                    messageSerializer.GenerateClassSerializer(m);
                }
                if (ns != null)
                {
                    cw.EndBracket();
                }
            }

            //Option to no include ProtocolParser.cs in the output directory
            if (options.NoProtocolParser)
            {
                Console.Error.WriteLine("ProtocolParser.cs not (re)generated");
            }
            else
            {
                string libPath = Path.Combine(Path.GetDirectoryName(csPath), "ProtocolParser.cs");
                using (TextWriter codeWriter = new StreamWriter(libPath, false, Encoding.UTF8))
                {
                    codeWriter.NewLine = "\r\n";
                    ReadCode(codeWriter, "ProtocolParser", true);
                    ReadCode(codeWriter, "ProtocolParserExceptions", false);
                    ReadCode(codeWriter, "ProtocolParserFixed", false);
                    ReadCode(codeWriter, "ProtocolParserKey", false);
                    ReadCode(codeWriter, "ProtocolParserMemory", false);
                    if (options.Net2 == false)
                    {
                        ReadCode(codeWriter, "ProtocolParserMemory4", false);
                    }
                    ReadCode(codeWriter, "ProtocolParserVarInt", false);
                }
            }
        }
Exemple #22
0
        static void ParseMessages(TokenReader tr, ProtoCollection p)
        {
            string package = "Example";

            while (true)
            {
                string token = tr.ReadNextComment();
                if (ParseComment(token))
                {
                    continue;
                }

                try
                {
                    switch (token)
                    {
                    case ";":
                        break;

                    case "message":
                        ParseMessage(tr, p, package);
                        break;

                    case "enum":
                        ParseEnum(tr, p, package);
                        break;

                    case "option":
                        //Save options
                        ParseOption(tr, p);
                        break;

                    case "import":
                        ParseImport(tr, p);
                        break;

                    case "package":
                        package = tr.ReadNext();
                        tr.ReadNextOrThrow(";");
                        break;

                    case "syntax":     //This is not a supported protobuf keyword, used in Google internally
                        tr.ReadNextOrThrow("=");
                        tr.ReadNext();
                        tr.ReadNextOrThrow(";");
                        break;

                    case "extend":
                        ParseExtend(tr, p, package);
                        break;

                    default:
                        throw new ProtoFormatException("Unexpected/not implemented: " + token, tr);
                    }
                    lastComment.Clear();
                }
                catch (EndOfStreamException)
                {
                    throw new ProtoFormatException("Unexpected EOF", tr);
                }
            }
        }
Exemple #23
0
        public static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Error.WriteLine("Usage:\n\tCodeGenerator.exe [--preserve-names] [--use-tabs] path-to.proto [path-to-second.proto [...]] [output.cs]");
                return(-1);
            }

            ProtoCollection collection = new ProtoCollection();
            string          outputPath = null;

            int argIndex = 0;

            while (args.Length > argIndex && args [argIndex].StartsWith("--"))
            {
                switch (args[argIndex])
                {
                case "--preserve-names":
                    ProtoPrepare.ConvertToCamelCase = false;
                    break;

                case ProtoPrepare.FixNameclashArgument:
                    ProtoPrepare.FixNameclash = true;
                    break;

                case "--use-tabs":
                    CodeWriter.IndentPrefix = "\t";
                    break;

                default:
                    Console.Error.WriteLine("Unknown option: " + args[argIndex]);
                    return(-1);
                }
                argIndex++;
            }

            while (argIndex < args.Length)
            {
                string protoPath = Path.GetFullPath(args[argIndex]);
                string protoBase = Path.Combine(
                    Path.GetDirectoryName(protoPath),
                    Path.GetFileNameWithoutExtension(protoPath));
                argIndex += 1;

                //First .proto filename is used as output unless specified later
                if (outputPath == null)
                {
                    outputPath = protoBase + ".cs";
                }

                //Handle last argument as the output .cs path
                if (argIndex == args.Length && protoPath.EndsWith(".cs"))
                {
                    outputPath = protoPath;
                    break;
                }

                //Handle last argument as the output path
                //Filename is taken from first .proto argument
                if (argIndex == args.Length && protoPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    Directory.CreateDirectory(protoPath);

                    // Replace the original output directory with the custom one
                    outputPath = Path.Combine(protoPath, Path.GetFileName(outputPath));
                    break;
                }

                if (File.Exists(protoPath) == false)
                {
                    Console.Error.WriteLine("File not found: " + protoPath);
                    return(-1);
                }

                try
                {
                    var proto = new ProtoCollection();

                    //Parse .proto
                    Console.WriteLine("Parsing " + protoPath);
                    ProtoParser.Parse(protoPath, proto);

                    collection.Merge(proto);
                } catch (ProtoFormatException pfe)
                {
                    Console.WriteLine();
                    Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                    return(-1);
                }
            }

            Console.WriteLine(collection);

            //Interpret and reformat
            try
            {
                ProtoPrepare.Prepare(collection);
            } catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                return(-1);
            }

            //Generate code
            ProtoCode.Save(collection, outputPath);
            Console.WriteLine("Saved: " + outputPath);
            return(0);
        }
Exemple #24
0
        /// <summary>
        /// Generate code for reading and writing protocol buffer messages
        /// </summary>
        public static void Save(ProtoCollection file, Options options)
        {
            string csPath = options.OutputPath;

            CodeWriter.DefaultIndentPrefix = options.UseTabs ? "\t" : "    ";

            string ext    = Path.GetExtension(csPath);
            string prefix = csPath.Substring(0, csPath.Length - ext.Length);

            string csDir = Path.GetDirectoryName(csPath);

            if (Directory.Exists(csDir) == false)
            {
                Directory.CreateDirectory(csDir);
            }

            //Basic structures
            using (var cw = new CodeWriter(csPath))
            {
                cw.Comment(@"Classes and structures being serialized");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
- a pure c# code generation implementation of protocol buffers
Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.
To make custom modifications, edit the .proto file and add //:external before the message line
then write the code and the changes in a separate file.");

                cw.WriteLine("using System;");
                cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                var messageCode = new MessageCode(cw, options);

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }

                        if (m.CsNamespace == "global")
                        {
                            ns = null;
                        }
                        else
                        {
                            cw.Bracket("namespace " + m.CsNamespace);
                            ns = m.CsNamespace;
                        }
                    }
                    messageCode.GenerateClass(m);
                    cw.WriteLine();
                }

                foreach (ProtoEnum e in file.Enums.Values)
                {
                    if (ns != e.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }
                        cw.Bracket("namespace " + e.CsNamespace);
                        ns = e.CsNamespace;
                    }
                    messageCode.GenerateEnum(e);
                    cw.WriteLine();
                }

                if (ns != null)
                {
                    cw.EndBracket();
                }
            }

            //.Serializer.cs
            //Code for Reading/Writing
            using (var cw = new CodeWriter(prefix + ".Serializer" + ext))
            {
                cw.Comment(@"This is the backend code for reading and writing");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
- a pure c# code generation implementation of protocol buffers
Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
This file will be overwritten when CodeGenerator is run.");

                cw.WriteLine("using System;");
                cw.WriteLine("using System.IO;");
                cw.WriteLine("using System.Text;");
                cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                cw.WriteLine("#pragma warning disable 0472, 0162");
                cw.WriteLine();

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                        {
                            cw.EndBracket();
                        }

                        if (m.CsNamespace == "global")
                        {
                            ns = null;
                        }
                        else
                        {
                            cw.Bracket("namespace " + m.CsNamespace);
                            ns = m.CsNamespace;
                        }
                    }
                    var messageSerializer = new MessageSerializer(cw, options);
                    messageSerializer.GenerateClassSerializer(m);
                }

                if (ns != null)
                {
                    cw.EndBracket();
                }
            }

            string libPath = Path.Combine(Path.GetDirectoryName(csPath), "ProtocolParser.cs");

            using (TextWriter codeWriter = new StreamWriter(libPath, false, Encoding.UTF8))
            {
                codeWriter.NewLine = "\r\n";
                ReadCode(codeWriter, "MessageTable", true);
                ReadCode(codeWriter, "ProtocolParser", false);
                ReadCode(codeWriter, "ProtocolParserExceptions", false);
                ReadCode(codeWriter, "ProtocolParserFixed", false);
                ReadCode(codeWriter, "ProtocolParserKey", false);
                ReadCode(codeWriter, "ProtocolParserMemory", false);
                ReadCode(codeWriter, "ProtocolParserVarInt", false);
            }
        }
Exemple #25
0
        public static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Error.WriteLine("Usage:\n\tCodeGenerator.exe [--preserve-names] [--use-tabs] path-to.proto [path-to-second.proto [...]] [output.cs]");
                return -1;
            }

            ProtoCollection collection = new ProtoCollection();
            string outputPath = null;

            int argIndex = 0;

            while (args.Length > argIndex && args [argIndex].StartsWith("--"))
            {
                switch (args[argIndex])
                {
                    case "--preserve-names":
                        ProtoPrepare.ConvertToCamelCase = false;
                        break;
                    case ProtoPrepare.FixNameclashArgument:
                        ProtoPrepare.FixNameclash = true;
                        break;
                    case "--use-tabs":
                        CodeWriter.IndentPrefix = "\t";
                        break;
                    default:
                        Console.Error.WriteLine("Unknown option: " + args[argIndex]);
                        return -1;
                }
                argIndex++;
            }

            while (argIndex < args.Length)
            {
                string protoPath = Path.GetFullPath(args[argIndex]);
                string protoBase = Path.Combine(
                    Path.GetDirectoryName(protoPath),
                    Path.GetFileNameWithoutExtension(protoPath));
                argIndex += 1;

                //First .proto filename is used as output unless specified later
                if (outputPath == null)
                    outputPath = protoBase + ".cs";

                //Handle last argument as the output .cs path
                if (argIndex == args.Length && protoPath.EndsWith(".cs"))
                {
                    outputPath = protoPath;
                    break;
                }

                //Handle last argument as the output path
                //Filename is taken from first .proto argument
                if (argIndex == args.Length && protoPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    Directory.CreateDirectory(protoPath);

                    // Replace the original output directory with the custom one
                    outputPath = Path.Combine(protoPath, Path.GetFileName(outputPath));
                    break;
                }

                if (File.Exists(protoPath) == false)
                {
                    Console.Error.WriteLine("File not found: " + protoPath);
                    return -1;
                }

                try
                {
                    var proto = new ProtoCollection();

                    //Parse .proto
                    Console.WriteLine("Parsing " + protoPath);
                    ProtoParser.Parse(protoPath, proto);

                    collection.Merge(proto);
                } catch (ProtoFormatException pfe)
                {
                    Console.WriteLine();
                    Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                    return -1;
                }
            }

            Console.WriteLine(collection);

            //Interpret and reformat
            try
            {
                ProtoPrepare.Prepare(collection);
            } catch (ProtoFormatException pfe)
            {
                Console.WriteLine();
                Console.WriteLine(pfe.SourcePath.Path + "(" + pfe.SourcePath.Line + "," + pfe.SourcePath.Column + "): error CS001: " + pfe.Message);
                return -1;
            }

            //Generate code
            ProtoCode.Save(collection, outputPath);
            Console.WriteLine("Saved: " + outputPath);
            return 0;
        }
        static void ParseImport(TokenReader tr, ProtoCollection collection)
        {
            string path = tr.ReadNext();
            bool publicImport = path == "public";
            if (publicImport)
                path = tr.ReadNext();
            tr.ReadNextOrThrow(";");

            if (publicImport)
                collection.ImportPublic.Add(path);
            else
                collection.Import.Add(path);
        }
Exemple #27
0
        static void ParseMessages(TokenReader tr, ProtoCollection p)
        {
            string package = "Example";

            while (true)
            {
                string token = tr.ReadNext();
                if (ParseComment(token))
                    continue;

                try
                {
                    switch (token)
                    {
                        case ";":
                            lastComment.Clear();
                            continue;
                        case "message":
                            ParseMessage(tr, p, package);
                            break;
                        case "enum":
                            ParseEnum(tr, p, package);
                            break;
                        case "option":
                        //Save options
                            ParseOption(tr, p);
                            break;
                        case "import": //Ignored
                            tr.ReadNext();
                            tr.ReadNextOrThrow(";");
                            break;
                        case "package":
                            package = tr.ReadNext();
                            tr.ReadNextOrThrow(";");
                            break;
                        case "extend":
                            ParseExtend(tr, p, package);
                            break;
                        default:
                            throw new ProtoFormatException("Unexpected/not implemented: " + token, tr);
                    }
                } catch (EndOfStreamException)
                {
                    throw new ProtoFormatException("Unexpected EOF", tr);
                }
            }
        }
Exemple #28
0
        /// <summary>
        /// Generate code for reading and writing protocol buffer messages
        /// </summary>
        public static void Save(ProtoCollection file, Options options)
        {
            string csPath = options.OutputPath;
            CodeWriter.DefaultIndentPrefix = options.UseTabs ? "\t" : "    ";

            string ext = Path.GetExtension(csPath);
            string prefix = csPath.Substring(0, csPath.Length - ext.Length);

            string csDir = Path.GetDirectoryName(csPath);
            if (Directory.Exists(csDir) == false)
                Directory.CreateDirectory(csDir);

            //Basic structures
            using (var cw = new CodeWriter(csPath))
            {
                cw.Comment(@"Classes and structures being serialized");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
            - a pure c# code generation implementation of protocol buffers
            Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
            This file will be overwritten when CodeGenerator is run.
            To make custom modifications, edit the .proto file and add //:external before the message line
            then write the code and the changes in a separate file.");

                cw.WriteLine("using System;");
                cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                            cw.EndBracket();
                        cw.Bracket("namespace " + m.CsNamespace);
                        ns = m.CsNamespace;
                    }
                    MessageCode.GenerateClass(m, cw, options);
                    cw.WriteLine();
                }

                foreach (ProtoEnum e in file.Enums.Values)
                {
                    if (ns != e.CsNamespace)
                    {
                        if (ns != null) //First time
                            cw.EndBracket();
                        cw.Bracket("namespace " + e.CsNamespace);
                        ns = e.CsNamespace;
                    }
                    MessageCode.GenerateEnum(e, cw);
                    cw.WriteLine();
                }

                cw.EndBracket();
            }

            //.Serializer.cs
            //Code for Reading/Writing
            using (var cw = new CodeWriter(prefix + ".Serializer" + ext))
            {
                cw.Comment(@"This is the backend code for reading and writing");
                cw.WriteLine();
                cw.Comment(@"Generated by ProtocolBuffer
            - a pure c# code generation implementation of protocol buffers
            Report bugs to: https://silentorbit.com/protobuf/");
                cw.WriteLine();
                cw.Comment(@"DO NOT EDIT
            This file will be overwritten when CodeGenerator is run.");

                cw.WriteLine("using System;");
                cw.WriteLine("using System.IO;");
                cw.WriteLine("using System.Text;");
                cw.WriteLine("using System.Collections.Generic;");
                cw.WriteLine();

                string ns = null; //avoid writing namespace between classes if they belong to the same
                foreach (ProtoMessage m in file.Messages.Values)
                {
                    if (ns != m.CsNamespace)
                    {
                        if (ns != null) //First time
                            cw.EndBracket();
                        cw.Bracket("namespace " + m.CsNamespace);
                        ns = m.CsNamespace;
                    }
                    MessageSerializer.GenerateClassSerializer(m, cw);
                }
                cw.EndBracket();
            }

            string libPath = Path.Combine(Path.GetDirectoryName(csPath), "ProtocolParser.cs");
            using (TextWriter codeWriter = new StreamWriter(libPath, false, Encoding.UTF8))
            {
                codeWriter.NewLine = "\r\n";
                ReadCode(codeWriter, "ProtocolParser", true);
                ReadCode(codeWriter, "ProtocolParserFixed", false);
                ReadCode(codeWriter, "ProtocolParserKey", false);
                ReadCode(codeWriter, "ProtocolParserVarInt", false);
            }
        }