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.ReadNextComment(); if (ParseComment(name)) continue; if (name == "}") return; //Ignore options if (name == "option") { ParseOption(tr, null); lastComment.Clear(); continue; } ParseEnumValue(tr, me, name); } }
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); } } }
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.ReadNextComment(); if (ParseComment(name)) { continue; } if (name == "}") { return; } //Ignore options if (name == "option") { ParseOption(tr, null); lastComment.Clear(); continue; } ParseEnumValue(tr, me, name); } }
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); } } }
static bool ParseField(TokenReader tr, ProtoMessage m) { string rule = tr.ReadNextComment(); while (ParseComment(rule)) { rule = tr.ReadNextComment(); } Field f = new Field(tr); //Rule switch (rule) { case ";": lastComment.Clear(); return(true); case "}": lastComment.Clear(); return(false); case "required": f.Rule = FieldRule.Required; break; case "optional": f.Rule = FieldRule.Optional; break; case "repeated": f.Rule = FieldRule.Repeated; break; case "option": //Save options ParseOption(tr, m); return(true); case "message": ParseMessage(tr, m, m.Package + "." + m.ProtoName); return(true); case "enum": ParseEnum(tr, m, m.Package + "." + m.ProtoName); return(true); case "extensions": ParseExtensions(tr); return(true); default: throw new ProtoFormatException("unknown rule: " + rule, tr); } //Field comments LocalParser.ParseComments(f, lastComment, tr); //Type f.ProtoTypeName = tr.ReadNext(); //Name f.ProtoName = tr.ReadNext(); //ID tr.ReadNextOrThrow("="); f.ID = ParseInt(tr); if (19000 <= f.ID && f.ID <= 19999) { throw new ProtoFormatException("Can't use reserved field ID 19000-19999", tr); } if (f.ID > (1 << 29) - 1) { throw new ProtoFormatException("Maximum field id is 2^29 - 1", tr); } //Add Field to message m.Fields.Add(f.ID, f); //Determine if extra options string extra = tr.ReadNext(); if (extra == ";") { return(true); } //Field options if (extra != "[") { throw new ProtoFormatException("Expected: [ got " + extra, tr); } ParseFieldOptions(tr, f); return(true); }
static bool ParseField(TokenReader tr, ProtoMessage m) { string rule = tr.ReadNextComment(); while (true) { if (ParseComment(rule) == false) break; rule = tr.ReadNextComment(); } Field f = new Field(tr); //Rule switch (rule) { case ";": lastComment.Clear(); return true; case "}": lastComment.Clear(); return false; case "required": f.Rule = FieldRule.Required; break; case "optional": f.Rule = FieldRule.Optional; break; case "repeated": f.Rule = FieldRule.Repeated; break; case "option": //Save options ParseOption(tr, m); return true; case "message": ParseMessage(tr, m, m.Package + "." + m.ProtoName); return true; case "enum": ParseEnum(tr, m, m.Package + "." + m.ProtoName); return true; case "extensions": ParseExtensions(tr, m); return true; default: throw new ProtoFormatException("unknown rule: " + rule, tr); } //Field comments LocalParser.ParseComments(f, lastComment, tr); //Type f.ProtoTypeName = tr.ReadNext(); //Name f.ProtoName = tr.ReadNext(); //ID tr.ReadNextOrThrow("="); f.ID = ParseInt(tr); if (19000 <= f.ID && f.ID <= 19999) throw new ProtoFormatException("Can't use reserved field ID 19000-19999", tr); if (f.ID > (1 << 29) - 1) throw new ProtoFormatException("Maximum field id is 2^29 - 1", tr); //Add Field to message m.Fields.Add(f.ID, f); //Determine if extra options string extra = tr.ReadNext(); if (extra == ";") return true; //Field options if (extra != "[") throw new ProtoFormatException("Expected: [ got " + extra, tr); ParseFieldOptions(tr, f); return true; }