{"action":"created","issue":{"url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/177","repository_url":"https://api.github.com/repos/trueaccord/ScalaPB","labels_url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/177/labels{/name}","comments_url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/177/comments","events_url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/177/events","html_url":"https://github.com/trueaccord/ScalaPB/issues/177","id":182002317,"number":177,"title":"Problem with custom types that have invariances","user":{"login":"nlochschmidt","id":759624,"avatar_url":"https://avatars.githubusercontent.com/u/759624?v=3","gravatar_id":"","url":"https://api.github.com/users/nlochschmidt","html_url":"https://github.com/nlochschmidt","followers_url":"https://api.github.com/users/nlochschmidt/followers","following_url":"https://api.github.com/users/nlochschmidt/following{/other_user}","gists_url":"https://api.github.com/users/nlochschmidt/gists{/gist_id}","starred_url":"https://api.github.com/users/nlochschmidt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nlochschmidt/subscriptions","organizations_url":"https://api.github.com/users/nlochschmidt/orgs","repos_url":"https://api.github.com/users/nlochschmidt/repos","events_url":"https://api.github.com/users/nlochschmidt/events{/privacy}","received_events_url":"https://api.github.com/users/nlochschmidt/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2016-10-10T12:27:00Z","updated_at":"2016-10-23T16:02:30Z","closed_at":"2016-10-18T02:03:52Z","body":"Given this proto definition:\r\n\r\n```protobuf\r\nsyntax = \"proto2\";\r\n\r\npackage example;\r\n\r\nimport \"scalapb/scalapb.proto\";\r\n\r\nmessage Event {\r\n    required string eventId = 1 [(scalapb.field).type = \"example.EventId\"];\r\n}\r\n\r\nmessage Deposit {\r\n    required int32 amount = 1 [(scalapb.field).type = \"example.PosMoneyAmount\"];\r\n}\r\n```\r\n\r\nand these TypeMappers\r\n\r\n```scala\r\ncase class EventId(id: UUID)\r\n\r\nobject EventId {\r\n  implicit val typeMapper = TypeMapper[String, EventId]{str => apply(UUID.fromString(str))}{_.id.toString}\r\n}\r\n\r\ncase class PosMoneyAmount(amount: Int) {\r\n  require(amount > 0, \"PosMoneyAmounts must be positive\")\r\n}\r\n\r\nobject PosMoneyAmount {\r\n  implicit val typeMapper = TypeMapper(apply(_: Int))(_.amount)\r\n}\r\n```\r\n\r\nI expected these tests to work:\r\n\r\n```scala\r\nbehavior of \"Custom Type serialization\"\r\n\r\nit must \"serialize and deserialize Event\" in {\r\n    val originalEvent = Event(EventId(UUID.randomUUID()))\r\n    val deserializedEvent = Event.parseFrom(originalEvent.toByteArray)\r\n\r\n    deserializedEvent mustBe originalEvent\r\n}\r\n\r\nit must \"serialize and deserialize Deposit\" in {\r\n    val originalDeposit = Deposit(PosMoneyAmount(10))\r\n    val deserializedDeposit = Deposit.parseFrom(originalDeposit.toByteArray)\r\n\r\n    deserializedDeposit mustBe originalDeposit\r\n}\r\n```\r\n\r\nInstead I get this output:\r\n\r\n```\r\n[info] DataSerializationTest:\r\n[info] Custom Type serialization\r\n[info] - must serialize and deserialize Event *** FAILED ***\r\n[info]   java.lang.IllegalArgumentException: Invalid UUID string:\r\n[info]   at java.util.UUID.fromString(UUID.java:194)\r\n[info]   at example.EventId$$anonfun$1.apply(EventId.scala:10)\r\n[info]   at example.EventId$$anonfun$1.apply(EventId.scala:10)\r\n[info]   at com.trueaccord.scalapb.TypeMapper$$anon$1.toCustom(TypeMapper.scala:24)\r\n[info]   at example.Event.Event$.defaultInstance$lzycompute(Event.scala:71)\r\n[info]   at example.Event.Event$.defaultInstance(Event.scala:70)\r\n[info]   at example.Event.Event$.defaultInstance(Event.scala:58)\r\n[info]   at com.trueaccord.scalapb.LiteParser$.parseFrom(LiteParser.scala:9)\r\n[info]   at com.trueaccord.scalapb.GeneratedMessageCompanion$class.parseFrom(GeneratedMessageCompanion.scala:103)\r\n[info]   at example.Event.Event$.parseFrom(Event.scala:58)\r\n[info]   ...\r\n[info] - must serialize and deserialize Deposit *** FAILED ***\r\n[info]   java.lang.IllegalArgumentException: requirement failed: PosMoneyAmounts must be positive\r\n[info]   at scala.Predef$.require(Predef.scala:224)\r\n[info]   at example.PosMoneyAmount.<init>(EventId.scala:14)\r\n[info]   at example.PosMoneyAmount$$anonfun$4.apply(EventId.scala:18)\r\n[info]   at example.PosMoneyAmount$$anonfun$4.apply(EventId.scala:18)\r\n[info]   at com.trueaccord.scalapb.TypeMapper$$anon$1.toCustom(TypeMapper.scala:24)\r\n[info]   at example.Event.Deposit$.defaultInstance$lzycompute(Deposit.scala:71)\r\n[info]   at example.Event.Deposit$.defaultInstance(Deposit.scala:70)\r\n[info]   at example.Event.Deposit$.defaultInstance(Deposit.scala:58)\r\n[info]   at com.trueaccord.scalapb.LiteParser$.parseFrom(LiteParser.scala:9)\r\n[info]   at com.trueaccord.scalapb.GeneratedMessageCompanion$class.parseFrom(GeneratedMessageCompanion.scala:103)\r\n```\r\n\r\nFull example project at https://github.com/nlochschmidt/ScalaPB-CustomTypesBug \r\n\r\nIt looks like the issue originates in the `defaultInstance` method which seems to try and create a `UUID` from an empty string and a `PosMoneyAmount` from 0.\r\n\r\nIs this a known limitation of using custom types in ScalaPB?"},"comment":{"url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/comments/255596732","html_url":"https://github.com/trueaccord/ScalaPB/issues/177#issuecomment-255596732","issue_url":"https://api.github.com/repos/trueaccord/ScalaPB/issues/177","id":255596732,"user":{"login":"nlochschmidt","id":759624,"avatar_url":"https://avatars.githubusercontent.com/u/759624?v=3","gravatar_id":"","url":"https://api.github.com/users/nlochschmidt","html_url":"https://github.com/nlochschmidt","followers_url":"https://api.github.com/users/nlochschmidt/followers","following_url":"https://api.github.com/users/nlochschmidt/following{/other_user}","gists_url":"https://api.github.com/users/nlochschmidt/gists{/gist_id}","starred_url":"https://api.github.com/users/nlochschmidt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nlochschmidt/subscriptions","organizations_url":"https://api.github.com/users/nlochschmidt/orgs","repos_url":"https://api.github.com/users/nlochschmidt/repos","events_url":"https://api.github.com/users/nlochschmidt/events{/privacy}","received_events_url":"https://api.github.com/users/nlochschmidt/received_events","type":"User","site_admin":false},"created_at":"2016-10-23T16:02:30Z","updated_at":"2016-10-23T16:02:30Z","body":"@thesamet I didn't know the part about the default instance from the java tutorial and from that standpoint it makes total sense to support the standard protobuf semantics instead of deviating from them.\r\nThanks for the detailed explanation 👍 "}}
{"actor":{"display_login":"nlochschmidt"}}