private bool AddEnumMapDef( ProtocolDescriptor.ProtocolDef protoDef, XElement element) { // check name attr string name; { XAttribute attr = element.Attribute("name"); if (attr == null) { PrintLineError(protoDef, element, "`enum_map` node must contain a `name` attribute"); return(false); } name = attr.Value; } if (Regex.IsMatch(name, @"^[a-zA-Z_]\w*$") == false) { PrintLineError(protoDef, element, "`enum_map` node `name` attribute is invalid"); return(false); } if (protoDef.EnumMapNameIndex.ContainsKey(name) || protoDef.EnumNameIndex.ContainsKey(name) || protoDef.StructNameIndex.ContainsKey(name)) { PrintLineError(protoDef, element, "`enum_map` node `name` attribute duplicated"); return(false); } ProtocolDescriptor.EnumMapDef def = new ProtocolDescriptor.EnumMapDef(); def.ParentRef = protoDef; def.Name = name; def.LineNumber = GetLineNumber(element); // parse items { IEnumerator <XElement> iter = element.Elements().GetEnumerator(); while (iter.MoveNext()) { XElement childElement = iter.Current; if (childElement.Name != "item") { PrintLineError(protoDef, childElement, "expect a `item` node"); return(false); } if (AddEnumMapItemDef(protoDef, def, childElement) == false) { return(false); } } } protoDef.EnumMaps.Add(def); protoDef.EnumMapNameIndex.Add(def.Name, def); return(true); }
private bool AddEnumMapItemDef( ProtocolDescriptor.ProtocolDef protoDef, ProtocolDescriptor.EnumMapDef enumMapDef, XElement element) { // check name attr string name; { XAttribute attr = element.Attribute("name"); if (attr == null) { PrintLineError(protoDef, element, "`item` node must contain a `name` attribute"); return(false); } name = attr.Value; } if (Regex.IsMatch(name, @"^[a-zA-Z_]\w*$") == false) { PrintLineError(protoDef, element, "`item` node `name` attribute is invalid"); return(false); } if (enumMapDef.ItemNameIndex.ContainsKey(name)) { PrintLineError(protoDef, element, "`item` node `name` attribute duplicated"); return(false); } // check value attr string val = ""; { XAttribute attr = element.Attribute("value"); if (attr != null) { val = attr.Value; } } // check struct attr string structVal = ""; { XAttribute attr = element.Attribute("struct"); if (attr != null) { structVal = attr.Value; } } ProtocolDescriptor.EnumMapDef.ItemDef def = new ProtocolDescriptor.EnumMapDef.ItemDef(); def.ParentRef = enumMapDef; def.Name = name; def.LineNumber = GetLineNumber(element); if (val == "") { // default def.Type = ProtocolDescriptor.EnumMapDef.ItemType.Default; if (enumMapDef.Items.Count == 0) { def.IntValue = 0; } else { def.IntValue = enumMapDef.Items[ enumMapDef.Items.Count - 1].IntValue + 1; } } else if (Regex.IsMatch(val, @"^[0-9]+$")) { // int def.Type = ProtocolDescriptor.EnumMapDef.ItemType.Int; def.IntValue = int.TryParse(val, out def.IntValue) ? def.IntValue : 0; } else { // current enum ProtocolDescriptor.EnumMapDef.ItemDef refDef = null; if (enumMapDef.ItemNameIndex.TryGetValue( val, out refDef) == false) { PrintLineError(protoDef, element, "enum_map item `{0}` is undefined", val); return(false); } def.Type = ProtocolDescriptor.EnumMapDef.ItemType.CurrentEnumRef; def.IntValue = refDef.IntValue; def.RefEnumItemDef = refDef; } if (enumMapDef.Items.Count > 0 && def.IntValue < enumMapDef.Items[ enumMapDef.Items.Count - 1].IntValue) { PrintLineError(protoDef, element, "`item` node `value` attribute can not be " + "less than previous one"); return(false); } if (structVal != "") { ProtocolDescriptor.ProtocolDef refProtoDef = null; string refDefName = ""; string[] parts = structVal.Split('.'); if (parts.Length == 1) { // in same file refProtoDef = protoDef; refDefName = parts[0]; } else if (parts.Length == 2) { // in other file string refProtoDefName = parts[0]; if (this.descriptor.ImportedProtos.TryGetValue( refProtoDefName, out refProtoDef) == false) { PrintLineError(protoDef, element, "protocol `{0}` is undefined", refProtoDefName); return(false); } refDefName = parts[1]; } else { PrintLineError(protoDef, element, "struct `{0}` is invalid", structVal); return(false); } ProtocolDescriptor.StructDef refStructDef = null; if (refProtoDef.StructNameIndex.TryGetValue( refDefName, out refStructDef) == false) { PrintLineError(protoDef, element, "struct `{0}` is undefined", refDefName); return(false); } def.RefStructDef = refStructDef; if (enumMapDef.IdToStructIndex.ContainsKey(def.IntValue)) { PrintLineError(protoDef, element, "id `{0}` is already mapped to a struct", def.IntValue); return(false); } if (enumMapDef.StructToIdIndex.ContainsKey(def.RefStructDef)) { PrintLineError(protoDef, element, "struct `{0}` is already mapped to a id", def.RefStructDef.Name); return(false); } enumMapDef.IdToStructIndex.Add(def.IntValue, def.RefStructDef); enumMapDef.StructToIdIndex.Add(def.RefStructDef, def.IntValue); } enumMapDef.Items.Add(def); enumMapDef.ItemNameIndex.Add(def.Name, def); return(true); }
private void ProcessImportedProtocols( ProtocolDescriptor.ProtocolDef protoDef) { Dictionary <string, ProtocolDescriptor.ProtocolDef> usedProtos = new Dictionary <string, ProtocolDescriptor.ProtocolDef>(); Dictionary <string, ProtocolDescriptor.ProtocolDef> enumRefProtos = new Dictionary <string, ProtocolDescriptor.ProtocolDef>(); Dictionary <string, ProtocolDescriptor.ProtocolDef> structRefProtos = new Dictionary <string, ProtocolDescriptor.ProtocolDef>(); Dictionary <string, ProtocolDescriptor.ProtocolDef> enumMapRefProtos = new Dictionary <string, ProtocolDescriptor.ProtocolDef>(); // collect enum ref protocols for (int i = 0; i < protoDef.Enums.Count; ++i) { ProtocolDescriptor.EnumDef enumDef = protoDef.Enums[i]; for (int j = 0; j < enumDef.Items.Count; ++j) { ProtocolDescriptor.EnumDef.ItemDef def = enumDef.Items[j]; if (def.RefEnumItemDef != null) { ProtocolDescriptor.ProtocolDef refProtoDef = def.RefEnumItemDef.ParentRef.ParentRef; usedProtos[refProtoDef.Name] = refProtoDef; enumRefProtos[refProtoDef.Name] = refProtoDef; } } } // collect struct ref protocols for (int i = 0; i < protoDef.Structs.Count; ++i) { ProtocolDescriptor.StructDef structDef = protoDef.Structs[i]; for (int j = 0; j < structDef.Fields.Count; ++j) { ProtocolDescriptor.StructDef.FieldDef def = structDef.Fields[j]; if (def.RefEnumDef != null) { ProtocolDescriptor.ProtocolDef refProtoDef = def.RefEnumDef.ParentRef; usedProtos[refProtoDef.Name] = refProtoDef; structRefProtos[refProtoDef.Name] = refProtoDef; } if (def.RefStructDef != null) { ProtocolDescriptor.ProtocolDef refProtoDef = def.RefStructDef.ParentRef; usedProtos[refProtoDef.Name] = refProtoDef; structRefProtos[refProtoDef.Name] = refProtoDef; } } } // collect enum map ref protocols for (int i = 0; i < protoDef.EnumMaps.Count; ++i) { ProtocolDescriptor.EnumMapDef enumMapDef = protoDef.EnumMaps[i]; for (int j = 0; j < enumMapDef.Items.Count; ++j) { ProtocolDescriptor.EnumMapDef.ItemDef def = enumMapDef.Items[j]; if (def.RefEnumItemDef != null) { ProtocolDescriptor.ProtocolDef refProtoDef = def.RefEnumItemDef.ParentRef.ParentRef; usedProtos[refProtoDef.Name] = refProtoDef; enumMapRefProtos[refProtoDef.Name] = refProtoDef; } if (def.RefStructDef != null) { ProtocolDescriptor.ProtocolDef refProtoDef = def.RefStructDef.ParentRef; usedProtos[refProtoDef.Name] = refProtoDef; enumMapRefProtos[refProtoDef.Name] = refProtoDef; } } } for (int i = 0; i < protoDef.Imports.Count; ++i) { ProtocolDescriptor.ImportDef importDef = protoDef.Imports[i]; // check imported protocol is used if (usedProtos.ContainsKey(importDef.ProtoDef.Name) == false) { Console.Error.WriteLine(string.Format( "warning:{0}:{1}: protocol `{2}` " + "is not used but imported", protoDef.FilePath, importDef.LineNumber, importDef.Name)); } if (enumRefProtos.ContainsKey(importDef.ProtoDef.Name)) { importDef.IsRefByEnum = true; } if (structRefProtos.ContainsKey(importDef.ProtoDef.Name)) { importDef.IsRefByStruct = true; } if (enumMapRefProtos.ContainsKey(importDef.ProtoDef.Name)) { importDef.IsRefByEnumMap = true; } } }