{"action":"created","comment":{"url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/comments/231580019","pull_request_review_id":172581734,"id":231580019,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMTU4MDAxOQ==","diff_hunk":"@@ -200,5 +201,41 @@ public bool Equals(DictionaryInterfaceContainer other)\n                 return Integers.All(pair => other.Integers.TryGetValue(pair.Key, out var otherValue) && pair.Value == otherValue);\n             }\n         }\n+\n+        [FirestoreData]\n+        public sealed class CustomUser\n+        {\n+            [FirestoreProperty]\n+            public int HighScore { get; set; }\n+\n+            [FirestoreProperty]\n+            public string Name { get; set; }\n+\n+            [FirestoreProperty]\n+            public Email Email { get; set; }\n+        }\n+\n+        [FirestoreData(Converter = typeof(EmailConverter))]\n+        public sealed class Email","path":"apis/Google.Cloud.Firestore/Google.Cloud.Firestore.Tests/SerializationTestData.cs","position":27,"original_position":27,"commit_id":"89e4ea069f959474ca2f53bb70cd7eb47a8bc0e8","original_commit_id":"89e4ea069f959474ca2f53bb70cd7eb47a8bc0e8","user":{"login":"mikelehen","id":206364,"node_id":"MDQ6VXNlcjIwNjM2NA==","avatar_url":"https://avatars1.githubusercontent.com/u/206364?v=4","gravatar_id":"","url":"https://api.github.com/users/mikelehen","html_url":"https://github.com/mikelehen","followers_url":"https://api.github.com/users/mikelehen/followers","following_url":"https://api.github.com/users/mikelehen/following{/other_user}","gists_url":"https://api.github.com/users/mikelehen/gists{/gist_id}","starred_url":"https://api.github.com/users/mikelehen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikelehen/subscriptions","organizations_url":"https://api.github.com/users/mikelehen/orgs","repos_url":"https://api.github.com/users/mikelehen/repos","events_url":"https://api.github.com/users/mikelehen/events{/privacy}","received_events_url":"https://api.github.com/users/mikelehen/received_events","type":"User","site_admin":false},"body":"FWIW- If we can actually solve the \"flexible serialization of types the developer doesn't own\" with this approach, then I'm much more on board. But without that it seems like boilerplate and indirection w/o benefit.\r\n\r\nAll models used with Firestore have to be mutable today, so I don't think it'd be problematic to require a public default constructor in order to implement IFirestoreConverter (which would probably be renamed IFirestoreConvertible or something).\r\n\r\nI'm not overly won over by the \"shared model\" use case. It seems like an advanced use case and worst case they can just use the poor-mans-converter workaround of excluding Email from serialization and instead having a String getter/setter that does the Firestore conversion.\r\n\r\nFor the MailAddress case, I thought you had a previous iteration of this proposal that attached the converter to the property instead of the class, e.g.:\r\n\r\n```\r\n        [FirestoreData]\r\n        public sealed class CustomUser\r\n        {\r\n           ...\r\n            [FirestoreProperty(Converter = typeof(EmailConverter)]\r\n            public Email Email { get; set; }\r\n```\r\nor something like that.  Would that solve this?","created_at":"2018-11-07T16:34:54Z","updated_at":"2018-11-07T16:34:54Z","html_url":"https://github.com/googleapis/google-cloud-dotnet/pull/2663#discussion_r231580019","pull_request_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/comments/231580019"},"html":{"href":"https://github.com/googleapis/google-cloud-dotnet/pull/2663#discussion_r231580019"},"pull_request":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663"}},"in_reply_to_id":231562923},"pull_request":{"url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663","id":228605753,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI4NjA1NzUz","html_url":"https://github.com/googleapis/google-cloud-dotnet/pull/2663","diff_url":"https://github.com/googleapis/google-cloud-dotnet/pull/2663.diff","patch_url":"https://github.com/googleapis/google-cloud-dotnet/pull/2663.patch","issue_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/2663","number":2663,"state":"open","locked":false,"title":"Rough and ready prototype of custom serialization","user":{"login":"jskeet","id":17011,"node_id":"MDQ6VXNlcjE3MDEx","avatar_url":"https://avatars1.githubusercontent.com/u/17011?v=4","gravatar_id":"","url":"https://api.github.com/users/jskeet","html_url":"https://github.com/jskeet","followers_url":"https://api.github.com/users/jskeet/followers","following_url":"https://api.github.com/users/jskeet/following{/other_user}","gists_url":"https://api.github.com/users/jskeet/gists{/gist_id}","starred_url":"https://api.github.com/users/jskeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jskeet/subscriptions","organizations_url":"https://api.github.com/users/jskeet/orgs","repos_url":"https://api.github.com/users/jskeet/repos","events_url":"https://api.github.com/users/jskeet/events{/privacy}","received_events_url":"https://api.github.com/users/jskeet/received_events","type":"User","site_admin":false},"body":"This is to demonstrate *one* possible approach to #2534.\r\n","created_at":"2018-11-06T08:15:51Z","updated_at":"2018-11-07T16:34:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"428c2647ce858b3a3d8788a57f0e76fe0541dd5d","assignee":{"login":"jskeet","id":17011,"node_id":"MDQ6VXNlcjE3MDEx","avatar_url":"https://avatars1.githubusercontent.com/u/17011?v=4","gravatar_id":"","url":"https://api.github.com/users/jskeet","html_url":"https://github.com/jskeet","followers_url":"https://api.github.com/users/jskeet/followers","following_url":"https://api.github.com/users/jskeet/following{/other_user}","gists_url":"https://api.github.com/users/jskeet/gists{/gist_id}","starred_url":"https://api.github.com/users/jskeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jskeet/subscriptions","organizations_url":"https://api.github.com/users/jskeet/orgs","repos_url":"https://api.github.com/users/jskeet/repos","events_url":"https://api.github.com/users/jskeet/events{/privacy}","received_events_url":"https://api.github.com/users/jskeet/received_events","type":"User","site_admin":false},"assignees":[{"login":"jskeet","id":17011,"node_id":"MDQ6VXNlcjE3MDEx","avatar_url":"https://avatars1.githubusercontent.com/u/17011?v=4","gravatar_id":"","url":"https://api.github.com/users/jskeet","html_url":"https://github.com/jskeet","followers_url":"https://api.github.com/users/jskeet/followers","following_url":"https://api.github.com/users/jskeet/following{/other_user}","gists_url":"https://api.github.com/users/jskeet/gists{/gist_id}","starred_url":"https://api.github.com/users/jskeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jskeet/subscriptions","organizations_url":"https://api.github.com/users/jskeet/orgs","repos_url":"https://api.github.com/users/jskeet/repos","events_url":"https://api.github.com/users/jskeet/events{/privacy}","received_events_url":"https://api.github.com/users/jskeet/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1062999527,"node_id":"MDU6TGFiZWwxMDYyOTk5NTI3","url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/labels/cla:%20yes","name":"cla: yes","color":"0B7601","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663/commits","review_comments_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663/comments","review_comment_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/2663/comments","statuses_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/statuses/89e4ea069f959474ca2f53bb70cd7eb47a8bc0e8","head":{"label":"jskeet:firestore-custom-serialization","ref":"firestore-custom-serialization","sha":"89e4ea069f959474ca2f53bb70cd7eb47a8bc0e8","user":{"login":"jskeet","id":17011,"node_id":"MDQ6VXNlcjE3MDEx","avatar_url":"https://avatars1.githubusercontent.com/u/17011?v=4","gravatar_id":"","url":"https://api.github.com/users/jskeet","html_url":"https://github.com/jskeet","followers_url":"https://api.github.com/users/jskeet/followers","following_url":"https://api.github.com/users/jskeet/following{/other_user}","gists_url":"https://api.github.com/users/jskeet/gists{/gist_id}","starred_url":"https://api.github.com/users/jskeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jskeet/subscriptions","organizations_url":"https://api.github.com/users/jskeet/orgs","repos_url":"https://api.github.com/users/jskeet/repos","events_url":"https://api.github.com/users/jskeet/events{/privacy}","received_events_url":"https://api.github.com/users/jskeet/received_events","type":"User","site_admin":false},"repo":{"id":35881054,"node_id":"MDEwOlJlcG9zaXRvcnkzNTg4MTA1NA==","name":"google-cloud-dotnet","full_name":"jskeet/google-cloud-dotnet","private":false,"owner":{"login":"jskeet","id":17011,"node_id":"MDQ6VXNlcjE3MDEx","avatar_url":"https://avatars1.githubusercontent.com/u/17011?v=4","gravatar_id":"","url":"https://api.github.com/users/jskeet","html_url":"https://github.com/jskeet","followers_url":"https://api.github.com/users/jskeet/followers","following_url":"https://api.github.com/users/jskeet/following{/other_user}","gists_url":"https://api.github.com/users/jskeet/gists{/gist_id}","starred_url":"https://api.github.com/users/jskeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jskeet/subscriptions","organizations_url":"https://api.github.com/users/jskeet/orgs","repos_url":"https://api.github.com/users/jskeet/repos","events_url":"https://api.github.com/users/jskeet/events{/privacy}","received_events_url":"https://api.github.com/users/jskeet/received_events","type":"User","site_admin":false},"html_url":"https://github.com/jskeet/google-cloud-dotnet","description":"Google Cloud Client Library for .NET","fork":true,"url":"https://api.github.com/repos/jskeet/google-cloud-dotnet","forks_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/forks","keys_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/teams","hooks_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/hooks","issue_events_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/issues/events{/number}","events_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/events","assignees_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/assignees{/user}","branches_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/branches{/branch}","tags_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/tags","blobs_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/statuses/{sha}","languages_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/languages","stargazers_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/stargazers","contributors_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/contributors","subscribers_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/subscribers","subscription_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/subscription","commits_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/contents/{+path}","compare_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/merges","archive_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/downloads","issues_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/issues{/number}","pulls_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/pulls{/number}","milestones_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/milestones{/number}","notifications_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/labels{/name}","releases_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/releases{/id}","deployments_url":"https://api.github.com/repos/jskeet/google-cloud-dotnet/deployments","created_at":"2015-05-19T12:36:32Z","updated_at":"2018-11-07T08:10:19Z","pushed_at":"2018-11-07T16:11:23Z","git_url":"git://github.com/jskeet/google-cloud-dotnet.git","ssh_url":"git@github.com:jskeet/google-cloud-dotnet.git","clone_url":"https://github.com/jskeet/google-cloud-dotnet.git","svn_url":"https://github.com/jskeet/google-cloud-dotnet","homepage":null,"size":45459,"stargazers_count":3,"watchers_count":3,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":3,"open_issues":0,"watchers":3,"default_branch":"master"}},"base":{"label":"googleapis:master","ref":"master","sha":"b05ef15de8fb92591d37aa18786b12595b334d78","user":{"login":"googleapis","id":16785467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2Nzg1NDY3","avatar_url":"https://avatars3.githubusercontent.com/u/16785467?v=4","gravatar_id":"","url":"https://api.github.com/users/googleapis","html_url":"https://github.com/googleapis","followers_url":"https://api.github.com/users/googleapis/followers","following_url":"https://api.github.com/users/googleapis/following{/other_user}","gists_url":"https://api.github.com/users/googleapis/gists{/gist_id}","starred_url":"https://api.github.com/users/googleapis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/googleapis/subscriptions","organizations_url":"https://api.github.com/users/googleapis/orgs","repos_url":"https://api.github.com/users/googleapis/repos","events_url":"https://api.github.com/users/googleapis/events{/privacy}","received_events_url":"https://api.github.com/users/googleapis/received_events","type":"Organization","site_admin":false},"repo":{"id":35877412,"node_id":"MDEwOlJlcG9zaXRvcnkzNTg3NzQxMg==","name":"google-cloud-dotnet","full_name":"googleapis/google-cloud-dotnet","private":false,"owner":{"login":"googleapis","id":16785467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2Nzg1NDY3","avatar_url":"https://avatars3.githubusercontent.com/u/16785467?v=4","gravatar_id":"","url":"https://api.github.com/users/googleapis","html_url":"https://github.com/googleapis","followers_url":"https://api.github.com/users/googleapis/followers","following_url":"https://api.github.com/users/googleapis/following{/other_user}","gists_url":"https://api.github.com/users/googleapis/gists{/gist_id}","starred_url":"https://api.github.com/users/googleapis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/googleapis/subscriptions","organizations_url":"https://api.github.com/users/googleapis/orgs","repos_url":"https://api.github.com/users/googleapis/repos","events_url":"https://api.github.com/users/googleapis/events{/privacy}","received_events_url":"https://api.github.com/users/googleapis/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/googleapis/google-cloud-dotnet","description":"Google Cloud Client Libraries for .NET","fork":false,"url":"https://api.github.com/repos/googleapis/google-cloud-dotnet","forks_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/forks","keys_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/teams","hooks_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/hooks","issue_events_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/events{/number}","events_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/events","assignees_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/assignees{/user}","branches_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/branches{/branch}","tags_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/tags","blobs_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/statuses/{sha}","languages_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/languages","stargazers_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/stargazers","contributors_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/contributors","subscribers_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/subscribers","subscription_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/subscription","commits_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/contents/{+path}","compare_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/merges","archive_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/downloads","issues_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues{/number}","pulls_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls{/number}","milestones_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/milestones{/number}","notifications_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/labels{/name}","releases_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/releases{/id}","deployments_url":"https://api.github.com/repos/googleapis/google-cloud-dotnet/deployments","created_at":"2015-05-19T11:14:02Z","updated_at":"2018-11-07T16:11:22Z","pushed_at":"2018-11-07T16:11:20Z","git_url":"git://github.com/googleapis/google-cloud-dotnet.git","ssh_url":"git@github.com:googleapis/google-cloud-dotnet.git","clone_url":"https://github.com/googleapis/google-cloud-dotnet.git","svn_url":"https://github.com/googleapis/google-cloud-dotnet","homepage":"https://googleapis.github.io/google-cloud-dotnet/","size":70866,"stargazers_count":337,"watchers_count":337,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":155,"mirror_url":null,"archived":false,"open_issues_count":32,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":155,"open_issues":32,"watchers":337,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663"},"html":{"href":"https://github.com/googleapis/google-cloud-dotnet/pull/2663"},"issue":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/2663"},"comments":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/issues/2663/comments"},"review_comments":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663/comments"},"review_comment":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/pulls/2663/commits"},"statuses":{"href":"https://api.github.com/repos/googleapis/google-cloud-dotnet/statuses/89e4ea069f959474ca2f53bb70cd7eb47a8bc0e8"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"mikelehen"}}