Exemplo n.º 1
0
        private static Tuple <ProtoEntity, ProtoField> ParseMapField(Lexer lexer, IEnumerable <string> parentNames)
        {
            var entity = new ProtoEntity(ProtoContainer.Message, Guid.NewGuid().ToString("N"));

            Parser.ParseValue(lexer, LexemType.LowerThan, "lower than sign");

            entity.Fields.Add(new ProtoField(1, Parser.ParseType(lexer, parentNames), "key", ProtoOccurrence.Required));

            Parser.ParseValue(lexer, LexemType.Comma, "comma");

            entity.Fields.Add(new ProtoField(2, Parser.ParseType(lexer, parentNames), "value", ProtoOccurrence.Required));

            Parser.ParseValue(lexer, LexemType.GreaterThan, "greater than sign");

            return(Tuple.Create(entity, Parser.ParseField(lexer, new ProtoReference(parentNames.Concat(new [] { entity.Name })), ProtoOccurrence.Required)));
        }
Exemplo n.º 2
0
        private                            ProtoBinding[] ResolveEntity(ProtoEntity entity, IEnumerable <ProtoEntity> parents)
        {
            var bindings = new ProtoBinding[0];

            foreach (var field in entity.Fields)
            {
                if (bindings.Length <= field.Number)
                {
                    Array.Resize(ref bindings, field.Number + 1);
                }

                bindings[field.Number] = this.ResolveField(field, parents);
            }

            return(bindings);
        }
Exemplo n.º 3
0
        private static ProtoEntity ParseEnum(Lexer lexer)
        {
            var entity = new ProtoEntity(ProtoContainer.Enum, Parser.ParseValue(lexer, LexemType.Symbol, "enum name"));

            Parser.ParseValue(lexer, LexemType.BraceBegin, "opening brace");

            while (lexer.Current.Type != LexemType.BraceEnd)
            {
                var label = Parser.ParseValue(lexer, LexemType.Symbol, "enum label");

                if (label == "option")
                {
                    Parser.ParseOption(lexer);
                }
                else
                {
                    Parser.ParseValue(lexer, LexemType.Equal, "equal sign");

                    int value;
                    if (!int.TryParse(Parser.ParseValue(lexer, LexemType.Number, "enum value"), NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                    {
                        throw new ParserException(lexer.Position, "invalid enum value");
                    }

                    if (lexer.Current.Type == LexemType.BracketBegin)
                    {
                        lexer.Next();

                        Parser.ParseOptions(lexer);
                        Parser.ParseValue(lexer, LexemType.BracketEnd, "closing bracket");
                    }

                    entity.Labels.Add(new ProtoLabel(value, label));
                }

                Parser.ParseValue(lexer, LexemType.SemiColon, "semicolon");
            }

            lexer.Next();

            if (entity.Labels.Count < 1 || entity.Labels[0].Value != 0)
            {
                throw new ParserException(lexer.Position, "first enum value must be zero");
            }

            return(entity);
        }
Exemplo n.º 4
0
        public static ProtoEntity Parse(TextReader proto)
        {
            var entity = new ProtoEntity(ProtoContainer.Root, string.Empty);
            var lexer  = new Lexer(proto);

            while (lexer.Current.Type != LexemType.End)
            {
                if (lexer.Current == Lexem.Option)
                {
                    lexer.Next();

                    Parser.ParseOption(lexer);
                    Parser.ParseValue(lexer, LexemType.SemiColon, "semicolon");
                }
                else
                {
                    entity.Entities.Add(Parser.ParseEntity(lexer));
                }
            }

            return(entity);
        }
Exemplo n.º 5
0
        private static ProtoEntity ParseMessage(Lexer lexer, IEnumerable <string> parentNames)
        {
            var name = Parser.ParseValue(lexer, LexemType.Symbol, "message name");

            var currentNames = parentNames.Concat(new [] { name });
            var entity       = new ProtoEntity(ProtoContainer.Message, name);

            Parser.ParseValue(lexer, LexemType.BraceBegin, "opening brace");

            while (lexer.Current.Type != LexemType.BraceEnd)
            {
                if (lexer.Current == Lexem.Enum)
                {
                    lexer.Next();

                    entity.Entities.Add(Parser.ParseEnum(lexer));
                }
                else if (lexer.Current == Lexem.Extend)
                {
                    throw new InvalidOperationException("extensions are not supported yet");
                }
                else if (lexer.Current == Lexem.Extensions)
                {
                    throw new InvalidOperationException("extensions are not supported yet");
                }
                else if (lexer.Current == Lexem.Group)
                {
                    throw new InvalidOperationException("groups are not supported yet");
                }
                else if (lexer.Current == Lexem.Map)
                {
                    lexer.Next();

                    var map = Parser.ParseMapField(lexer, currentNames);

                    entity.Entities.Add(map.Item1);
                    entity.Fields.Add(map.Item2);

                    Parser.ParseValue(lexer, LexemType.SemiColon, "semicolon");
                }
                else if (lexer.Current == Lexem.Message)
                {
                    lexer.Next();

                    entity.Entities.Add(Parser.ParseMessage(lexer, currentNames));
                }
                else if (lexer.Current == Lexem.OneOf)
                {
                    lexer.Next();

                    entity.Entities.Add(Parser.ParseOneOf(lexer, currentNames));
                }
                else if (lexer.Current == Lexem.Option)
                {
                    lexer.Next();

                    Parser.ParseOption(lexer);
                    Parser.ParseValue(lexer, LexemType.SemiColon, "semicolon");
                }
                else if (lexer.Current == Lexem.Reserved)
                {
                    throw new InvalidOperationException("reserved fields are not supported yet");
                }
                else
                {
                    ProtoOccurrence occurrence;

                    if (lexer.Current == Lexem.Optional)
                    {
                        lexer.Next();

                        occurrence = ProtoOccurrence.Optional;
                    }
                    else if (lexer.Current == Lexem.Repeated)
                    {
                        lexer.Next();

                        occurrence = ProtoOccurrence.Repeated;
                    }
                    else if (lexer.Current == Lexem.Required)
                    {
                        lexer.Next();

                        occurrence = ProtoOccurrence.Required;
                    }
                    else
                    {
                        occurrence = ProtoOccurrence.Optional;
                    }

                    entity.Fields.Add(Parser.ParseField(lexer, Parser.ParseType(lexer, parentNames), occurrence));

                    Parser.ParseValue(lexer, LexemType.SemiColon, "semicolon");
                }
            }

            lexer.Next();

            return(entity);
        }