static bool ParseField(TokenReader tr, Message m)
{
string rule = tr.ReadNext ();
while (true) {
if (ParseComment (rule) == false)
break;
rule = tr.ReadNext ();
}
if (rule == "}")
return false;
if (rule == "enum") {
MessageEnum me = ParseEnum (tr, m);
m.Enums.Add (me);
return true;
}
Field f = new Field ();
f.Comments = lastComment;
lastComment = null;
//Rule
switch (rule) {
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":
m.Messages.Add (ParseMessage (tr, m));
return true;
default:
throw new ProtoFormatException ("unknown rule: " + rule);
}
//Type
f.ProtoTypeName = tr.ReadNext ();
//Name
f.Name = tr.ReadNext ();
//ID
tr.ReadNextOrThrow ("=");
f.ID = int.Parse (tr.ReadNext ());
if (19000 <= f.ID && f.ID <= 19999)
throw new ProtoFormatException ("Can't use reserved field ID 19000-19999");
if (f.ID > (1 << 29) - 1)
throw new ProtoFormatException ("Maximum field id is 2^29 - 1");
//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);
while (true) {
string key = tr.ReadNext ();
tr.ReadNextOrThrow ("=");
string val = tr.ReadNext ();
ParseFieldOption (key, val, f);
string optionSep = tr.ReadNext ();
if (optionSep == "]")
break;
if (optionSep == ",")
continue;
throw new ProtoFormatException (@"Expected "","" or ""]"" got " + tr.Next);
}
tr.ReadNextOrThrow (";");
return true;
}