private StatEntity InstantiateEntityInternal(StatSubtypeDefinition subtype, string declarationName, CodeLocation location, Dictionary <string, object> properties, Dictionary <string, CodeLocation> propertyLocations) { var entity = new StatEntity { Name = declarationName, Type = subtype, BaseClass = null, // FIXME Location = location, Properties = new Dictionary <string, object>(), PropertyLocations = propertyLocations }; foreach (var property in properties) { if (property.Key == "EntityType") { continue; } propertyLocations.TryGetValue(property.Key, out CodeLocation propLocation); var parsed = ParseProperty(subtype, property.Key, property.Value, propLocation, declarationName); if (parsed != null) { entity.Properties.Add(property.Key, parsed); } } return(entity); }
private void AddSubtype(StatTypeDefinition definition, string subtypeName, IEnumerable <XElement> fields) { var subtype = new StatSubtypeDefinition(definition, subtypeName); foreach (var field in fields) { AddField(definition, subtype, field); } definition.Subtypes.Add(subtypeName, subtype); }
private object ParseProperty(StatSubtypeDefinition subtype, string propertyName, object value, CodeLocation location, string declarationName) { if (!subtype.Fields.TryGetValue(propertyName, out StatField field)) { Context.LogError(DiagnosticCode.StatPropertyUnsupported, $"Property '{propertyName}' is not supported on {subtype.Name} '{declarationName}'", location?.FileName, location?.StartLine ?? 0, declarationName); return(null); } bool succeeded = false; string errorText = null; object parsed; if (field.Type != "Passthrough") { var parser = field.GetParser(ParserFactory, Context.Definitions); parsed = parser.Parse((string)value, ref succeeded, ref errorText); } else { parsed = value; succeeded = true; } if (errorText != null) { Context.LogError(DiagnosticCode.StatPropertyValueInvalid, $"{subtype.Name} '{declarationName}' has invalid {propertyName}: '{value}' ({errorText})", location?.FileName, location?.StartLine ?? 0, declarationName); } if (succeeded) { return(parsed); } else { return(null); } }
private void AddField(StatTypeDefinition definition, StatSubtypeDefinition subtype, XElement field) { if (field.Attribute("export_name").Value == "") { return; } var fieldName = field.Attribute("export_name").Value; var typeName = field.Attribute("type").Value; StatEnumeration enumeration = null; List <StatReferenceConstraint> referenceConstraints = null; switch (typeName) { case "Enumeration": case "EnumerationList": var enumName = field.Attribute("enumeration_type_name").Value; enumeration = Enumerations[enumName]; break; case "Name": if (definition.NameProperty == null) { definition.NameProperty = fieldName; } else if (definition.NameProperty != fieldName) { throw new Exception($"Conflicting Name property for type '{definition.Name}': First seen using '{definition.NameProperty}', now seen using '{fieldName}'."); } break; case "BaseClass": if (definition.BaseClassProperty == null) { definition.BaseClassProperty = fieldName; } else if (definition.BaseClassProperty != fieldName) { throw new Exception($"Conflicting BaseClass for type '{definition.Name}': First seen using '{definition.BaseClassProperty}', now seen using '{fieldName}'."); } break; case "StatReference": case "StatReferences": referenceConstraints = new List <StatReferenceConstraint>(); var descriptions = field.Element("stat_descriptions"); if (descriptions == null) { throw new Exception("Field of type 'StatReference' must have a list of stat types in the <stat_descriptions> node"); } var descs = descriptions.Elements("description"); foreach (var desc in descs) { var constraint = new StatReferenceConstraint { StatType = desc.Attribute("stat_type").Value, StatSubtype = desc.Attribute("stat_subtype")?.Value ?? null }; referenceConstraints.Add(constraint); } break; case "Boolean": case "Integer": case "Float": case "String": case "TranslatedString": case "RootTemplate": case "Comment": case "Color": case "Requirements": case "Properties": case "Conditions": case "Passthrough": case "UUID": break; default: throw new Exception($"Unsupported stat field type: '{typeName}'"); } var statField = new StatField { Name = fieldName, Type = typeName, EnumType = enumeration, ReferenceTypes = referenceConstraints }; subtype.Fields.Add(fieldName, statField); if (typeName == "TranslatedString") { var translatedKeyRefField = new StatField { Name = fieldName + "Ref", Type = typeName, EnumType = enumeration }; subtype.Fields.Add(fieldName + "Ref", translatedKeyRefField); } }
private StatEntity InstantiateEntity(StatSubtypeDefinition subtype, string declarationName, StatDeclaration declaration) { return(InstantiateEntityInternal(subtype, declarationName, declaration.Location, declaration.Properties, declaration.PropertyLocations)); }