/// <summary> /// Parses the node represented by the next event in <paramref name="events" />. /// </summary> /// <param name="events">The events.</param> /// <param name="state">The state.</param> /// <returns>Returns the node that has been parsed.</returns> static internal YamlNode ParseNode(EventReader events, DocumentLoadingState state) { if (events.Accept<Scalar>()) { return new YamlScalarNode(events, state); } if (events.Accept<SequenceStart>()) { return new YamlSequenceNode(events, state); } if (events.Accept<MappingStart>()) { return new YamlMappingNode(events, state); } if (events.Accept<AnchorAlias>()) { AnchorAlias alias = events.Expect<AnchorAlias>(); return state.GetNode(alias.Value, false, alias.Start, alias.End) ?? new YamlAliasNode(alias.Value); } throw new ArgumentException("The current event is of an unsupported type.", "events"); }
/// <summary> /// Initializes a new instance of the <see cref="YamlDocument"/> class. /// </summary> /// <param name="events">The events.</param> internal YamlDocument(EventReader events) { DocumentLoadingState state = new DocumentLoadingState(); events.Expect<DocumentStart>(); while (!events.Accept<DocumentEnd>()) { Debug.Assert(RootNode == null); RootNode = YamlNode.ParseNode(events, state); if (RootNode is YamlAliasNode) { throw new YamlException(); } } state.ResolveAliases(); #if DEBUG foreach (var node in AllNodes) { if (node is YamlAliasNode) { throw new InvalidOperationException("Error in alias resolution."); } } #endif events.Expect<DocumentEnd>(); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value) { if (!typeof(IList).IsAssignableFrom(expectedType)) { value = false; return false; } reader.Expect<SequenceStart>(); var list = (IList)_objectFactory.Create(expectedType); while (!reader.Accept<SequenceEnd>()) { var item = nestedObjectDeserializer(reader, typeof(object)); var promise = item as IValuePromise; if (promise == null) { list.Add(item); } else { var index = list.Count; list.Add(null); promise.ValueAvailable += v => list[index] = v; } } value = list; reader.Expect<SequenceEnd>(); return true; }
// Use this for initialization void Start () { var input = new StringReader(Document); var deserializer = new Deserializer(); var reader = new EventReader(new Parser(input)); // Consume the stream start event "manually" reader.Expect<StreamStart>(); var output = new StringBuilder(); while(reader.Accept<DocumentStart>()) { // Deserialize the document var doc = deserializer.Deserialize<List<string>>(reader); output.AppendLine("## Document"); foreach(var item in doc) { output.AppendLine(item); } } Debug.Log(output); }
private static object GetData(EventReader r) { if(r.Accept<Scalar>()) { return r.Expect<Scalar>().Value; } else if(r.Accept<SequenceStart>()) { var seq = new ArrayList(); r.Expect<SequenceStart>(); while(!r.Accept<SequenceEnd>()) { seq.Add(GetData(r)); } r.Expect<SequenceEnd>(); // Arrays are IStructuralEquatable, ArrayLists are not. return seq.ToArray(); } else if(r.Accept<MappingStart>()) { // Since we use sequences as keys... var map = new OrderedDictionary(StructuralComparisons.StructuralEqualityComparer); r.Expect<MappingStart>(); while(!r.Accept<MappingEnd>()) { object key = GetData(r); object value = GetData(r); map.Add(key, value); } r.Expect<MappingEnd>(); return map; } else { throw new YamlException(); } }
public static void ReadConfigYAML() { var input = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + @"/AME.yaml"); var deserializer = new Deserializer(); var reader = new EventReader(new Parser(input)); // Deserialize the document reader.Expect<StreamStart>(); reader.Accept<DocumentStart>(); var settings = deserializer.Deserialize<AMESettings>(reader); reader.Accept<DocumentStart>(); var behaviorManifests = deserializer.Deserialize<BehaviorManifests>(reader); foreach (var behavior in behaviorManifests.FRLGBehaviors) { if(behavior.Value[0] == '&') behaviorManifests.FRLGBehaviors[behavior.Key] = InternalStrings.ResourceManager.GetString(behavior.Value); Console.WriteLine("[{0}] {1}", behavior.Key.ToString("X"), behavior.Value); } }
public YamlOctopusModel[] Read(Stream stream) { var models = new List <YamlOctopusModel>(); using (var reader = new StreamReader(stream)) { var eventReader = new EventReader(new Parser(reader)); eventReader.Expect <StreamStart>(); while (eventReader.Accept <DocumentStart>()) { models.Add(_deserializer.Deserialize <YamlOctopusModel>(eventReader)); } return(models.ToArray()); } }
private object DeserializeList(EventReader reader, Type type, DeserializationContext context) { SequenceStart sequence = reader.Expect <SequenceStart>(); type = GetType(sequence.Tag, type, context.Options.Mappings); // Choose a default list type in case there was no specific type specified. if (type == typeof(object)) { type = typeof(ArrayList); } object result = Activator.CreateInstance(type); Type iCollection = GetImplementedGenericInterface(type, typeof(ICollection <>)); if (iCollection != null) { Type[] iCollectionArguments = iCollection.GetGenericArguments(); Debug.Assert(iCollectionArguments.Length == 1, "ICollection<> must have one generic argument."); MethodInfo addAdapter = addAdapterGeneric.MakeGenericMethod(iCollectionArguments); Action <object, object> addAdapterDelegate = (Action <object, object>)Delegate.CreateDelegate(typeof(Action <object, object>), addAdapter); DeserializeGenericListInternal(reader, iCollectionArguments[0], result, addAdapterDelegate, context); } else { IList list = result as IList; if (list != null) { while (!reader.Accept <SequenceEnd>()) { list.Add(DeserializeValue(reader, typeof(object), context)); } } reader.Expect <SequenceEnd>(); } AddAnchoredObject(sequence, result, context.Anchors); return(result); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { var mapping = reader.Allow <MappingStart>(); if (mapping == null) { value = null; return(false); } value = _objectFactory.Create(expectedType); while (!reader.Accept <MappingEnd>()) { var propertyName = reader.Expect <Scalar>(); var property = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched); if (property == null) { reader.SkipThisAndNestedEvents(); continue; } var propertyValue = nestedObjectDeserializer(reader, property.Type); var propertyValuePromise = propertyValue as IValuePromise; if (propertyValuePromise == null) { var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type); property.Write(value, convertedValue); } else { var valueRef = value; propertyValuePromise.ValueAvailable += v => { var convertedValue = TypeConverter.ChangeType(v, property.Type); property.Write(valueRef, convertedValue); }; } } reader.Expect <MappingEnd>(); return(true); }
private object DeserializeValue(EventReader reader, Type expectedType, DeserializationContext context) { if (reader.Accept <AnchorAlias>()) { return(context.Anchors[reader.Expect <AnchorAlias>().Value]); } NodeEvent nodeEvent = (NodeEvent)reader.Parser.Current; if (nodeEvent.Tag == "tag:yaml.org,2002:null") { reader.Expect <NodeEvent>(); AddAnchoredObject(nodeEvent, null, context.Anchors); return(null); } object result = DeserializeValueNotNull(reader, context, nodeEvent, expectedType); return(ObjectConverter.Convert(result, expectedType)); }
internal YamlSequenceNode(EventReader events, DocumentLoadingState state) { this.children = new List <YamlNode>(); SequenceStart yamlEvent = events.Expect <SequenceStart>(); base.Load(yamlEvent, state); bool flag = false; while (!events.Accept <SequenceEnd>()) { YamlNode item = ParseNode(events, state); this.children.Add(item); flag |= item is YamlAliasNode; } if (flag) { state.AddNodeWithUnresolvedAliases(this); } events.Expect <SequenceEnd>(); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value) { var mapping = reader.Allow<MappingStart>(); if (mapping == null) { value = null; return false; } value = _objectFactory.Create(expectedType); while (!reader.Accept<MappingEnd>()) { var propertyName = reader.Expect<Scalar>(); var property = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched); if (property == null) { reader.SkipThisAndNestedEvents(); continue; } var propertyValue = nestedObjectDeserializer(reader, property.Type); var propertyValuePromise = propertyValue as IValuePromise; if (propertyValuePromise == null) { var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type); property.Write(value, convertedValue); } else { var valueRef = value; propertyValuePromise.ValueAvailable += v => { var convertedValue = TypeConverter.ChangeType(v, property.Type); property.Write(valueRef, convertedValue); }; } } reader.Expect<MappingEnd>(); return true; }
private object DeserializeValue(EventReader reader, Type expectedType, object context) { if (reader.Accept <AnchorAlias>()) { throw new NotImplementedException(); //return context.Anchors[reader.Expect<AnchorAlias>().Value]; } var nodeEvent = (NodeEvent)reader.Parser.Current; if (IsNull(nodeEvent)) { reader.Expect <NodeEvent>(); AddAnchoredObject(nodeEvent, null, context.Anchors); return(null); } object result = DeserializeValueNotNull(reader, context, nodeEvent, expectedType); return(ObjectConverter.Convert(result, expectedType)); }
/// <summary> /// Name and Title are mandatory while shortcut is optional /// </summary> /// <param name="metaModel"></param> /// <param name="r"></param> private void DeserializeIcon(MetaModel.MetaModel metaModel, EventReader r) { string name = null, title = null, shortcut = null; r.Expect <MappingStart>(); r.Expect <Scalar>(); //name name = r.Expect <Scalar>().Value; r.Expect <Scalar>(); title = r.Expect <Scalar>().Value; if (r.Accept <Scalar>()) { if (r.Expect <Scalar>().Value.Equals(Shortcut)) { shortcut = r.Expect <Scalar>().Value; } } r.Expect <MappingEnd>(); metaModel.IconsList.Add(new ModelIcon(name, title, shortcut)); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { if (!typeof(IList).IsAssignableFrom(expectedType)) { value = false; return(false); } reader.Expect <SequenceStart>(); var list = (IList)_objectFactory.Create(expectedType); while (!reader.Accept <SequenceEnd>()) { var item = nestedObjectDeserializer(reader, typeof(object)); list.Add(item); } value = list; reader.Expect <SequenceEnd>(); return(true); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { if (!typeof(IDictionary).IsAssignableFrom(expectedType)) { value = false; return(false); } reader.Expect <MappingStart>(); var dictionary = (IDictionary)_objectFactory.Create(expectedType); while (!reader.Accept <MappingEnd>()) { var key = nestedObjectDeserializer(reader, typeof(object)); var keyValue = nestedObjectDeserializer(reader, typeof(object)); dictionary.Add(key, keyValue); } value = dictionary; reader.Expect <MappingEnd>(); return(true); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { var mapping = reader.Allow <MappingStart>(); if (mapping == null) { value = null; return(false); } value = _objectFactory.Create(expectedType); while (!reader.Accept <MappingEnd>()) { var propertyName = reader.Expect <Scalar>(); var property = _typeDescriptor.GetProperty(expectedType, propertyName.Value).Property; var propertyValue = nestedObjectDeserializer(reader, property.PropertyType); var convertedValue = TypeConverter.ChangeType(propertyValue, property.PropertyType); property.SetValue(value, convertedValue, null); } reader.Expect <MappingEnd>(); return(true); }
private static object FromYaml(string yamlText, bool expectOnlyFrontMatter, out TextPosition position) { position = new TextPosition(); if (yamlText == null) { return(null); } var parser = new Parser(new StringReader(yamlText)); var reader = new EventReader(parser); if (!reader.Accept <StreamStart>()) { return(null); } reader.Expect <StreamStart>(); var docStart = reader.Expect <DocumentStart>(); var hasDocumentStart = true; object result = null; ScriptArray objects = null; // If we expect to read multiple documents, we will return an array of result if (expectOnlyFrontMatter && docStart.IsImplicit) { return(null); } Mark endPosition; while (true) { if (reader.Accept <StreamEnd>()) { var evt = reader.Expect <StreamEnd>(); endPosition = evt.End; break; } if (hasDocumentStart && reader.Accept <DocumentEnd>()) { reader.Expect <DocumentEnd>(); hasDocumentStart = false; if (expectOnlyFrontMatter) { reader.Accept <DocumentStart>(); var nextDocStart = reader.Expect <DocumentStart>(); endPosition = nextDocStart.End; break; } continue; } if (reader.Accept <DocumentStart>()) { reader.Expect <DocumentStart>(); hasDocumentStart = true; } var obj = ReadEvent(reader); if (result == null) { result = obj; } else { if (objects == null) { objects = new ScriptArray { result }; result = objects; } objects.Add(obj); } } position = new TextPosition(endPosition.Index, endPosition.Line, endPosition.Column); return(result); }
//private static MethodInfo _deserializeHelperMethod = typeof(GenericDictionaryNodeDeserializer) // .GetMethod("DeserializeHelper", BindingFlags.Static | BindingFlags.NonPublic); private static void DeserializeHelper <TKey, TValue>(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, IDictionary <TKey, TValue> result) { while (!reader.Accept <MappingEnd>()) { var key = nestedObjectDeserializer(reader, typeof(TKey)); var keyPromise = key as IValuePromise; var value = nestedObjectDeserializer(reader, typeof(TValue)); var valuePromise = value as IValuePromise; if (keyPromise == null) { if (valuePromise == null) { // Happy path: both key and value are known result[(TKey)key] = (TValue)value; } else { // Key is known, value is pending valuePromise.ValueAvailable += v => result[(TKey)key] = (TValue)v; } } else { if (valuePromise == null) { // Key is pending, value is known keyPromise.ValueAvailable += v => result[(TKey)v] = (TValue)value; } else { // Both key and value are pending. We need to wait until both of them becom available. var hasFirstPart = false; keyPromise.ValueAvailable += v => { if (hasFirstPart) { result[(TKey)v] = (TValue)value; } else { key = v; hasFirstPart = true; } }; valuePromise.ValueAvailable += v => { if (hasFirstPart) { result[(TKey)key] = (TValue)v; } else { value = v; hasFirstPart = true; } }; } } } }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) return false; assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetFileSerializer.FindSerializer(assetFileExtension); if (!(serializer is YamlAssetSerializer)) return false; // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = PackageVersion.Zero; PackageVersion expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect<StreamStart>(); yamlEventReader.Expect<DocumentStart>(); var mappingStart = yamlEventReader.Expect<MappingStart>(); var tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType); expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero; Scalar assetKey; while ((assetKey = yamlEventReader.Allow<Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == nameof(Asset.Id)) { yamlEventReader.Skip(); } else if (assetKey.Value == nameof(Asset.SerializedVersion)) { // Check for old format: only a scalar var scalarVersion = yamlEventReader.Allow<Scalar>(); if (scalarVersion != null) { serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture)); // Let's update to new format using (var yamlAsset = loadAsset.AsYamlAsset()) { yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion); var baseBranch = yamlAsset.DynamicRootNode["~Base"]; if (baseBranch != null) { var baseAsset = baseBranch["Asset"]; if (baseAsset != null) { baseAsset.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion); } } } } else { // New format: package => version mapping yamlEventReader.Expect<MappingStart>(); while (!yamlEventReader.Accept<MappingEnd>()) { var packageName = yamlEventReader.Expect<Scalar>().Value; var packageVersion = PackageVersion.Parse(yamlEventReader.Expect<Scalar>().Value); // For now, we handle only one dependency at a time if (packageName == dependencyName) { serializedVersion = packageVersion; } } yamlEventReader.Expect<MappingEnd>(); } break; } else { // If anything else than Id or SerializedVersion, let's stop break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Xenko) throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Xenko?"); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); using (var yamlAsset = loadAsset.AsYamlAsset()) { var yamlRootNode = yamlAsset.RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName); if (assetUpgraders == null) { throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found"); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { PackageVersion targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); // Stop if the next version would be higher than what is expected if (untilVersion != null && targetVersion > untilVersion) break; upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; PackageVersion newSerializedVersion = null; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode)) { var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)]; newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value); } if (untilVersion == null && newSerializedVersion != expectedVersion) { throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}."); } context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); } return true; } return false; }
private object DeserializeProperties(EventReader reader, Type type, DeserializationContext context) { MappingStart mapping = reader.Expect <MappingStart>(); type = GetType(mapping.Tag, type, context.Options.Mappings); object result = Activator.CreateInstance(type); IDictionary dictionary = result as IDictionary; if (dictionary != null) { Type keyType = typeof(object); Type valueType = typeof(object); foreach (var interfaceType in result.GetType().GetInterfaces()) { if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { Type[] genericArguments = interfaceType.GetGenericArguments(); Debug.Assert(genericArguments.Length == 2, "IDictionary<,> must contain two generic arguments."); keyType = genericArguments[0]; valueType = genericArguments[1]; break; } } while (!reader.Accept <MappingEnd>()) { object key = DeserializeValue(reader, keyType, context); object value = DeserializeValue(reader, valueType, context); dictionary.Add(key, value); } } else { while (!reader.Accept <MappingEnd>()) { Scalar key = reader.Expect <Scalar>(); bool isOverriden = false; if (context.Options != null) { var deserializer = context.Options.Overrides.GetOverride(type, key.Value); if (deserializer != null) { isOverriden = true; deserializer(result, reader); } } if (!isOverriden) { PropertyInfo property = type.GetProperty(key.Value, BindingFlags.Instance | BindingFlags.Public); if (property == null) { Console.WriteLine(key); throw new SerializationException( string.Format( CultureInfo.InvariantCulture, "Property '{0}' not found on type '{1}'", key.Value, type.FullName ) ); } property.SetValue(result, DeserializeValue(reader, property.PropertyType, context), null); } } } reader.Expect <MappingEnd>(); AddAnchoredObject(mapping, result, context.Anchors); return(result); }
internal static void DeserializeHelper(Type tItem, EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, IList result, bool canUpdate) { reader.Expect<SequenceStart>(); while (!reader.Accept<SequenceEnd>()) { var current = reader.Parser.Current; var value = nestedObjectDeserializer(reader, tItem); var promise = value as IValuePromise; if (promise == null) { result.Add(TypeConverter.ChangeType(value, tItem)); } else if (canUpdate) { var index = result.Add(tItem.IsValueType() ? Activator.CreateInstance(tItem) : null); promise.ValueAvailable += v => result[index] = TypeConverter.ChangeType(v, tItem); } else { throw new ForwardAnchorNotSupportedException( current.Start, current.End, "Forward alias references are not allowed because this type does not implement IList<>" ); } } reader.Expect<SequenceEnd>(); }
/// <summary> /// Name and Title are mandatory while shortcut is optional /// </summary> /// <param name="metaModel"></param> /// <param name="r"></param> private void DeserializeIcon(MetaModel.MetaModel metaModel, EventReader r) { string name = null, title = null, shortcut = null; r.Expect<MappingStart>(); r.Expect<Scalar>(); //name name = r.Expect<Scalar>().Value; r.Expect<Scalar>(); title = r.Expect<Scalar>().Value; if (r.Accept<Scalar>()) { if(r.Expect<Scalar>().Value.Equals(Shortcut)) { shortcut = r.Expect<Scalar>().Value; } } r.Expect<MappingEnd>(); metaModel.IconsList.Add(new ModelIcon(name, title, shortcut)); }
private void DeserializeNodeStyles(MetaModel.MetaModel metaModel, EventReader r) { r.Expect<SequenceStart>(); while (r.Accept<MappingStart>()) { DeserializeNodeStyle(metaModel, r); } r.Expect<SequenceEnd>(); }
private static object FromYaml(string yamlText, string yamlFile, bool expectOnlyFrontMatter, out TextPosition position) { try { position = new TextPosition(); if (yamlText == null) { return(null); } var parser = new Parser(new StringReader(yamlText)); var reader = new EventReader(parser); if (!reader.Accept <StreamStart>()) { return(null); } reader.Expect <StreamStart>(); var docStart = reader.Expect <DocumentStart>(); var hasDocumentStart = true; object result = null; ScriptArray objects = null; // If we expect to read multiple documents, we will return an array of result if (expectOnlyFrontMatter && docStart.IsImplicit) { return(null); } Mark endPosition; while (true) { if (reader.Accept <StreamEnd>()) { var evt = reader.Expect <StreamEnd>(); endPosition = evt.End; break; } if (hasDocumentStart && reader.Accept <DocumentEnd>()) { reader.Expect <DocumentEnd>(); hasDocumentStart = false; if (expectOnlyFrontMatter) { reader.Accept <DocumentStart>(); // Don't consume the token as the parser will try to parse // the following characters and could hit non YAML syntax (in Markdown) // and would throw a parser exception var nextDocStart = reader.Peek <DocumentStart>(); endPosition = nextDocStart.End; break; } continue; } if (reader.Accept <DocumentStart>()) { reader.Expect <DocumentStart>(); hasDocumentStart = true; } var obj = ReadEvent(reader); if (result == null) { result = obj; } else { if (objects == null) { objects = new ScriptArray { result }; result = objects; } objects.Add(obj); } } position = new TextPosition(endPosition.Index, endPosition.Line, endPosition.Column); return(result); } catch (Exception ex) { throw new LunetException($"Error while parsing {yamlFile}. {ex.Message}"); } }
private object DeserializeValue(EventReader reader, Type expectedType, object context) { if (reader.Accept<AnchorAlias>()) { throw new NotImplementedException(); //return context.Anchors[reader.Expect<AnchorAlias>().Value]; } var nodeEvent = (NodeEvent)reader.Parser.Current; if (IsNull(nodeEvent)) { reader.Expect<NodeEvent>(); AddAnchoredObject(nodeEvent, null, context.Anchors); return null; } object result = DeserializeValueNotNull(reader, context, nodeEvent, expectedType); return ObjectConverter.Convert(result, expectedType); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { if (!typeof(IDictionary).IsAssignableFrom(expectedType)) { value = false; return(false); } reader.Expect <MappingStart>(); var dictionary = (IDictionary)_objectFactory.Create(expectedType); while (!reader.Accept <MappingEnd>()) { var key = nestedObjectDeserializer(reader, typeof(object)); var keyPromise = key as IValuePromise; var keyValue = nestedObjectDeserializer(reader, typeof(object)); var valuePromise = keyValue as IValuePromise; if (keyPromise == null) { if (valuePromise == null) { // Happy path: both key and value are known dictionary.Add(key, keyValue); } else { // Key is known, value is pending valuePromise.ValueAvailable += v => dictionary.Add(key, v); } } else { if (valuePromise == null) { // Key is pending, value is known keyPromise.ValueAvailable += v => dictionary.Add(v, keyValue); } else { // Both key and value are pending. We need to wait until both of them becom available. var hasFirstPart = false; keyPromise.ValueAvailable += v => { if (hasFirstPart) { dictionary.Add(v, keyValue); } else { key = v; hasFirstPart = true; } }; valuePromise.ValueAvailable += v => { if (hasFirstPart) { dictionary.Add(key, v); } else { keyValue = v; hasFirstPart = true; } }; } } } value = dictionary; reader.Expect <MappingEnd>(); return(true); }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) { return(false); } assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetFileSerializer.FindSerializer(assetFileExtension); if (!(serializer is YamlAssetSerializer)) { return(false); } // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = PackageVersion.Zero; PackageVersion expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect <StreamStart>(); yamlEventReader.Expect <DocumentStart>(); var mappingStart = yamlEventReader.Expect <MappingStart>(); var tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType); expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero; Scalar assetKey; while ((assetKey = yamlEventReader.Allow <Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == nameof(Asset.Id)) { yamlEventReader.Skip(); } else if (assetKey.Value == nameof(Asset.SerializedVersion)) { // Check for old format: only a scalar var scalarVersion = yamlEventReader.Allow <Scalar>(); if (scalarVersion != null) { serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture)); // Let's update to new format using (var yamlAsset = loadAsset.AsYamlAsset()) { yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion); var baseBranch = yamlAsset.DynamicRootNode["~Base"]; if (baseBranch != null) { var baseAsset = baseBranch["Asset"]; if (baseAsset != null) { baseAsset.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion); } } } } else { // New format: package => version mapping yamlEventReader.Expect <MappingStart>(); while (!yamlEventReader.Accept <MappingEnd>()) { var packageName = yamlEventReader.Expect <Scalar>().Value; var packageVersion = PackageVersion.Parse(yamlEventReader.Expect <Scalar>().Value); // For now, we handle only one dependency at a time if (packageName == dependencyName) { serializedVersion = packageVersion; } } yamlEventReader.Expect <MappingEnd>(); } break; } else { // If anything else than Id or SerializedVersion, let's stop break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Stride) throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Stride?"); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} needs update, from version {serializedVersion} to version {expectedVersion}"); using (var yamlAsset = loadAsset.AsYamlAsset()) { var yamlRootNode = yamlAsset.RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName); if (assetUpgraders == null) { throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found"); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { PackageVersion targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); // Stop if the next version would be higher than what is expected if (untilVersion != null && targetVersion > untilVersion) { break; } upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; PackageVersion newSerializedVersion = null; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode)) { var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)]; newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value); } if (untilVersion == null && newSerializedVersion != expectedVersion) { throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}."); } context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} updated from version {serializedVersion} to version {expectedVersion}"); } return(true); } return(false); }
private static void DeserializeHelper(Type tKey, Type tValue, EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, IDictionary result) { reader.Expect<MappingStart>(); while (!reader.Accept<MappingEnd>()) { var key = nestedObjectDeserializer(reader, tKey); var keyPromise = key as IValuePromise; var value = nestedObjectDeserializer(reader, tValue); var valuePromise = value as IValuePromise; if (keyPromise == null) { if (valuePromise == null) { // Happy path: both key and value are known result[key] = value; } else { // Key is known, value is pending valuePromise.ValueAvailable += v => result[key] = v; } } else { if (valuePromise == null) { // Key is pending, value is known keyPromise.ValueAvailable += v => result[v] = value; } else { // Both key and value are pending. We need to wait until both of them becom available. var hasFirstPart = false; keyPromise.ValueAvailable += v => { if (hasFirstPart) { result[v] = value; } else { key = v; hasFirstPart = true; } }; valuePromise.ValueAvailable += v => { if (hasFirstPart) { result[key] = v; } else { value = v; hasFirstPart = true; } }; } } } reader.Expect<MappingEnd>(); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value) { if(!typeof(IDictionary).IsAssignableFrom(expectedType)) { value = false; return false; } reader.Expect<MappingStart>(); var dictionary = (IDictionary)_objectFactory.Create(expectedType); while (!reader.Accept<MappingEnd>()) { var key = nestedObjectDeserializer(reader, typeof(object)); var keyPromise = key as IValuePromise; var keyValue = nestedObjectDeserializer(reader, typeof(object)); var valuePromise = keyValue as IValuePromise; if (keyPromise == null) { if (valuePromise == null) { // Happy path: both key and value are known dictionary.Add(key, keyValue); } else { // Key is known, value is pending valuePromise.ValueAvailable += v => dictionary.Add(key, v); } } else { if (valuePromise == null) { // Key is pending, value is known keyPromise.ValueAvailable += v => dictionary.Add(v, keyValue); } else { // Both key and value are pending. We need to wait until both of them becom available. var hasFirstPart = false; keyPromise.ValueAvailable += v => { if (hasFirstPart) { dictionary.Add(v, keyValue); } else { key = v; hasFirstPart = true; } }; valuePromise.ValueAvailable += v => { if (hasFirstPart) { dictionary.Add(key, v); } else { keyValue = v; hasFirstPart = true; } }; } } } value = dictionary; reader.Expect<MappingEnd>(); return true; }
private void DeserializeRecentFiles(MetaModel.MetaModel metaModel, EventReader r) { r.Expect<SequenceStart>(); while (r.Accept<Scalar>()) { metaModel.RecentFiles.Add(r.Expect<Scalar>().Value); } r.Expect<SequenceEnd>(); }