示例#1
0
		/// <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");
		}
示例#2
0
		/// <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);
     
 }
示例#5
0
    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());
            }
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        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));
        }
示例#11
0
        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;
		}
示例#13
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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;
                            }
                        };
                    }
                }
            }
        }
示例#20
0
        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;
        }
示例#21
0
        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>();
        }
示例#23
0
        /// <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));
        }
示例#24
0
        private void DeserializeNodeStyles(MetaModel.MetaModel metaModel, EventReader r)
        {
            r.Expect<SequenceStart>();

            while (r.Accept<MappingStart>())
            {
                DeserializeNodeStyle(metaModel, r);
            }

            r.Expect<SequenceEnd>();
        }
示例#25
0
        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}");
            }
        }
示例#26
0
        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);
        }
示例#28
0
        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;
        }
示例#31
0
        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>();
        }