public GameObjectVisitor(UnsafeValueView view, List <DeserializationEvent> events, SerializationMetadata metadata,
                          Transform parent, GameObjectContainer prefabRoot, JsonSerializationParameters parameters) : base(metadata)
 {
     SetView(view);
     SetEvents(events);
     m_Events     = events;
     m_Parameters = parameters;
     m_Parent     = parent;
     m_PrefabRoot = prefabRoot;
 }
        protected override void AcceptProperty <TContainer>(ref TContainer container, UnsafeObjectView view, IProperty <TContainer> property)
        {
            var name = property.Name;

            if (view.TryGetValue(name, out var value))
            {
                using (CreateViewScope(value))
                {
                    if (container is GameObjectContainer gameObjectContainer)
                    {
                        gameObjectContainer.Parent = m_Parent;
                        m_GameObjectContainer      = gameObjectContainer;
                        // TODO: Detect by type?
                        if (name == GameObjectContainer.PrefabMetadataProperty)
                        {
                            ((IPropertyAccept <TContainer>)property).Accept(this, ref container);
                            return;
                        }

                        if (name == GameObjectContainer.ComponentsProperty)
                        {
                            var gameObject = gameObjectContainer.GameObject;
                            ((IPropertyAccept <TContainer>)property).Accept(
                                new ComponentVisitor(gameObject, m_View, m_Events, m_SerializationMetadata),
                                ref container);

                            var prefabMetadata = gameObjectContainer.PrefabMetadataContainer;
                            if (prefabMetadata != null)
                            {
                                gameObjectContainer.FinalizePrefab(prefabMetadata, m_SerializationMetadata);
                                m_PrefabRoot = null;
                            }

                            return;
                        }

                        if (name == GameObjectContainer.ChildrenProperty)
                        {
                            ((IPropertyAccept <TContainer>)property).Accept(
                                new GameObjectVisitor(m_View, m_Events, m_SerializationMetadata,
                                                      gameObjectContainer.GameObject.transform, m_PrefabRoot, m_Parameters),
                                ref container);

                            return;
                        }
                    }
                    else if (container is RuntimeAddedComponent addedComponent)
                    {
                        if (name == RuntimeAddedComponent.ComponentFieldName)
                        {
                            var target = m_PrefabRoot.GameObject.transform.GetTransformAtPath(addedComponent.TransformPath);
                            ((IPropertyAccept <TContainer>)property).Accept(
                                new ComponentVisitor(target.gameObject, m_View, m_Events, m_SerializationMetadata),
                                ref container);

                            return;
                        }
                    }
                    else if (container is RuntimeAddedGameObject addedGameObject)
                    {
                        if (name == nameof(addedGameObject.GameObject))
                        {
                            var parent = m_PrefabRoot.GameObject.transform.GetTransformAtPath(addedGameObject.TransformPath);
                            ((IPropertyAccept <TContainer>)property).Accept(
                                new GameObjectVisitor(m_View, m_Events, m_SerializationMetadata, parent, m_PrefabRoot, m_Parameters),
                                ref container);

                            return;
                        }
                    }
                    else if (container is PrefabMetadataContainer prefabMetadataContainer)
                    {
                        if (name == PrefabMetadataContainer.GuidFieldName)
                        {
                            m_PrefabRoot = m_GameObjectContainer;
                            ((IPropertyAccept <TContainer>)property).Accept(this, ref container);
                            m_PrefabRoot.InstantiatePrefab(prefabMetadataContainer.Guid, m_SerializationMetadata.AssetPack);
                            return;
                        }
                    }

                    ((IPropertyAccept <TContainer>)property).Accept(this, ref container);
                }
            }
        }