diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Timothy Clem (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# proto-lens-jsonpb
+
+Quick hack to generate orphan ToJSON/FromJSON instances for proto-lens.
+
+This requires the use of [proto-lens](https://github.com/google/proto-lens) to generate haskell datatypes from proto messages.
+
+## Requirements
+
+1. Install `protoc` (e.g., `brew install protoc`)
+2. Install the required protoc plugins:
+   - `cabal install proto-lens-protoc`
+   - `go get github.com/tclem/proto-lens-jsonpb/protoc-gen-jsonpb_haskell`
+
+## Usage
+
+Use the protoc plugin to generate associated protobuf types from a proto file.
+
+```
+protoc -I=. --proto_path=./proto \
+  --plugin=protoc-gen-haskell=`which proto-lens-protoc` --haskell_out=./app \
+  --plugin=protoc-gen-jsonpb_haskell=./script/run-jsonpb_haskell --jsonpb_haskell_out=./app \
+  haberdasher.proto
+```
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,23 @@
+module Main where
+
+import           Data.Aeson (ToJSON (..), fromEncoding)
+import           Data.ByteString.Builder (toLazyByteString)
+import qualified Data.ByteString.Lazy.Char8 as BC
+import           Data.ProtoLens (defMessage)
+import           Lens.Micro
+import           Proto.Haberdasher as P
+import           Proto.Haberdasher_Fields as P
+import           Proto.Haberdasher_JSON ()
+
+main :: IO ()
+main = do
+  print mkPong
+  BC.putStrLn $ toLazyByteString (fromEncoding (toEncoding mkPong))
+  where
+    mkPong :: Pong
+    mkPong = defMessage
+      & P.status .~ "OK"
+      & P.stuff .~ mempty
+      & P.maybe'extra .~ Nothing
+      & P.id .~ 1
+      & P.type' .~ "hello"
diff --git a/app/Proto/Haberdasher.hs b/app/Proto/Haberdasher.hs
new file mode 100644
--- /dev/null
+++ b/app/Proto/Haberdasher.hs
@@ -0,0 +1,2279 @@
+{- This file was auto-generated from haberdasher.proto by the proto-lens-protoc program. -}
+{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies,
+  UndecidableInstances, GeneralizedNewtypeDeriving,
+  MultiParamTypeClasses, FlexibleContexts, FlexibleInstances,
+  PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds,
+  BangPatterns, TypeApplications #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports#-}
+{-# OPTIONS_GHC -fno-warn-duplicate-exports#-}
+module Proto.Haberdasher
+       (Haberdasher(..), Health(..), Bill(), Bill'Extra(..),
+        _Bill'VatInfo, _Bill'ZipCode, Bill'BillingStatus(..),
+        Bill'BillingStatus(), Bill'BillingStatus'UnrecognizedValue,
+        ChangeType(..), ChangeType(), ChangeType'UnrecognizedValue,
+        DeletedTerm(), Demo(), DiffTreeVertex(),
+        DiffTreeVertex'DiffTerm(..), _DiffTreeVertex'Deleted,
+        _DiffTreeVertex'Inserted, EmptyMessage(), FieldTestMessage(),
+        Hat(), InsertedTerm(), Ping(), Pong(), Pong'Extra(..), _Pong'T,
+        _Pong'U, Price(), Size(), Test())
+       where
+import qualified Data.ProtoLens.Runtime.Control.DeepSeq
+       as Control.DeepSeq
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Prism
+       as Data.ProtoLens.Prism
+import qualified Data.ProtoLens.Runtime.Prelude as Prelude
+import qualified Data.ProtoLens.Runtime.Data.Int as Data.Int
+import qualified Data.ProtoLens.Runtime.Data.Monoid as Data.Monoid
+import qualified Data.ProtoLens.Runtime.Data.Word as Data.Word
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens
+       as Data.ProtoLens
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Bytes
+       as Data.ProtoLens.Encoding.Bytes
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Growing
+       as Data.ProtoLens.Encoding.Growing
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Parser.Unsafe
+       as Data.ProtoLens.Encoding.Parser.Unsafe
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Wire
+       as Data.ProtoLens.Encoding.Wire
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Field
+       as Data.ProtoLens.Field
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Message.Enum
+       as Data.ProtoLens.Message.Enum
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Service.Types
+       as Data.ProtoLens.Service.Types
+import qualified Data.ProtoLens.Runtime.Lens.Family2
+       as Lens.Family2
+import qualified Data.ProtoLens.Runtime.Lens.Family2.Unchecked
+       as Lens.Family2.Unchecked
+import qualified Data.ProtoLens.Runtime.Data.Text as Data.Text
+import qualified Data.ProtoLens.Runtime.Data.Map as Data.Map
+import qualified Data.ProtoLens.Runtime.Data.ByteString
+       as Data.ByteString
+import qualified Data.ProtoLens.Runtime.Data.ByteString.Char8
+       as Data.ByteString.Char8
+import qualified Data.ProtoLens.Runtime.Data.Text.Encoding
+       as Data.Text.Encoding
+import qualified Data.ProtoLens.Runtime.Data.Vector as Data.Vector
+import qualified Data.ProtoLens.Runtime.Data.Vector.Generic
+       as Data.Vector.Generic
+import qualified Data.ProtoLens.Runtime.Data.Vector.Unboxed
+       as Data.Vector.Unboxed
+import qualified Data.ProtoLens.Runtime.Text.Read as Text.Read
+
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.price' @:: Lens' Bill Price@
+    * 'Proto.Haberdasher_Fields.maybe'price' @:: Lens' Bill (Prelude.Maybe Price)@
+    * 'Proto.Haberdasher_Fields.status' @:: Lens' Bill Bill'BillingStatus@
+    * 'Proto.Haberdasher_Fields.maybe'extra' @:: Lens' Bill (Prelude.Maybe Bill'Extra)@
+    * 'Proto.Haberdasher_Fields.maybe'vatInfo' @:: Lens' Bill (Prelude.Maybe Data.Text.Text)@
+    * 'Proto.Haberdasher_Fields.vatInfo' @:: Lens' Bill Data.Text.Text@
+    * 'Proto.Haberdasher_Fields.maybe'zipCode' @:: Lens' Bill (Prelude.Maybe Data.Text.Text)@
+    * 'Proto.Haberdasher_Fields.zipCode' @:: Lens' Bill Data.Text.Text@
+ -}
+data Bill = Bill{_Bill'price :: !(Prelude.Maybe Price),
+                 _Bill'status :: !Bill'BillingStatus,
+                 _Bill'extra :: !(Prelude.Maybe Bill'Extra),
+                 _Bill'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Bill where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+data Bill'Extra = Bill'VatInfo !Data.Text.Text
+                | Bill'ZipCode !Data.Text.Text
+                    deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
+instance Data.ProtoLens.Field.HasField Bill "price" (Price) where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'price
+               (\ x__ y__ -> x__{_Bill'price = y__}))
+              Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.defMessage
+instance Data.ProtoLens.Field.HasField Bill "maybe'price"
+           (Prelude.Maybe Price)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'price
+               (\ x__ y__ -> x__{_Bill'price = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Bill "status"
+           (Bill'BillingStatus)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'status
+               (\ x__ y__ -> x__{_Bill'status = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Bill "maybe'extra"
+           (Prelude.Maybe Bill'Extra)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'extra
+               (\ x__ y__ -> x__{_Bill'extra = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Bill "maybe'vatInfo"
+           (Prelude.Maybe Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'extra
+               (\ x__ y__ -> x__{_Bill'extra = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (Bill'VatInfo x__val) -> Prelude.Just x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap Bill'VatInfo y__)
+instance Data.ProtoLens.Field.HasField Bill "vatInfo"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'extra
+               (\ x__ y__ -> x__{_Bill'extra = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (Bill'VatInfo x__val) -> Prelude.Just x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap Bill'VatInfo y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault
+instance Data.ProtoLens.Field.HasField Bill "maybe'zipCode"
+           (Prelude.Maybe Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'extra
+               (\ x__ y__ -> x__{_Bill'extra = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (Bill'ZipCode x__val) -> Prelude.Just x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap Bill'ZipCode y__)
+instance Data.ProtoLens.Field.HasField Bill "zipCode"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Bill'extra
+               (\ x__ y__ -> x__{_Bill'extra = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (Bill'ZipCode x__val) -> Prelude.Just x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap Bill'ZipCode y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault
+instance Data.ProtoLens.Message Bill where
+        messageName _ = Data.Text.pack "example.haberdasher.Bill"
+        fieldsByTag
+          = let price__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "price"
+                      (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::
+                         Data.ProtoLens.FieldTypeDescriptor Price)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'price"))
+                      :: Data.ProtoLens.FieldDescriptor Bill
+                status__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "status"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::
+                         Data.ProtoLens.FieldTypeDescriptor Bill'BillingStatus)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"status"))
+                      :: Data.ProtoLens.FieldDescriptor Bill
+                vatInfo__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "vat_info"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'vatInfo"))
+                      :: Data.ProtoLens.FieldDescriptor Bill
+                zipCode__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "zip_code"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'zipCode"))
+                      :: Data.ProtoLens.FieldDescriptor Bill
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, price__field_descriptor),
+                 (Data.ProtoLens.Tag 2, status__field_descriptor),
+                 (Data.ProtoLens.Tag 3, vatInfo__field_descriptor),
+                 (Data.ProtoLens.Tag 4, zipCode__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Bill'_unknownFields
+              (\ x__ y__ -> x__{_Bill'_unknownFields = y__})
+        defMessage
+          = Bill{_Bill'price = Prelude.Nothing,
+                 _Bill'status = Data.ProtoLens.fieldDefault,
+                 _Bill'extra = Prelude.Nothing, _Bill'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Bill -> Data.ProtoLens.Encoding.Bytes.Parser Bill
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                10 -> do y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                  Data.ProtoLens.Encoding.Bytes.isolate
+                                                    (Prelude.fromIntegral len)
+                                                    Data.ProtoLens.parseMessage)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "price"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"price") y
+                                              x)
+                                16 -> do y <- (Prelude.fmap Prelude.toEnum
+                                                 (Prelude.fmap Prelude.fromIntegral
+                                                    Data.ProtoLens.Encoding.Bytes.getVarInt))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "status"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"status")
+                                              y
+                                              x)
+                                26 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "vat_info"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"vatInfo")
+                                              y
+                                              x)
+                                34 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "zip_code"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"zipCode")
+                                              y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Bill"
+        buildMessage
+          = (\ _x ->
+               (case
+                  Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'price") _x of
+                    (Prelude.Nothing) -> Data.Monoid.mempty
+                    Prelude.Just _v -> (Data.ProtoLens.Encoding.Bytes.putVarInt 10)
+                                         Data.Monoid.<>
+                                         (((\ bs ->
+                                              (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                 (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                                Data.Monoid.<>
+                                                Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                                            Prelude.. Data.ProtoLens.encodeMessage)
+                                           _v)
+                 Data.Monoid.<>
+                 (let _v
+                        = Lens.Family2.view (Data.ProtoLens.Field.field @"status") _x
+                    in
+                    if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                      Data.Monoid.mempty else
+                      (Data.ProtoLens.Encoding.Bytes.putVarInt 16) Data.Monoid.<>
+                        (((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                            Prelude.fromIntegral)
+                           Prelude.. Prelude.fromEnum)
+                          _v)
+                   Data.Monoid.<>
+                   (case
+                      Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'extra") _x of
+                        (Prelude.Nothing) -> Data.Monoid.mempty
+                        Prelude.Just
+                          (Bill'VatInfo v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt 26)
+                                                Data.Monoid.<>
+                                                (((\ bs ->
+                                                     (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                        (Prelude.fromIntegral
+                                                           (Data.ByteString.length bs)))
+                                                       Data.Monoid.<>
+                                                       Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                                                   Prelude.. Data.Text.Encoding.encodeUtf8)
+                                                  v
+                        Prelude.Just
+                          (Bill'ZipCode v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt 34)
+                                                Data.Monoid.<>
+                                                (((\ bs ->
+                                                     (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                        (Prelude.fromIntegral
+                                                           (Data.ByteString.length bs)))
+                                                       Data.Monoid.<>
+                                                       Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                                                   Prelude.. Data.Text.Encoding.encodeUtf8)
+                                                  v)
+                     Data.Monoid.<>
+                     Data.ProtoLens.Encoding.Wire.buildFieldSet
+                       (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Bill where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Bill'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Bill'price x__)
+                    (Control.DeepSeq.deepseq (_Bill'status x__)
+                       (Control.DeepSeq.deepseq (_Bill'extra x__) (())))))
+instance Control.DeepSeq.NFData Bill'Extra where
+        rnf (Bill'VatInfo x__) = Control.DeepSeq.rnf x__
+        rnf (Bill'ZipCode x__) = Control.DeepSeq.rnf x__
+_Bill'VatInfo ::
+              Data.ProtoLens.Prism.Prism' Bill'Extra Data.Text.Text
+_Bill'VatInfo
+  = Data.ProtoLens.Prism.prism' Bill'VatInfo
+      (\ p__ ->
+         case p__ of
+             Bill'VatInfo p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+_Bill'ZipCode ::
+              Data.ProtoLens.Prism.Prism' Bill'Extra Data.Text.Text
+_Bill'ZipCode
+  = Data.ProtoLens.Prism.prism' Bill'ZipCode
+      (\ p__ ->
+         case p__ of
+             Bill'ZipCode p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+newtype Bill'BillingStatus'UnrecognizedValue = Bill'BillingStatus'UnrecognizedValue Data.Int.Int32
+                                                 deriving (Prelude.Eq, Prelude.Ord, Prelude.Show)
+data Bill'BillingStatus = Bill'UN_PAID
+                        | Bill'PAID
+                        | Bill'BillingStatus'Unrecognized !Bill'BillingStatus'UnrecognizedValue
+                            deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
+instance Data.ProtoLens.MessageEnum Bill'BillingStatus where
+        maybeToEnum 0 = Prelude.Just Bill'UN_PAID
+        maybeToEnum 1 = Prelude.Just Bill'PAID
+        maybeToEnum k
+          = Prelude.Just
+              (Bill'BillingStatus'Unrecognized
+                 (Bill'BillingStatus'UnrecognizedValue (Prelude.fromIntegral k)))
+        showEnum Bill'UN_PAID = "UN_PAID"
+        showEnum Bill'PAID = "PAID"
+        showEnum
+          (Bill'BillingStatus'Unrecognized
+             (Bill'BillingStatus'UnrecognizedValue k))
+          = Prelude.show k
+        readEnum k
+          | (k) Prelude.== "UN_PAID" = Prelude.Just Bill'UN_PAID
+          | (k) Prelude.== "PAID" = Prelude.Just Bill'PAID
+        readEnum k
+          = (Text.Read.readMaybe k) Prelude.>>= Data.ProtoLens.maybeToEnum
+instance Prelude.Bounded Bill'BillingStatus where
+        minBound = Bill'UN_PAID
+        maxBound = Bill'PAID
+instance Prelude.Enum Bill'BillingStatus where
+        toEnum k__
+          = Prelude.maybe
+              (Prelude.error
+                 (("toEnum: unknown value for enum BillingStatus: ") Prelude.++
+                    Prelude.show k__))
+              Prelude.id
+              (Data.ProtoLens.maybeToEnum k__)
+        fromEnum Bill'UN_PAID = 0
+        fromEnum Bill'PAID = 1
+        fromEnum
+          (Bill'BillingStatus'Unrecognized
+             (Bill'BillingStatus'UnrecognizedValue k))
+          = Prelude.fromIntegral k
+        succ Bill'PAID
+          = Prelude.error
+              "Bill'BillingStatus.succ: bad argument Bill'PAID. This value would be out of bounds."
+        succ Bill'UN_PAID = Bill'PAID
+        succ (Bill'BillingStatus'Unrecognized _)
+          = Prelude.error
+              "Bill'BillingStatus.succ: bad argument: unrecognized value"
+        pred Bill'UN_PAID
+          = Prelude.error
+              "Bill'BillingStatus.pred: bad argument Bill'UN_PAID. This value would be out of bounds."
+        pred Bill'PAID = Bill'UN_PAID
+        pred (Bill'BillingStatus'Unrecognized _)
+          = Prelude.error
+              "Bill'BillingStatus.pred: bad argument: unrecognized value"
+        enumFrom = Data.ProtoLens.Message.Enum.messageEnumFrom
+        enumFromTo = Data.ProtoLens.Message.Enum.messageEnumFromTo
+        enumFromThen = Data.ProtoLens.Message.Enum.messageEnumFromThen
+        enumFromThenTo = Data.ProtoLens.Message.Enum.messageEnumFromThenTo
+instance Data.ProtoLens.FieldDefault Bill'BillingStatus where
+        fieldDefault = Bill'UN_PAID
+instance Control.DeepSeq.NFData Bill'BillingStatus where
+        rnf x__ = Prelude.seq x__ (())
+newtype ChangeType'UnrecognizedValue = ChangeType'UnrecognizedValue Data.Int.Int32
+                                         deriving (Prelude.Eq, Prelude.Ord, Prelude.Show)
+data ChangeType = ADDED
+                | REMOVED
+                | ChangeType'Unrecognized !ChangeType'UnrecognizedValue
+                    deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
+instance Data.ProtoLens.MessageEnum ChangeType where
+        maybeToEnum 0 = Prelude.Just ADDED
+        maybeToEnum 1 = Prelude.Just REMOVED
+        maybeToEnum k
+          = Prelude.Just
+              (ChangeType'Unrecognized
+                 (ChangeType'UnrecognizedValue (Prelude.fromIntegral k)))
+        showEnum ADDED = "ADDED"
+        showEnum REMOVED = "REMOVED"
+        showEnum (ChangeType'Unrecognized (ChangeType'UnrecognizedValue k))
+          = Prelude.show k
+        readEnum k
+          | (k) Prelude.== "ADDED" = Prelude.Just ADDED
+          | (k) Prelude.== "REMOVED" = Prelude.Just REMOVED
+        readEnum k
+          = (Text.Read.readMaybe k) Prelude.>>= Data.ProtoLens.maybeToEnum
+instance Prelude.Bounded ChangeType where
+        minBound = ADDED
+        maxBound = REMOVED
+instance Prelude.Enum ChangeType where
+        toEnum k__
+          = Prelude.maybe
+              (Prelude.error
+                 (("toEnum: unknown value for enum ChangeType: ") Prelude.++
+                    Prelude.show k__))
+              Prelude.id
+              (Data.ProtoLens.maybeToEnum k__)
+        fromEnum ADDED = 0
+        fromEnum REMOVED = 1
+        fromEnum (ChangeType'Unrecognized (ChangeType'UnrecognizedValue k))
+          = Prelude.fromIntegral k
+        succ REMOVED
+          = Prelude.error
+              "ChangeType.succ: bad argument REMOVED. This value would be out of bounds."
+        succ ADDED = REMOVED
+        succ (ChangeType'Unrecognized _)
+          = Prelude.error "ChangeType.succ: bad argument: unrecognized value"
+        pred ADDED
+          = Prelude.error
+              "ChangeType.pred: bad argument ADDED. This value would be out of bounds."
+        pred REMOVED = ADDED
+        pred (ChangeType'Unrecognized _)
+          = Prelude.error "ChangeType.pred: bad argument: unrecognized value"
+        enumFrom = Data.ProtoLens.Message.Enum.messageEnumFrom
+        enumFromTo = Data.ProtoLens.Message.Enum.messageEnumFromTo
+        enumFromThen = Data.ProtoLens.Message.Enum.messageEnumFromThen
+        enumFromThenTo = Data.ProtoLens.Message.Enum.messageEnumFromThenTo
+instance Data.ProtoLens.FieldDefault ChangeType where
+        fieldDefault = ADDED
+instance Control.DeepSeq.NFData ChangeType where
+        rnf x__ = Prelude.seq x__ (())
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.term' @:: Lens' DeletedTerm Data.Text.Text@
+ -}
+data DeletedTerm = DeletedTerm{_DeletedTerm'term ::
+                               !Data.Text.Text,
+                               _DeletedTerm'_unknownFields :: !Data.ProtoLens.FieldSet}
+                     deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show DeletedTerm where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField DeletedTerm "term"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DeletedTerm'term
+               (\ x__ y__ -> x__{_DeletedTerm'term = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message DeletedTerm where
+        messageName _ = Data.Text.pack "example.haberdasher.DeletedTerm"
+        fieldsByTag
+          = let term__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "term"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"term"))
+                      :: Data.ProtoLens.FieldDescriptor DeletedTerm
+              in
+              Data.Map.fromList [(Data.ProtoLens.Tag 1, term__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _DeletedTerm'_unknownFields
+              (\ x__ y__ -> x__{_DeletedTerm'_unknownFields = y__})
+        defMessage
+          = DeletedTerm{_DeletedTerm'term = Data.ProtoLens.fieldDefault,
+                        _DeletedTerm'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     DeletedTerm -> Data.ProtoLens.Encoding.Bytes.Parser DeletedTerm
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                10 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "term"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"term") y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "DeletedTerm"
+        buildMessage
+          = (\ _x ->
+               (let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"term") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 10) Data.Monoid.<>
+                      (((\ bs ->
+                           (Data.ProtoLens.Encoding.Bytes.putVarInt
+                              (Prelude.fromIntegral (Data.ByteString.length bs)))
+                             Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                         Prelude.. Data.Text.Encoding.encodeUtf8)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData DeletedTerm where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_DeletedTerm'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_DeletedTerm'term x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.changeType' @:: Lens' Demo ChangeType@
+ -}
+data Demo = Demo{_Demo'changeType :: !ChangeType,
+                 _Demo'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Demo where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Demo "changeType"
+           (ChangeType)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Demo'changeType
+               (\ x__ y__ -> x__{_Demo'changeType = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Demo where
+        messageName _ = Data.Text.pack "example.haberdasher.Demo"
+        fieldsByTag
+          = let changeType__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "change_type"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::
+                         Data.ProtoLens.FieldTypeDescriptor ChangeType)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"changeType"))
+                      :: Data.ProtoLens.FieldDescriptor Demo
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, changeType__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Demo'_unknownFields
+              (\ x__ y__ -> x__{_Demo'_unknownFields = y__})
+        defMessage
+          = Demo{_Demo'changeType = Data.ProtoLens.fieldDefault,
+                 _Demo'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Demo -> Data.ProtoLens.Encoding.Bytes.Parser Demo
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do y <- (Prelude.fmap Prelude.toEnum
+                                                (Prelude.fmap Prelude.fromIntegral
+                                                   Data.ProtoLens.Encoding.Bytes.getVarInt))
+                                               Data.ProtoLens.Encoding.Bytes.<?> "change_type"
+                                        loop
+                                          (Lens.Family2.set
+                                             (Data.ProtoLens.Field.field @"changeType")
+                                             y
+                                             x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Demo"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"changeType") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 8) Data.Monoid.<>
+                      (((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                          Prelude.fromIntegral)
+                         Prelude.. Prelude.fromEnum)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Demo where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Demo'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Demo'changeType x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.diffVertexId' @:: Lens' DiffTreeVertex Data.Int.Int32@
+    * 'Proto.Haberdasher_Fields.maybe'diffTerm' @:: Lens' DiffTreeVertex (Prelude.Maybe DiffTreeVertex'DiffTerm)@
+    * 'Proto.Haberdasher_Fields.maybe'deleted' @:: Lens' DiffTreeVertex (Prelude.Maybe DeletedTerm)@
+    * 'Proto.Haberdasher_Fields.deleted' @:: Lens' DiffTreeVertex DeletedTerm@
+    * 'Proto.Haberdasher_Fields.maybe'inserted' @:: Lens' DiffTreeVertex (Prelude.Maybe InsertedTerm)@
+    * 'Proto.Haberdasher_Fields.inserted' @:: Lens' DiffTreeVertex InsertedTerm@
+ -}
+data DiffTreeVertex = DiffTreeVertex{_DiffTreeVertex'diffVertexId
+                                     :: !Data.Int.Int32,
+                                     _DiffTreeVertex'diffTerm ::
+                                     !(Prelude.Maybe DiffTreeVertex'DiffTerm),
+                                     _DiffTreeVertex'_unknownFields :: !Data.ProtoLens.FieldSet}
+                        deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show DiffTreeVertex where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+data DiffTreeVertex'DiffTerm = DiffTreeVertex'Deleted !DeletedTerm
+                             | DiffTreeVertex'Inserted !InsertedTerm
+                                 deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
+instance Data.ProtoLens.Field.HasField DiffTreeVertex
+           "diffVertexId"
+           (Data.Int.Int32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffVertexId
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffVertexId = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField DiffTreeVertex
+           "maybe'diffTerm"
+           (Prelude.Maybe DiffTreeVertex'DiffTerm)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffTerm
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffTerm = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField DiffTreeVertex
+           "maybe'deleted"
+           (Prelude.Maybe DeletedTerm)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffTerm
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffTerm = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (DiffTreeVertex'Deleted x__val) -> Prelude.Just x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap DiffTreeVertex'Deleted y__)
+instance Data.ProtoLens.Field.HasField DiffTreeVertex "deleted"
+           (DeletedTerm)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffTerm
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffTerm = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (DiffTreeVertex'Deleted x__val) -> Prelude.Just x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap DiffTreeVertex'Deleted y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.defMessage
+instance Data.ProtoLens.Field.HasField DiffTreeVertex
+           "maybe'inserted"
+           (Prelude.Maybe InsertedTerm)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffTerm
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffTerm = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (DiffTreeVertex'Inserted x__val) -> Prelude.Just
+                                                                          x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap DiffTreeVertex'Inserted y__)
+instance Data.ProtoLens.Field.HasField DiffTreeVertex "inserted"
+           (InsertedTerm)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _DiffTreeVertex'diffTerm
+               (\ x__ y__ -> x__{_DiffTreeVertex'diffTerm = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (DiffTreeVertex'Inserted x__val) -> Prelude.Just
+                                                                           x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap DiffTreeVertex'Inserted y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.defMessage
+instance Data.ProtoLens.Message DiffTreeVertex where
+        messageName _ = Data.Text.pack "example.haberdasher.DiffTreeVertex"
+        fieldsByTag
+          = let diffVertexId__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "diff_vertex_id"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"diffVertexId"))
+                      :: Data.ProtoLens.FieldDescriptor DiffTreeVertex
+                deleted__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "deleted"
+                      (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::
+                         Data.ProtoLens.FieldTypeDescriptor DeletedTerm)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'deleted"))
+                      :: Data.ProtoLens.FieldDescriptor DiffTreeVertex
+                inserted__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "inserted"
+                      (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::
+                         Data.ProtoLens.FieldTypeDescriptor InsertedTerm)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'inserted"))
+                      :: Data.ProtoLens.FieldDescriptor DiffTreeVertex
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, diffVertexId__field_descriptor),
+                 (Data.ProtoLens.Tag 2, deleted__field_descriptor),
+                 (Data.ProtoLens.Tag 3, inserted__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _DiffTreeVertex'_unknownFields
+              (\ x__ y__ -> x__{_DiffTreeVertex'_unknownFields = y__})
+        defMessage
+          = DiffTreeVertex{_DiffTreeVertex'diffVertexId =
+                             Data.ProtoLens.fieldDefault,
+                           _DiffTreeVertex'diffTerm = Prelude.Nothing,
+                           _DiffTreeVertex'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     DiffTreeVertex ->
+                       Data.ProtoLens.Encoding.Bytes.Parser DiffTreeVertex
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                               Data.ProtoLens.Encoding.Bytes.<?> "diff_vertex_id"
+                                        loop
+                                          (Lens.Family2.set
+                                             (Data.ProtoLens.Field.field @"diffVertexId")
+                                             y
+                                             x)
+                                18 -> do y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                  Data.ProtoLens.Encoding.Bytes.isolate
+                                                    (Prelude.fromIntegral len)
+                                                    Data.ProtoLens.parseMessage)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "deleted"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"deleted")
+                                              y
+                                              x)
+                                26 -> do y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                  Data.ProtoLens.Encoding.Bytes.isolate
+                                                    (Prelude.fromIntegral len)
+                                                    Data.ProtoLens.parseMessage)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "inserted"
+                                         loop
+                                           (Lens.Family2.set
+                                              (Data.ProtoLens.Field.field @"inserted")
+                                              y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "DiffTreeVertex"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"diffVertexId") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 8) Data.Monoid.<>
+                      ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                         Prelude.fromIntegral)
+                        _v)
+                 Data.Monoid.<>
+                 (case
+                    Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'diffTerm") _x
+                    of
+                      (Prelude.Nothing) -> Data.Monoid.mempty
+                      Prelude.Just
+                        (DiffTreeVertex'Deleted
+                           v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt 18) Data.Monoid.<>
+                                   (((\ bs ->
+                                        (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                           (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                          Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                                      Prelude.. Data.ProtoLens.encodeMessage)
+                                     v
+                      Prelude.Just
+                        (DiffTreeVertex'Inserted
+                           v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt 26) Data.Monoid.<>
+                                   (((\ bs ->
+                                        (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                           (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                          Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                                      Prelude.. Data.ProtoLens.encodeMessage)
+                                     v)
+                   Data.Monoid.<>
+                   Data.ProtoLens.Encoding.Wire.buildFieldSet
+                     (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData DiffTreeVertex where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_DiffTreeVertex'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_DiffTreeVertex'diffVertexId x__)
+                    (Control.DeepSeq.deepseq (_DiffTreeVertex'diffTerm x__) (()))))
+instance Control.DeepSeq.NFData DiffTreeVertex'DiffTerm where
+        rnf (DiffTreeVertex'Deleted x__) = Control.DeepSeq.rnf x__
+        rnf (DiffTreeVertex'Inserted x__) = Control.DeepSeq.rnf x__
+_DiffTreeVertex'Deleted ::
+                        Data.ProtoLens.Prism.Prism' DiffTreeVertex'DiffTerm DeletedTerm
+_DiffTreeVertex'Deleted
+  = Data.ProtoLens.Prism.prism' DiffTreeVertex'Deleted
+      (\ p__ ->
+         case p__ of
+             DiffTreeVertex'Deleted p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+_DiffTreeVertex'Inserted ::
+                         Data.ProtoLens.Prism.Prism' DiffTreeVertex'DiffTerm InsertedTerm
+_DiffTreeVertex'Inserted
+  = Data.ProtoLens.Prism.prism' DiffTreeVertex'Inserted
+      (\ p__ ->
+         case p__ of
+             DiffTreeVertex'Inserted p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+{- | Fields :
+
+ -}
+data EmptyMessage = EmptyMessage{_EmptyMessage'_unknownFields ::
+                                 !Data.ProtoLens.FieldSet}
+                      deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show EmptyMessage where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Message EmptyMessage where
+        messageName _ = Data.Text.pack "example.haberdasher.EmptyMessage"
+        fieldsByTag = let in Data.Map.fromList []
+        unknownFields
+          = Lens.Family2.Unchecked.lens _EmptyMessage'_unknownFields
+              (\ x__ y__ -> x__{_EmptyMessage'_unknownFields = y__})
+        defMessage = EmptyMessage{_EmptyMessage'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     EmptyMessage -> Data.ProtoLens.Encoding.Bytes.Parser EmptyMessage
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "EmptyMessage"
+        buildMessage
+          = (\ _x ->
+               Data.ProtoLens.Encoding.Wire.buildFieldSet
+                 (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData EmptyMessage where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_EmptyMessage'_unknownFields x__) (()))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.testBytes' @:: Lens' FieldTestMessage Data.ByteString.ByteString@
+ -}
+data FieldTestMessage = FieldTestMessage{_FieldTestMessage'testBytes
+                                         :: !Data.ByteString.ByteString,
+                                         _FieldTestMessage'_unknownFields ::
+                                         !Data.ProtoLens.FieldSet}
+                          deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show FieldTestMessage where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField FieldTestMessage "testBytes"
+           (Data.ByteString.ByteString)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _FieldTestMessage'testBytes
+               (\ x__ y__ -> x__{_FieldTestMessage'testBytes = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message FieldTestMessage where
+        messageName _
+          = Data.Text.pack "example.haberdasher.FieldTestMessage"
+        fieldsByTag
+          = let testBytes__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "test_bytes"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"testBytes"))
+                      :: Data.ProtoLens.FieldDescriptor FieldTestMessage
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 3, testBytes__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _FieldTestMessage'_unknownFields
+              (\ x__ y__ -> x__{_FieldTestMessage'_unknownFields = y__})
+        defMessage
+          = FieldTestMessage{_FieldTestMessage'testBytes =
+                               Data.ProtoLens.fieldDefault,
+                             _FieldTestMessage'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     FieldTestMessage ->
+                       Data.ProtoLens.Encoding.Bytes.Parser FieldTestMessage
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                26 -> do y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                  Data.ProtoLens.Encoding.Bytes.getBytes
+                                                    (Prelude.fromIntegral len))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "test_bytes"
+                                         loop
+                                           (Lens.Family2.set
+                                              (Data.ProtoLens.Field.field @"testBytes")
+                                              y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "FieldTestMessage"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"testBytes") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 26) Data.Monoid.<>
+                      (\ bs ->
+                         (Data.ProtoLens.Encoding.Bytes.putVarInt
+                            (Prelude.fromIntegral (Data.ByteString.length bs)))
+                           Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData FieldTestMessage where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_FieldTestMessage'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_FieldTestMessage'testBytes x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.inches' @:: Lens' Hat Data.Int.Int32@
+    * 'Proto.Haberdasher_Fields.color' @:: Lens' Hat Data.Text.Text@
+    * 'Proto.Haberdasher_Fields.name' @:: Lens' Hat Data.Text.Text@
+ -}
+data Hat = Hat{_Hat'inches :: !Data.Int.Int32,
+               _Hat'color :: !Data.Text.Text, _Hat'name :: !Data.Text.Text,
+               _Hat'_unknownFields :: !Data.ProtoLens.FieldSet}
+             deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Hat where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Hat "inches"
+           (Data.Int.Int32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Hat'inches
+               (\ x__ y__ -> x__{_Hat'inches = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Hat "color" (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Hat'color
+               (\ x__ y__ -> x__{_Hat'color = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Hat "name" (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Hat'name
+               (\ x__ y__ -> x__{_Hat'name = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Hat where
+        messageName _ = Data.Text.pack "example.haberdasher.Hat"
+        fieldsByTag
+          = let inches__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "inches"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"inches"))
+                      :: Data.ProtoLens.FieldDescriptor Hat
+                color__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "color"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"color"))
+                      :: Data.ProtoLens.FieldDescriptor Hat
+                name__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "name"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"name"))
+                      :: Data.ProtoLens.FieldDescriptor Hat
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, inches__field_descriptor),
+                 (Data.ProtoLens.Tag 2, color__field_descriptor),
+                 (Data.ProtoLens.Tag 3, name__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Hat'_unknownFields
+              (\ x__ y__ -> x__{_Hat'_unknownFields = y__})
+        defMessage
+          = Hat{_Hat'inches = Data.ProtoLens.fieldDefault,
+                _Hat'color = Data.ProtoLens.fieldDefault,
+                _Hat'name = Data.ProtoLens.fieldDefault,
+                _Hat'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Hat -> Data.ProtoLens.Encoding.Bytes.Parser Hat
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                               Data.ProtoLens.Encoding.Bytes.<?> "inches"
+                                        loop
+                                          (Lens.Family2.set (Data.ProtoLens.Field.field @"inches") y
+                                             x)
+                                18 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "color"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"color") y
+                                              x)
+                                26 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "name"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"name") y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Hat"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"inches") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 8) Data.Monoid.<>
+                      ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                         Prelude.fromIntegral)
+                        _v)
+                 Data.Monoid.<>
+                 (let _v
+                        = Lens.Family2.view (Data.ProtoLens.Field.field @"color") _x
+                    in
+                    if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                      Data.Monoid.mempty else
+                      (Data.ProtoLens.Encoding.Bytes.putVarInt 18) Data.Monoid.<>
+                        (((\ bs ->
+                             (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                (Prelude.fromIntegral (Data.ByteString.length bs)))
+                               Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                           Prelude.. Data.Text.Encoding.encodeUtf8)
+                          _v)
+                   Data.Monoid.<>
+                   (let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"name") _x
+                      in
+                      if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                        Data.Monoid.mempty else
+                        (Data.ProtoLens.Encoding.Bytes.putVarInt 26) Data.Monoid.<>
+                          (((\ bs ->
+                               (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                  (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                 Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                             Prelude.. Data.Text.Encoding.encodeUtf8)
+                            _v)
+                     Data.Monoid.<>
+                     Data.ProtoLens.Encoding.Wire.buildFieldSet
+                       (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Hat where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Hat'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Hat'inches x__)
+                    (Control.DeepSeq.deepseq (_Hat'color x__)
+                       (Control.DeepSeq.deepseq (_Hat'name x__) (())))))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.term' @:: Lens' InsertedTerm Data.Text.Text@
+ -}
+data InsertedTerm = InsertedTerm{_InsertedTerm'term ::
+                                 !Data.Text.Text,
+                                 _InsertedTerm'_unknownFields :: !Data.ProtoLens.FieldSet}
+                      deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show InsertedTerm where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField InsertedTerm "term"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _InsertedTerm'term
+               (\ x__ y__ -> x__{_InsertedTerm'term = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message InsertedTerm where
+        messageName _ = Data.Text.pack "example.haberdasher.InsertedTerm"
+        fieldsByTag
+          = let term__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "term"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"term"))
+                      :: Data.ProtoLens.FieldDescriptor InsertedTerm
+              in
+              Data.Map.fromList [(Data.ProtoLens.Tag 1, term__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _InsertedTerm'_unknownFields
+              (\ x__ y__ -> x__{_InsertedTerm'_unknownFields = y__})
+        defMessage
+          = InsertedTerm{_InsertedTerm'term = Data.ProtoLens.fieldDefault,
+                         _InsertedTerm'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     InsertedTerm -> Data.ProtoLens.Encoding.Bytes.Parser InsertedTerm
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                10 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "term"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"term") y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "InsertedTerm"
+        buildMessage
+          = (\ _x ->
+               (let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"term") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 10) Data.Monoid.<>
+                      (((\ bs ->
+                           (Data.ProtoLens.Encoding.Bytes.putVarInt
+                              (Prelude.fromIntegral (Data.ByteString.length bs)))
+                             Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                         Prelude.. Data.Text.Encoding.encodeUtf8)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData InsertedTerm where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_InsertedTerm'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_InsertedTerm'term x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.service' @:: Lens' Ping Data.Text.Text@
+ -}
+data Ping = Ping{_Ping'service :: !Data.Text.Text,
+                 _Ping'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Ping where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Ping "service"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Ping'service
+               (\ x__ y__ -> x__{_Ping'service = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Ping where
+        messageName _ = Data.Text.pack "example.haberdasher.Ping"
+        fieldsByTag
+          = let service__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "service"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"service"))
+                      :: Data.ProtoLens.FieldDescriptor Ping
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, service__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Ping'_unknownFields
+              (\ x__ y__ -> x__{_Ping'_unknownFields = y__})
+        defMessage
+          = Ping{_Ping'service = Data.ProtoLens.fieldDefault,
+                 _Ping'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Ping -> Data.ProtoLens.Encoding.Bytes.Parser Ping
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                10 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "service"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"service")
+                                              y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Ping"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"service") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 10) Data.Monoid.<>
+                      (((\ bs ->
+                           (Data.ProtoLens.Encoding.Bytes.putVarInt
+                              (Prelude.fromIntegral (Data.ByteString.length bs)))
+                             Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                         Prelude.. Data.Text.Encoding.encodeUtf8)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Ping where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Ping'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Ping'service x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.status' @:: Lens' Pong Data.Text.Text@
+    * 'Proto.Haberdasher_Fields.stuff' @:: Lens' Pong [Test]@
+    * 'Proto.Haberdasher_Fields.vec'stuff' @:: Lens' Pong (Data.Vector.Vector Test)@
+    * 'Proto.Haberdasher_Fields.id' @:: Lens' Pong Data.Int.Int32@
+    * 'Proto.Haberdasher_Fields.type'' @:: Lens' Pong Data.Text.Text@
+    * 'Proto.Haberdasher_Fields.maybe'extra' @:: Lens' Pong (Prelude.Maybe Pong'Extra)@
+    * 'Proto.Haberdasher_Fields.maybe't' @:: Lens' Pong (Prelude.Maybe Data.Word.Word32)@
+    * 'Proto.Haberdasher_Fields.t' @:: Lens' Pong Data.Word.Word32@
+    * 'Proto.Haberdasher_Fields.maybe'u' @:: Lens' Pong (Prelude.Maybe Data.Text.Text)@
+    * 'Proto.Haberdasher_Fields.u' @:: Lens' Pong Data.Text.Text@
+ -}
+data Pong = Pong{_Pong'status :: !Data.Text.Text,
+                 _Pong'stuff :: !(Data.Vector.Vector Test),
+                 _Pong'id :: !Data.Int.Int32, _Pong'type' :: !Data.Text.Text,
+                 _Pong'extra :: !(Prelude.Maybe Pong'Extra),
+                 _Pong'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Pong where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+data Pong'Extra = Pong'T !Data.Word.Word32
+                | Pong'U !Data.Text.Text
+                    deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)
+instance Data.ProtoLens.Field.HasField Pong "status"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'status
+               (\ x__ y__ -> x__{_Pong'status = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Pong "stuff" ([Test]) where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'stuff
+               (\ x__ y__ -> x__{_Pong'stuff = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens Data.Vector.Generic.toList
+                (\ _ y__ -> Data.Vector.Generic.fromList y__)
+instance Data.ProtoLens.Field.HasField Pong "vec'stuff"
+           (Data.Vector.Vector Test)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'stuff
+               (\ x__ y__ -> x__{_Pong'stuff = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Pong "id" (Data.Int.Int32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'id
+               (\ x__ y__ -> x__{_Pong'id = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Pong "type'"
+           (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'type'
+               (\ x__ y__ -> x__{_Pong'type' = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Pong "maybe'extra"
+           (Prelude.Maybe Pong'Extra)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'extra
+               (\ x__ y__ -> x__{_Pong'extra = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Pong "maybe't"
+           (Prelude.Maybe Data.Word.Word32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'extra
+               (\ x__ y__ -> x__{_Pong'extra = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (Pong'T x__val) -> Prelude.Just x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap Pong'T y__)
+instance Data.ProtoLens.Field.HasField Pong "t" (Data.Word.Word32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'extra
+               (\ x__ y__ -> x__{_Pong'extra = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (Pong'T x__val) -> Prelude.Just x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap Pong'T y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault
+instance Data.ProtoLens.Field.HasField Pong "maybe'u"
+           (Prelude.Maybe Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'extra
+               (\ x__ y__ -> x__{_Pong'extra = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens
+                (\ x__ ->
+                   case x__ of
+                       Prelude.Just (Pong'U x__val) -> Prelude.Just x__val
+                       _otherwise -> Prelude.Nothing)
+                (\ _ y__ -> Prelude.fmap Pong'U y__)
+instance Data.ProtoLens.Field.HasField Pong "u" (Data.Text.Text)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Pong'extra
+               (\ x__ y__ -> x__{_Pong'extra = y__}))
+              Prelude..
+              (Lens.Family2.Unchecked.lens
+                 (\ x__ ->
+                    case x__ of
+                        Prelude.Just (Pong'U x__val) -> Prelude.Just x__val
+                        _otherwise -> Prelude.Nothing)
+                 (\ _ y__ -> Prelude.fmap Pong'U y__))
+                Prelude.. Data.ProtoLens.maybeLens Data.ProtoLens.fieldDefault
+instance Data.ProtoLens.Message Pong where
+        messageName _ = Data.Text.pack "example.haberdasher.Pong"
+        fieldsByTag
+          = let status__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "status"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"status"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+                stuff__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "stuff"
+                      (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::
+                         Data.ProtoLens.FieldTypeDescriptor Test)
+                      (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked
+                         (Data.ProtoLens.Field.field @"stuff"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+                id__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "id"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"id"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+                type'__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "type"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"type'"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+                t__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "t"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.UInt32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Word.Word32)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe't"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+                u__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "u"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)
+                      (Data.ProtoLens.OptionalField
+                         (Data.ProtoLens.Field.field @"maybe'u"))
+                      :: Data.ProtoLens.FieldDescriptor Pong
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, status__field_descriptor),
+                 (Data.ProtoLens.Tag 2, stuff__field_descriptor),
+                 (Data.ProtoLens.Tag 5, id__field_descriptor),
+                 (Data.ProtoLens.Tag 6, type'__field_descriptor),
+                 (Data.ProtoLens.Tag 3, t__field_descriptor),
+                 (Data.ProtoLens.Tag 4, u__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Pong'_unknownFields
+              (\ x__ y__ -> x__{_Pong'_unknownFields = y__})
+        defMessage
+          = Pong{_Pong'status = Data.ProtoLens.fieldDefault,
+                 _Pong'stuff = Data.Vector.Generic.empty,
+                 _Pong'id = Data.ProtoLens.fieldDefault,
+                 _Pong'type' = Data.ProtoLens.fieldDefault,
+                 _Pong'extra = Prelude.Nothing, _Pong'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     Pong ->
+                       Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector
+                         Data.ProtoLens.Encoding.Growing.RealWorld
+                         Test
+                         -> Data.ProtoLens.Encoding.Bytes.Parser Pong
+                loop x mutable'stuff
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do frozen'stuff <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                              (Data.ProtoLens.Encoding.Growing.unsafeFreeze
+                                                 mutable'stuff)
+                            let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 (Lens.Family2.set (Data.ProtoLens.Field.field @"vec'stuff")
+                                    frozen'stuff
+                                    x))
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                10 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "status"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"status")
+                                              y
+                                              x)
+                                           mutable'stuff
+                                18 -> do !y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                   Data.ProtoLens.Encoding.Bytes.isolate
+                                                     (Prelude.fromIntegral len)
+                                                     Data.ProtoLens.parseMessage)
+                                                 Data.ProtoLens.Encoding.Bytes.<?> "stuff"
+                                         v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                                (Data.ProtoLens.Encoding.Growing.append
+                                                   mutable'stuff
+                                                   y)
+                                         loop x v
+                                40 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                 Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "id"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"id") y x)
+                                           mutable'stuff
+                                50 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "type"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"type'") y
+                                              x)
+                                           mutable'stuff
+                                24 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                 Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "t"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"t") y x)
+                                           mutable'stuff
+                                34 -> do y <- (do value <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                              Data.ProtoLens.Encoding.Bytes.getBytes
+                                                                (Prelude.fromIntegral len)
+                                                  Data.ProtoLens.Encoding.Bytes.runEither
+                                                    (case Data.Text.Encoding.decodeUtf8' value of
+                                                         Prelude.Left err -> Prelude.Left
+                                                                               (Prelude.show err)
+                                                         Prelude.Right r -> Prelude.Right r))
+                                                Data.ProtoLens.Encoding.Bytes.<?> "u"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"u") y x)
+                                           mutable'stuff
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+                                             mutable'stuff
+              in
+              (do mutable'stuff <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                     Data.ProtoLens.Encoding.Growing.new
+                  loop Data.ProtoLens.defMessage mutable'stuff)
+                Data.ProtoLens.Encoding.Bytes.<?> "Pong"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"status") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 10) Data.Monoid.<>
+                      (((\ bs ->
+                           (Data.ProtoLens.Encoding.Bytes.putVarInt
+                              (Prelude.fromIntegral (Data.ByteString.length bs)))
+                             Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                         Prelude.. Data.Text.Encoding.encodeUtf8)
+                        _v)
+                 Data.Monoid.<>
+                 (Data.ProtoLens.Encoding.Bytes.foldMapBuilder
+                    (\ _v ->
+                       (Data.ProtoLens.Encoding.Bytes.putVarInt 18) Data.Monoid.<>
+                         (((\ bs ->
+                              (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                 (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                            Prelude.. Data.ProtoLens.encodeMessage)
+                           _v)
+                    (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'stuff") _x))
+                   Data.Monoid.<>
+                   (let _v = Lens.Family2.view (Data.ProtoLens.Field.field @"id") _x
+                      in
+                      if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                        Data.Monoid.mempty else
+                        (Data.ProtoLens.Encoding.Bytes.putVarInt 40) Data.Monoid.<>
+                          ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                             Prelude.fromIntegral)
+                            _v)
+                     Data.Monoid.<>
+                     (let _v
+                            = Lens.Family2.view (Data.ProtoLens.Field.field @"type'") _x
+                        in
+                        if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                          Data.Monoid.mempty else
+                          (Data.ProtoLens.Encoding.Bytes.putVarInt 50) Data.Monoid.<>
+                            (((\ bs ->
+                                 (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                    (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                   Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                               Prelude.. Data.Text.Encoding.encodeUtf8)
+                              _v)
+                       Data.Monoid.<>
+                       (case
+                          Lens.Family2.view (Data.ProtoLens.Field.field @"maybe'extra") _x of
+                            (Prelude.Nothing) -> Data.Monoid.mempty
+                            Prelude.Just (Pong'T v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                          24)
+                                                         Data.Monoid.<>
+                                                         ((Data.ProtoLens.Encoding.Bytes.putVarInt)
+                                                            Prelude.. Prelude.fromIntegral)
+                                                           v
+                            Prelude.Just (Pong'U v) -> (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                          34)
+                                                         Data.Monoid.<>
+                                                         (((\ bs ->
+                                                              (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                                                 (Prelude.fromIntegral
+                                                                    (Data.ByteString.length bs)))
+                                                                Data.Monoid.<>
+                                                                Data.ProtoLens.Encoding.Bytes.putBytes
+                                                                  bs))
+                                                            Prelude.. Data.Text.Encoding.encodeUtf8)
+                                                           v)
+                         Data.Monoid.<>
+                         Data.ProtoLens.Encoding.Wire.buildFieldSet
+                           (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Pong where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Pong'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Pong'status x__)
+                    (Control.DeepSeq.deepseq (_Pong'stuff x__)
+                       (Control.DeepSeq.deepseq (_Pong'id x__)
+                          (Control.DeepSeq.deepseq (_Pong'type' x__)
+                             (Control.DeepSeq.deepseq (_Pong'extra x__) (())))))))
+instance Control.DeepSeq.NFData Pong'Extra where
+        rnf (Pong'T x__) = Control.DeepSeq.rnf x__
+        rnf (Pong'U x__) = Control.DeepSeq.rnf x__
+_Pong'T :: Data.ProtoLens.Prism.Prism' Pong'Extra Data.Word.Word32
+_Pong'T
+  = Data.ProtoLens.Prism.prism' Pong'T
+      (\ p__ ->
+         case p__ of
+             Pong'T p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+_Pong'U :: Data.ProtoLens.Prism.Prism' Pong'Extra Data.Text.Text
+_Pong'U
+  = Data.ProtoLens.Prism.prism' Pong'U
+      (\ p__ ->
+         case p__ of
+             Pong'U p__val -> Prelude.Just p__val
+             _otherwise -> Prelude.Nothing)
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.dollars' @:: Lens' Price Data.Word.Word32@
+    * 'Proto.Haberdasher_Fields.cents' @:: Lens' Price Data.Word.Word32@
+ -}
+data Price = Price{_Price'dollars :: !Data.Word.Word32,
+                   _Price'cents :: !Data.Word.Word32,
+                   _Price'_unknownFields :: !Data.ProtoLens.FieldSet}
+               deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Price where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Price "dollars"
+           (Data.Word.Word32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Price'dollars
+               (\ x__ y__ -> x__{_Price'dollars = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Price "cents"
+           (Data.Word.Word32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Price'cents
+               (\ x__ y__ -> x__{_Price'cents = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Price where
+        messageName _ = Data.Text.pack "example.haberdasher.Price"
+        fieldsByTag
+          = let dollars__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "dollars"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.UInt32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Word.Word32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"dollars"))
+                      :: Data.ProtoLens.FieldDescriptor Price
+                cents__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "cents"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.UInt32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Word.Word32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"cents"))
+                      :: Data.ProtoLens.FieldDescriptor Price
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, dollars__field_descriptor),
+                 (Data.ProtoLens.Tag 2, cents__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Price'_unknownFields
+              (\ x__ y__ -> x__{_Price'_unknownFields = y__})
+        defMessage
+          = Price{_Price'dollars = Data.ProtoLens.fieldDefault,
+                  _Price'cents = Data.ProtoLens.fieldDefault,
+                  _Price'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Price -> Data.ProtoLens.Encoding.Bytes.Parser Price
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                               Data.ProtoLens.Encoding.Bytes.<?> "dollars"
+                                        loop
+                                          (Lens.Family2.set (Data.ProtoLens.Field.field @"dollars")
+                                             y
+                                             x)
+                                16 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                 Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "cents"
+                                         loop
+                                           (Lens.Family2.set (Data.ProtoLens.Field.field @"cents") y
+                                              x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Price"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"dollars") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 8) Data.Monoid.<>
+                      ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                         Prelude.fromIntegral)
+                        _v)
+                 Data.Monoid.<>
+                 (let _v
+                        = Lens.Family2.view (Data.ProtoLens.Field.field @"cents") _x
+                    in
+                    if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                      Data.Monoid.mempty else
+                      (Data.ProtoLens.Encoding.Bytes.putVarInt 16) Data.Monoid.<>
+                        ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                           Prelude.fromIntegral)
+                          _v)
+                   Data.Monoid.<>
+                   Data.ProtoLens.Encoding.Wire.buildFieldSet
+                     (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Price where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Price'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Price'dollars x__)
+                    (Control.DeepSeq.deepseq (_Price'cents x__) (()))))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.inches' @:: Lens' Size Data.Int.Int32@
+ -}
+data Size = Size{_Size'inches :: !Data.Int.Int32,
+                 _Size'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Size where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Size "inches"
+           (Data.Int.Int32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Size'inches
+               (\ x__ y__ -> x__{_Size'inches = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Size where
+        messageName _ = Data.Text.pack "example.haberdasher.Size"
+        fieldsByTag
+          = let inches__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "inches"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)
+                      (Data.ProtoLens.PlainField Data.ProtoLens.Optional
+                         (Data.ProtoLens.Field.field @"inches"))
+                      :: Data.ProtoLens.FieldDescriptor Size
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, inches__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Size'_unknownFields
+              (\ x__ y__ -> x__{_Size'_unknownFields = y__})
+        defMessage
+          = Size{_Size'inches = Data.ProtoLens.fieldDefault,
+                 _Size'_unknownFields = ([])}
+        parseMessage
+          = let loop :: Size -> Data.ProtoLens.Encoding.Bytes.Parser Size
+                loop x
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 x)
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do y <- (Prelude.fmap Prelude.fromIntegral
+                                                Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                               Data.ProtoLens.Encoding.Bytes.<?> "inches"
+                                        loop
+                                          (Lens.Family2.set (Data.ProtoLens.Field.field @"inches") y
+                                             x)
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+              in
+              (do loop Data.ProtoLens.defMessage)
+                Data.ProtoLens.Encoding.Bytes.<?> "Size"
+        buildMessage
+          = (\ _x ->
+               (let _v
+                      = Lens.Family2.view (Data.ProtoLens.Field.field @"inches") _x
+                  in
+                  if (_v) Prelude.== Data.ProtoLens.fieldDefault then
+                    Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 8) Data.Monoid.<>
+                      ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                         Prelude.fromIntegral)
+                        _v)
+                 Data.Monoid.<>
+                 Data.ProtoLens.Encoding.Wire.buildFieldSet
+                   (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Size where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Size'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Size'inches x__) (())))
+{- | Fields :
+
+    * 'Proto.Haberdasher_Fields.items' @:: Lens' Test [Data.Int.Int32]@
+    * 'Proto.Haberdasher_Fields.vec'items' @:: Lens' Test (Data.Vector.Unboxed.Vector Data.Int.Int32)@
+    * 'Proto.Haberdasher_Fields.altPrices' @:: Lens' Test [Price]@
+    * 'Proto.Haberdasher_Fields.vec'altPrices' @:: Lens' Test (Data.Vector.Vector Price)@
+ -}
+data Test = Test{_Test'items ::
+                 !(Data.Vector.Unboxed.Vector Data.Int.Int32),
+                 _Test'altPrices :: !(Data.Vector.Vector Price),
+                 _Test'_unknownFields :: !Data.ProtoLens.FieldSet}
+              deriving (Prelude.Eq, Prelude.Ord)
+instance Prelude.Show Test where
+        showsPrec _ __x __s
+          = Prelude.showChar '{'
+              (Prelude.showString (Data.ProtoLens.showMessageShort __x)
+                 (Prelude.showChar '}' __s))
+instance Data.ProtoLens.Field.HasField Test "items"
+           ([Data.Int.Int32])
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Test'items
+               (\ x__ y__ -> x__{_Test'items = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens Data.Vector.Generic.toList
+                (\ _ y__ -> Data.Vector.Generic.fromList y__)
+instance Data.ProtoLens.Field.HasField Test "vec'items"
+           (Data.Vector.Unboxed.Vector Data.Int.Int32)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Test'items
+               (\ x__ y__ -> x__{_Test'items = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Field.HasField Test "altPrices" ([Price])
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Test'altPrices
+               (\ x__ y__ -> x__{_Test'altPrices = y__}))
+              Prelude..
+              Lens.Family2.Unchecked.lens Data.Vector.Generic.toList
+                (\ _ y__ -> Data.Vector.Generic.fromList y__)
+instance Data.ProtoLens.Field.HasField Test "vec'altPrices"
+           (Data.Vector.Vector Price)
+         where
+        fieldOf _
+          = (Lens.Family2.Unchecked.lens _Test'altPrices
+               (\ x__ y__ -> x__{_Test'altPrices = y__}))
+              Prelude.. Prelude.id
+instance Data.ProtoLens.Message Test where
+        messageName _ = Data.Text.pack "example.haberdasher.Test"
+        fieldsByTag
+          = let items__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "items"
+                      (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::
+                         Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)
+                      (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed
+                         (Data.ProtoLens.Field.field @"items"))
+                      :: Data.ProtoLens.FieldDescriptor Test
+                altPrices__field_descriptor
+                  = Data.ProtoLens.FieldDescriptor "alt_prices"
+                      (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::
+                         Data.ProtoLens.FieldTypeDescriptor Price)
+                      (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked
+                         (Data.ProtoLens.Field.field @"altPrices"))
+                      :: Data.ProtoLens.FieldDescriptor Test
+              in
+              Data.Map.fromList
+                [(Data.ProtoLens.Tag 1, items__field_descriptor),
+                 (Data.ProtoLens.Tag 2, altPrices__field_descriptor)]
+        unknownFields
+          = Lens.Family2.Unchecked.lens _Test'_unknownFields
+              (\ x__ y__ -> x__{_Test'_unknownFields = y__})
+        defMessage
+          = Test{_Test'items = Data.Vector.Generic.empty,
+                 _Test'altPrices = Data.Vector.Generic.empty,
+                 _Test'_unknownFields = ([])}
+        parseMessage
+          = let loop ::
+                     Test ->
+                       Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Vector
+                         Data.ProtoLens.Encoding.Growing.RealWorld
+                         Price
+                         ->
+                         Data.ProtoLens.Encoding.Growing.Growing Data.Vector.Unboxed.Vector
+                           Data.ProtoLens.Encoding.Growing.RealWorld
+                           Data.Int.Int32
+                           -> Data.ProtoLens.Encoding.Bytes.Parser Test
+                loop x mutable'altPrices mutable'items
+                  = do end <- Data.ProtoLens.Encoding.Bytes.atEnd
+                       if end then
+                         do frozen'altPrices <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                                  (Data.ProtoLens.Encoding.Growing.unsafeFreeze
+                                                     mutable'altPrices)
+                            frozen'items <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                              (Data.ProtoLens.Encoding.Growing.unsafeFreeze
+                                                 mutable'items)
+                            let missing = [] in
+                              if Prelude.null missing then Prelude.return () else
+                                Prelude.fail
+                                  (("Missing required fields: ") Prelude.++
+                                     Prelude.show (missing :: ([Prelude.String])))
+                            Prelude.return
+                              (Lens.Family2.over Data.ProtoLens.unknownFields
+                                 (\ !t -> Prelude.reverse t)
+                                 (Lens.Family2.set (Data.ProtoLens.Field.field @"vec'altPrices")
+                                    frozen'altPrices
+                                    (Lens.Family2.set (Data.ProtoLens.Field.field @"vec'items")
+                                       frozen'items
+                                       x)))
+                         else
+                         do tag <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                            case tag of
+                                8 -> do !y <- (Prelude.fmap Prelude.fromIntegral
+                                                 Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                                Data.ProtoLens.Encoding.Bytes.<?> "items"
+                                        v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                               (Data.ProtoLens.Encoding.Growing.append mutable'items
+                                                  y)
+                                        loop x mutable'altPrices v
+                                10 -> do y <- do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                 Data.ProtoLens.Encoding.Bytes.isolate
+                                                   (Prelude.fromIntegral len)
+                                                   ((let ploop qs
+                                                           = do packedEnd <- Data.ProtoLens.Encoding.Bytes.atEnd
+                                                                if packedEnd then Prelude.return qs
+                                                                  else
+                                                                  do !q <- (Prelude.fmap
+                                                                              Prelude.fromIntegral
+                                                                              Data.ProtoLens.Encoding.Bytes.getVarInt)
+                                                                             Data.ProtoLens.Encoding.Bytes.<?>
+                                                                             "items"
+                                                                     qs' <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                                                              (Data.ProtoLens.Encoding.Growing.append
+                                                                                 qs
+                                                                                 q)
+                                                                     ploop qs'
+                                                       in ploop)
+                                                      mutable'items)
+                                         loop x mutable'altPrices y
+                                18 -> do !y <- (do len <- Data.ProtoLens.Encoding.Bytes.getVarInt
+                                                   Data.ProtoLens.Encoding.Bytes.isolate
+                                                     (Prelude.fromIntegral len)
+                                                     Data.ProtoLens.parseMessage)
+                                                 Data.ProtoLens.Encoding.Bytes.<?> "alt_prices"
+                                         v <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                                (Data.ProtoLens.Encoding.Growing.append
+                                                   mutable'altPrices
+                                                   y)
+                                         loop x v mutable'items
+                                wire -> do !y <- Data.ProtoLens.Encoding.Wire.parseTaggedValueFromWire
+                                                   wire
+                                           loop
+                                             (Lens.Family2.over Data.ProtoLens.unknownFields
+                                                (\ !t -> (:) y t)
+                                                x)
+                                             mutable'altPrices
+                                             mutable'items
+              in
+              (do mutable'altPrices <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                         Data.ProtoLens.Encoding.Growing.new
+                  mutable'items <- Data.ProtoLens.Encoding.Parser.Unsafe.unsafeLiftIO
+                                     Data.ProtoLens.Encoding.Growing.new
+                  loop Data.ProtoLens.defMessage mutable'altPrices mutable'items)
+                Data.ProtoLens.Encoding.Bytes.<?> "Test"
+        buildMessage
+          = (\ _x ->
+               (let p = Lens.Family2.view
+                          (Data.ProtoLens.Field.field @"vec'items")
+                          _x
+                  in
+                  if Data.Vector.Generic.null p then Data.Monoid.mempty else
+                    (Data.ProtoLens.Encoding.Bytes.putVarInt 10) Data.Monoid.<>
+                      (\ bs ->
+                         (Data.ProtoLens.Encoding.Bytes.putVarInt
+                            (Prelude.fromIntegral (Data.ByteString.length bs)))
+                           Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs)
+                        (Data.ProtoLens.Encoding.Bytes.runBuilder
+                           (Data.ProtoLens.Encoding.Bytes.foldMapBuilder
+                              ((Data.ProtoLens.Encoding.Bytes.putVarInt) Prelude..
+                                 Prelude.fromIntegral)
+                              p)))
+                 Data.Monoid.<>
+                 (Data.ProtoLens.Encoding.Bytes.foldMapBuilder
+                    (\ _v ->
+                       (Data.ProtoLens.Encoding.Bytes.putVarInt 18) Data.Monoid.<>
+                         (((\ bs ->
+                              (Data.ProtoLens.Encoding.Bytes.putVarInt
+                                 (Prelude.fromIntegral (Data.ByteString.length bs)))
+                                Data.Monoid.<> Data.ProtoLens.Encoding.Bytes.putBytes bs))
+                            Prelude.. Data.ProtoLens.encodeMessage)
+                           _v)
+                    (Lens.Family2.view (Data.ProtoLens.Field.field @"vec'altPrices")
+                       _x))
+                   Data.Monoid.<>
+                   Data.ProtoLens.Encoding.Wire.buildFieldSet
+                     (Lens.Family2.view Data.ProtoLens.unknownFields _x))
+instance Control.DeepSeq.NFData Test where
+        rnf
+          = (\ x__ ->
+               Control.DeepSeq.deepseq (_Test'_unknownFields x__)
+                 (Control.DeepSeq.deepseq (_Test'items x__)
+                    (Control.DeepSeq.deepseq (_Test'altPrices x__) (()))))
+data Haberdasher = Haberdasher{}
+                     deriving ()
+instance Data.ProtoLens.Service.Types.Service Haberdasher where
+        type ServiceName Haberdasher = "Haberdasher"
+        type ServicePackage Haberdasher = "example.haberdasher"
+        type ServiceMethods Haberdasher = '["getBill", "makeHat"]
+instance Data.ProtoLens.Service.Types.HasMethodImpl Haberdasher
+           "makeHat"
+         where
+        type MethodName Haberdasher "makeHat" = "MakeHat"
+        type MethodInput Haberdasher "makeHat" = Size
+        type MethodOutput Haberdasher "makeHat" = Hat
+        type MethodStreamingType Haberdasher "makeHat" =
+             'Data.ProtoLens.Service.Types.NonStreaming
+instance Data.ProtoLens.Service.Types.HasMethodImpl Haberdasher
+           "getBill"
+         where
+        type MethodName Haberdasher "getBill" = "GetBill"
+        type MethodInput Haberdasher "getBill" = Hat
+        type MethodOutput Haberdasher "getBill" = Bill
+        type MethodStreamingType Haberdasher "getBill" =
+             'Data.ProtoLens.Service.Types.NonStreaming
+data Health = Health{}
+                deriving ()
+instance Data.ProtoLens.Service.Types.Service Health where
+        type ServiceName Health = "Health"
+        type ServicePackage Health = "example.haberdasher"
+        type ServiceMethods Health = '["check"]
+instance Data.ProtoLens.Service.Types.HasMethodImpl Health "check"
+         where
+        type MethodName Health "check" = "Check"
+        type MethodInput Health "check" = Ping
+        type MethodOutput Health "check" = Pong
+        type MethodStreamingType Health "check" =
+             'Data.ProtoLens.Service.Types.NonStreaming
diff --git a/app/Proto/Haberdasher_Fields.hs b/app/Proto/Haberdasher_Fields.hs
new file mode 100644
--- /dev/null
+++ b/app/Proto/Haberdasher_Fields.hs
@@ -0,0 +1,243 @@
+{- This file was auto-generated from haberdasher.proto by the proto-lens-protoc program. -}
+{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies,
+  UndecidableInstances, GeneralizedNewtypeDeriving,
+  MultiParamTypeClasses, FlexibleContexts, FlexibleInstances,
+  PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds,
+  BangPatterns, TypeApplications #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports#-}
+{-# OPTIONS_GHC -fno-warn-duplicate-exports#-}
+module Proto.Haberdasher_Fields where
+import qualified Data.ProtoLens.Runtime.Prelude as Prelude
+import qualified Data.ProtoLens.Runtime.Data.Int as Data.Int
+import qualified Data.ProtoLens.Runtime.Data.Monoid as Data.Monoid
+import qualified Data.ProtoLens.Runtime.Data.Word as Data.Word
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens
+       as Data.ProtoLens
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Bytes
+       as Data.ProtoLens.Encoding.Bytes
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Growing
+       as Data.ProtoLens.Encoding.Growing
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Parser.Unsafe
+       as Data.ProtoLens.Encoding.Parser.Unsafe
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Encoding.Wire
+       as Data.ProtoLens.Encoding.Wire
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Field
+       as Data.ProtoLens.Field
+import qualified Data.ProtoLens.Runtime.Data.ProtoLens.Message.Enum
+       as Data.ProtoLens.Message.Enum
+import qualified
+       Data.ProtoLens.Runtime.Data.ProtoLens.Service.Types
+       as Data.ProtoLens.Service.Types
+import qualified Data.ProtoLens.Runtime.Lens.Family2
+       as Lens.Family2
+import qualified Data.ProtoLens.Runtime.Lens.Family2.Unchecked
+       as Lens.Family2.Unchecked
+import qualified Data.ProtoLens.Runtime.Data.Text as Data.Text
+import qualified Data.ProtoLens.Runtime.Data.Map as Data.Map
+import qualified Data.ProtoLens.Runtime.Data.ByteString
+       as Data.ByteString
+import qualified Data.ProtoLens.Runtime.Data.ByteString.Char8
+       as Data.ByteString.Char8
+import qualified Data.ProtoLens.Runtime.Data.Text.Encoding
+       as Data.Text.Encoding
+import qualified Data.ProtoLens.Runtime.Data.Vector as Data.Vector
+import qualified Data.ProtoLens.Runtime.Data.Vector.Generic
+       as Data.Vector.Generic
+import qualified Data.ProtoLens.Runtime.Data.Vector.Unboxed
+       as Data.Vector.Unboxed
+import qualified Data.ProtoLens.Runtime.Text.Read as Text.Read
+
+altPrices ::
+          forall f s a .
+            (Prelude.Functor f,
+             Data.ProtoLens.Field.HasField s "altPrices" a) =>
+            Lens.Family2.LensLike' f s a
+altPrices = Data.ProtoLens.Field.field @"altPrices"
+cents ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "cents" a) =>
+        Lens.Family2.LensLike' f s a
+cents = Data.ProtoLens.Field.field @"cents"
+changeType ::
+           forall f s a .
+             (Prelude.Functor f,
+              Data.ProtoLens.Field.HasField s "changeType" a) =>
+             Lens.Family2.LensLike' f s a
+changeType = Data.ProtoLens.Field.field @"changeType"
+color ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "color" a) =>
+        Lens.Family2.LensLike' f s a
+color = Data.ProtoLens.Field.field @"color"
+deleted ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "deleted" a) =>
+          Lens.Family2.LensLike' f s a
+deleted = Data.ProtoLens.Field.field @"deleted"
+diffVertexId ::
+             forall f s a .
+               (Prelude.Functor f,
+                Data.ProtoLens.Field.HasField s "diffVertexId" a) =>
+               Lens.Family2.LensLike' f s a
+diffVertexId = Data.ProtoLens.Field.field @"diffVertexId"
+dollars ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "dollars" a) =>
+          Lens.Family2.LensLike' f s a
+dollars = Data.ProtoLens.Field.field @"dollars"
+id ::
+   forall f s a .
+     (Prelude.Functor f, Data.ProtoLens.Field.HasField s "id" a) =>
+     Lens.Family2.LensLike' f s a
+id = Data.ProtoLens.Field.field @"id"
+inches ::
+       forall f s a .
+         (Prelude.Functor f, Data.ProtoLens.Field.HasField s "inches" a) =>
+         Lens.Family2.LensLike' f s a
+inches = Data.ProtoLens.Field.field @"inches"
+inserted ::
+         forall f s a .
+           (Prelude.Functor f,
+            Data.ProtoLens.Field.HasField s "inserted" a) =>
+           Lens.Family2.LensLike' f s a
+inserted = Data.ProtoLens.Field.field @"inserted"
+items ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "items" a) =>
+        Lens.Family2.LensLike' f s a
+items = Data.ProtoLens.Field.field @"items"
+maybe'deleted ::
+              forall f s a .
+                (Prelude.Functor f,
+                 Data.ProtoLens.Field.HasField s "maybe'deleted" a) =>
+                Lens.Family2.LensLike' f s a
+maybe'deleted = Data.ProtoLens.Field.field @"maybe'deleted"
+maybe'diffTerm ::
+               forall f s a .
+                 (Prelude.Functor f,
+                  Data.ProtoLens.Field.HasField s "maybe'diffTerm" a) =>
+                 Lens.Family2.LensLike' f s a
+maybe'diffTerm = Data.ProtoLens.Field.field @"maybe'diffTerm"
+maybe'extra ::
+            forall f s a .
+              (Prelude.Functor f,
+               Data.ProtoLens.Field.HasField s "maybe'extra" a) =>
+              Lens.Family2.LensLike' f s a
+maybe'extra = Data.ProtoLens.Field.field @"maybe'extra"
+maybe'inserted ::
+               forall f s a .
+                 (Prelude.Functor f,
+                  Data.ProtoLens.Field.HasField s "maybe'inserted" a) =>
+                 Lens.Family2.LensLike' f s a
+maybe'inserted = Data.ProtoLens.Field.field @"maybe'inserted"
+maybe'price ::
+            forall f s a .
+              (Prelude.Functor f,
+               Data.ProtoLens.Field.HasField s "maybe'price" a) =>
+              Lens.Family2.LensLike' f s a
+maybe'price = Data.ProtoLens.Field.field @"maybe'price"
+maybe't ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "maybe't" a) =>
+          Lens.Family2.LensLike' f s a
+maybe't = Data.ProtoLens.Field.field @"maybe't"
+maybe'u ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "maybe'u" a) =>
+          Lens.Family2.LensLike' f s a
+maybe'u = Data.ProtoLens.Field.field @"maybe'u"
+maybe'vatInfo ::
+              forall f s a .
+                (Prelude.Functor f,
+                 Data.ProtoLens.Field.HasField s "maybe'vatInfo" a) =>
+                Lens.Family2.LensLike' f s a
+maybe'vatInfo = Data.ProtoLens.Field.field @"maybe'vatInfo"
+maybe'zipCode ::
+              forall f s a .
+                (Prelude.Functor f,
+                 Data.ProtoLens.Field.HasField s "maybe'zipCode" a) =>
+                Lens.Family2.LensLike' f s a
+maybe'zipCode = Data.ProtoLens.Field.field @"maybe'zipCode"
+name ::
+     forall f s a .
+       (Prelude.Functor f, Data.ProtoLens.Field.HasField s "name" a) =>
+       Lens.Family2.LensLike' f s a
+name = Data.ProtoLens.Field.field @"name"
+price ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "price" a) =>
+        Lens.Family2.LensLike' f s a
+price = Data.ProtoLens.Field.field @"price"
+service ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "service" a) =>
+          Lens.Family2.LensLike' f s a
+service = Data.ProtoLens.Field.field @"service"
+status ::
+       forall f s a .
+         (Prelude.Functor f, Data.ProtoLens.Field.HasField s "status" a) =>
+         Lens.Family2.LensLike' f s a
+status = Data.ProtoLens.Field.field @"status"
+stuff ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "stuff" a) =>
+        Lens.Family2.LensLike' f s a
+stuff = Data.ProtoLens.Field.field @"stuff"
+t ::
+  forall f s a .
+    (Prelude.Functor f, Data.ProtoLens.Field.HasField s "t" a) =>
+    Lens.Family2.LensLike' f s a
+t = Data.ProtoLens.Field.field @"t"
+term ::
+     forall f s a .
+       (Prelude.Functor f, Data.ProtoLens.Field.HasField s "term" a) =>
+       Lens.Family2.LensLike' f s a
+term = Data.ProtoLens.Field.field @"term"
+testBytes ::
+          forall f s a .
+            (Prelude.Functor f,
+             Data.ProtoLens.Field.HasField s "testBytes" a) =>
+            Lens.Family2.LensLike' f s a
+testBytes = Data.ProtoLens.Field.field @"testBytes"
+type' ::
+      forall f s a .
+        (Prelude.Functor f, Data.ProtoLens.Field.HasField s "type'" a) =>
+        Lens.Family2.LensLike' f s a
+type' = Data.ProtoLens.Field.field @"type'"
+u ::
+  forall f s a .
+    (Prelude.Functor f, Data.ProtoLens.Field.HasField s "u" a) =>
+    Lens.Family2.LensLike' f s a
+u = Data.ProtoLens.Field.field @"u"
+vatInfo ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "vatInfo" a) =>
+          Lens.Family2.LensLike' f s a
+vatInfo = Data.ProtoLens.Field.field @"vatInfo"
+vec'altPrices ::
+              forall f s a .
+                (Prelude.Functor f,
+                 Data.ProtoLens.Field.HasField s "vec'altPrices" a) =>
+                Lens.Family2.LensLike' f s a
+vec'altPrices = Data.ProtoLens.Field.field @"vec'altPrices"
+vec'items ::
+          forall f s a .
+            (Prelude.Functor f,
+             Data.ProtoLens.Field.HasField s "vec'items" a) =>
+            Lens.Family2.LensLike' f s a
+vec'items = Data.ProtoLens.Field.field @"vec'items"
+vec'stuff ::
+          forall f s a .
+            (Prelude.Functor f,
+             Data.ProtoLens.Field.HasField s "vec'stuff" a) =>
+            Lens.Family2.LensLike' f s a
+vec'stuff = Data.ProtoLens.Field.field @"vec'stuff"
+zipCode ::
+        forall f s a .
+          (Prelude.Functor f, Data.ProtoLens.Field.HasField s "zipCode" a) =>
+          Lens.Family2.LensLike' f s a
+zipCode = Data.ProtoLens.Field.field @"zipCode"
diff --git a/app/Proto/Haberdasher_JSON.hs b/app/Proto/Haberdasher_JSON.hs
new file mode 100644
--- /dev/null
+++ b/app/Proto/Haberdasher_JSON.hs
@@ -0,0 +1,419 @@
+-- Code generated by protoc-gen-jsonpb_haskell 0.1.0, DO NOT EDIT.
+{-# OPTIONS_GHC -Wno-orphans -Wno-unused-imports -Wno-missing-export-lists #-}
+module Proto.Haberdasher_JSON where
+
+import           Prelude(($), (.), (<$>), pure, show, Maybe(..))
+
+import           Data.ProtoLens.Runtime.Lens.Family2 ((^.), (.~), (&))
+import           Data.Monoid (mconcat)
+import           Control.Monad (msum)
+import           Data.ProtoLens (defMessage)
+import qualified Data.Aeson as A
+import qualified Data.Aeson.Encoding as E
+import           Data.ProtoLens.JSONPB as JSONPB
+import qualified Data.Text as T
+
+import           Proto.Haberdasher as P
+import           Proto.Haberdasher_Fields as P
+
+instance FromJSONPB Size where
+  parseJSONPB = withObject "Size" $ \obj -> do
+    inches' <- obj .: "inches"
+    pure $ defMessage
+      & P.inches .~ inches'
+
+instance ToJSONPB Size where
+  toJSONPB x = object
+    [ "inches" .= (x^.inches)
+    ]
+  toEncodingPB x = pairs
+    [ "inches" .= (x^.inches)
+    ]
+
+instance FromJSON Size where
+  parseJSON = parseJSONPB
+
+instance ToJSON Size where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Hat where
+  parseJSONPB = withObject "Hat" $ \obj -> do
+    inches' <- obj .: "inches"
+    color' <- obj .: "color"
+    name' <- obj .: "name"
+    pure $ defMessage
+      & P.inches .~ inches'
+      & P.color .~ color'
+      & P.name .~ name'
+
+instance ToJSONPB Hat where
+  toJSONPB x = object
+    [ "inches" .= (x^.inches)
+    , "color" .= (x^.color)
+    , "name" .= (x^.name)
+    ]
+  toEncodingPB x = pairs
+    [ "inches" .= (x^.inches)
+    , "color" .= (x^.color)
+    , "name" .= (x^.name)
+    ]
+
+instance FromJSON Hat where
+  parseJSON = parseJSONPB
+
+instance ToJSON Hat where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Bill'Extra where
+  parseJSONPB = A.withObject "Bill'Extra" $ \obj -> mconcat
+    [
+      Bill'VatInfo <$> parseField obj "vat_info"
+    , Bill'ZipCode <$> parseField obj "zip_code"
+    ]
+
+instance ToJSONPB Bill'Extra where
+  toJSONPB (Bill'VatInfo x) = object [ "vat_info" .= x ]
+  toJSONPB (Bill'ZipCode x) = object [ "zip_code" .= x ]
+  toEncodingPB (Bill'VatInfo x) = pairs [ "vat_info" .= x ]
+  toEncodingPB (Bill'ZipCode x) = pairs [ "zip_code" .= x ]
+
+instance FromJSON Bill'Extra where
+  parseJSON = parseJSONPB
+
+instance ToJSON Bill'Extra where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Bill where
+  parseJSONPB = withObject "Bill" $ \obj -> do
+    price' <- obj A..:? "price"
+    status' <- obj .: "status"
+    extra' <- obj A..:? "extra"
+    pure $ defMessage
+      & P.maybe'price .~ price'
+      & P.status .~ status'
+      & P.maybe'extra .~ extra'
+
+instance ToJSONPB Bill where
+  toJSONPB x = object
+    [ "price" .= (x^.maybe'price)
+    , "status" .= (x^.status)
+    , "extra" .= (x^.maybe'extra)
+    ]
+  toEncodingPB x = pairs
+    [ "price" .= (x^.maybe'price)
+    , "status" .= (x^.status)
+    , "extra" .= (x^.maybe'extra)
+    ]
+
+instance FromJSON Bill where
+  parseJSON = parseJSONPB
+
+instance ToJSON Bill where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Bill'BillingStatus where
+  parseJSONPB (JSONPB.String "UN_PAID") = pure Bill'UN_PAID
+  parseJSONPB (JSONPB.String "PAID") = pure Bill'PAID
+  parseJSONPB x = typeMismatch "BillingStatus" x
+
+instance ToJSONPB Bill'BillingStatus where
+  toJSONPB x _ = A.String . T.toUpper . T.pack $ show x
+  toEncodingPB x _ = E.text . T.toUpper . T.pack  $ show x
+
+instance FromJSON Bill'BillingStatus where
+  parseJSON = parseJSONPB
+
+instance ToJSON Bill'BillingStatus where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Test where
+  parseJSONPB = withObject "Test" $ \obj -> do
+    items' <- obj .: "items"
+    altPrices' <- obj .: "altPrices"
+    pure $ defMessage
+      & P.items .~ items'
+      & P.altPrices .~ altPrices'
+
+instance ToJSONPB Test where
+  toJSONPB x = object
+    [ "items" .= (x^.items)
+    , "altPrices" .= (x^.altPrices)
+    ]
+  toEncodingPB x = pairs
+    [ "items" .= (x^.items)
+    , "altPrices" .= (x^.altPrices)
+    ]
+
+instance FromJSON Test where
+  parseJSON = parseJSONPB
+
+instance ToJSON Test where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Price where
+  parseJSONPB = withObject "Price" $ \obj -> do
+    dollars' <- obj .: "dollars"
+    cents' <- obj .: "cents"
+    pure $ defMessage
+      & P.dollars .~ dollars'
+      & P.cents .~ cents'
+
+instance ToJSONPB Price where
+  toJSONPB x = object
+    [ "dollars" .= (x^.dollars)
+    , "cents" .= (x^.cents)
+    ]
+  toEncodingPB x = pairs
+    [ "dollars" .= (x^.dollars)
+    , "cents" .= (x^.cents)
+    ]
+
+instance FromJSON Price where
+  parseJSON = parseJSONPB
+
+instance ToJSON Price where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Ping where
+  parseJSONPB = withObject "Ping" $ \obj -> do
+    service' <- obj .: "service"
+    pure $ defMessage
+      & P.service .~ service'
+
+instance ToJSONPB Ping where
+  toJSONPB x = object
+    [ "service" .= (x^.service)
+    ]
+  toEncodingPB x = pairs
+    [ "service" .= (x^.service)
+    ]
+
+instance FromJSON Ping where
+  parseJSON = parseJSONPB
+
+instance ToJSON Ping where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Pong'Extra where
+  parseJSONPB = A.withObject "Pong'Extra" $ \obj -> mconcat
+    [
+      Pong'T <$> parseField obj "t"
+    , Pong'U <$> parseField obj "u"
+    ]
+
+instance ToJSONPB Pong'Extra where
+  toJSONPB (Pong'T x) = object [ "t" .= x ]
+  toJSONPB (Pong'U x) = object [ "u" .= x ]
+  toEncodingPB (Pong'T x) = pairs [ "t" .= x ]
+  toEncodingPB (Pong'U x) = pairs [ "u" .= x ]
+
+instance FromJSON Pong'Extra where
+  parseJSON = parseJSONPB
+
+instance ToJSON Pong'Extra where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Pong where
+  parseJSONPB = withObject "Pong" $ \obj -> do
+    status' <- obj .: "status"
+    stuff' <- obj .: "stuff"
+    id' <- obj .: "id"
+    type'' <- obj .: "type'"
+    extra' <- obj A..:? "extra"
+    pure $ defMessage
+      & P.status .~ status'
+      & P.stuff .~ stuff'
+      & P.id .~ id'
+      & P.type' .~ type''
+      & P.maybe'extra .~ extra'
+
+instance ToJSONPB Pong where
+  toJSONPB x = object
+    [ "status" .= (x^.status)
+    , "stuff" .= (x^.stuff)
+    , "id" .= (x^.id)
+    , "type'" .= (x^.type')
+    , "extra" .= (x^.maybe'extra)
+    ]
+  toEncodingPB x = pairs
+    [ "status" .= (x^.status)
+    , "stuff" .= (x^.stuff)
+    , "id" .= (x^.id)
+    , "type'" .= (x^.type')
+    , "extra" .= (x^.maybe'extra)
+    ]
+
+instance FromJSON Pong where
+  parseJSON = parseJSONPB
+
+instance ToJSON Pong where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB Demo where
+  parseJSONPB = withObject "Demo" $ \obj -> do
+    changeType' <- obj .: "changeType"
+    pure $ defMessage
+      & P.changeType .~ changeType'
+
+instance ToJSONPB Demo where
+  toJSONPB x = object
+    [ "changeType" .= (x^.changeType)
+    ]
+  toEncodingPB x = pairs
+    [ "changeType" .= (x^.changeType)
+    ]
+
+instance FromJSON Demo where
+  parseJSON = parseJSONPB
+
+instance ToJSON Demo where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB FieldTestMessage where
+  parseJSONPB = withObject "FieldTestMessage" $ \obj -> do
+    testBytes' <- obj .: "testBytes"
+    pure $ defMessage
+      & P.testBytes .~ testBytes'
+
+instance ToJSONPB FieldTestMessage where
+  toJSONPB x = object
+    [ "testBytes" .= (x^.testBytes)
+    ]
+  toEncodingPB x = pairs
+    [ "testBytes" .= (x^.testBytes)
+    ]
+
+instance FromJSON FieldTestMessage where
+  parseJSON = parseJSONPB
+
+instance ToJSON FieldTestMessage where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB EmptyMessage where
+  parseJSONPB = withObject "EmptyMessage" $ \_ -> pure defMessage
+
+instance ToJSONPB EmptyMessage where
+  toJSONPB _ = object []
+  toEncodingPB _ = pairs []
+
+instance FromJSON EmptyMessage where
+  parseJSON = parseJSONPB
+
+instance ToJSON EmptyMessage where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB DiffTreeVertex'DiffTerm where
+  parseJSONPB = A.withObject "DiffTreeVertex'DiffTerm" $ \obj -> mconcat
+    [
+      DiffTreeVertex'Deleted <$> parseField obj "deleted"
+    , DiffTreeVertex'Inserted <$> parseField obj "inserted"
+    ]
+
+instance ToJSONPB DiffTreeVertex'DiffTerm where
+  toJSONPB (DiffTreeVertex'Deleted x) = object [ "deleted" .= Just x ]
+  toJSONPB (DiffTreeVertex'Inserted x) = object [ "inserted" .= Just x ]
+  toEncodingPB (DiffTreeVertex'Deleted x) = pairs [ "deleted" .= Just x ]
+  toEncodingPB (DiffTreeVertex'Inserted x) = pairs [ "inserted" .= Just x ]
+
+instance FromJSON DiffTreeVertex'DiffTerm where
+  parseJSON = parseJSONPB
+
+instance ToJSON DiffTreeVertex'DiffTerm where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB DiffTreeVertex where
+  parseJSONPB = withObject "DiffTreeVertex" $ \obj -> do
+    diffVertexId' <- obj .: "diffVertexId"
+    diffTerm' <- obj A..:? "diffTerm"
+    pure $ defMessage
+      & P.diffVertexId .~ diffVertexId'
+      & P.maybe'diffTerm .~ diffTerm'
+
+instance ToJSONPB DiffTreeVertex where
+  toJSONPB x = object
+    [ "diffVertexId" .= (x^.diffVertexId)
+    , "diffTerm" .= (x^.maybe'diffTerm)
+    ]
+  toEncodingPB x = pairs
+    [ "diffVertexId" .= (x^.diffVertexId)
+    , "diffTerm" .= (x^.maybe'diffTerm)
+    ]
+
+instance FromJSON DiffTreeVertex where
+  parseJSON = parseJSONPB
+
+instance ToJSON DiffTreeVertex where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB DeletedTerm where
+  parseJSONPB = withObject "DeletedTerm" $ \obj -> do
+    term' <- obj .: "term"
+    pure $ defMessage
+      & P.term .~ term'
+
+instance ToJSONPB DeletedTerm where
+  toJSONPB x = object
+    [ "term" .= (x^.term)
+    ]
+  toEncodingPB x = pairs
+    [ "term" .= (x^.term)
+    ]
+
+instance FromJSON DeletedTerm where
+  parseJSON = parseJSONPB
+
+instance ToJSON DeletedTerm where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB InsertedTerm where
+  parseJSONPB = withObject "InsertedTerm" $ \obj -> do
+    term' <- obj .: "term"
+    pure $ defMessage
+      & P.term .~ term'
+
+instance ToJSONPB InsertedTerm where
+  toJSONPB x = object
+    [ "term" .= (x^.term)
+    ]
+  toEncodingPB x = pairs
+    [ "term" .= (x^.term)
+    ]
+
+instance FromJSON InsertedTerm where
+  parseJSON = parseJSONPB
+
+instance ToJSON InsertedTerm where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
+
+instance FromJSONPB ChangeType where
+  parseJSONPB (JSONPB.String "ADDED") = pure ADDED
+  parseJSONPB (JSONPB.String "REMOVED") = pure REMOVED
+  parseJSONPB x = typeMismatch "ChangeType" x
+
+instance ToJSONPB ChangeType where
+  toJSONPB x _ = A.String . T.toUpper . T.pack $ show x
+  toEncodingPB x _ = E.text . T.toUpper . T.pack  $ show x
+
+instance FromJSON ChangeType where
+  parseJSON = parseJSONPB
+
+instance ToJSON ChangeType where
+  toJSON = toAesonValue
+  toEncoding = toAesonEncoding
diff --git a/proto-lens-jsonpb.cabal b/proto-lens-jsonpb.cabal
new file mode 100644
--- /dev/null
+++ b/proto-lens-jsonpb.cabal
@@ -0,0 +1,77 @@
+cabal-version:  2.4
+
+name:           proto-lens-jsonpb
+version:        0.1.0.0
+synopsis:       JSON protobuf encoding for proto-lens
+description:    Please see the README on GitHub at <https://github.com/tclem/proto-lens-jsonpb#readme>
+homepage:       https://github.com/tclem/proto-lens-jsonpb#readme
+bug-reports:    https://github.com/tclem/proto-lens-jsonpb/issues
+license:        BSD-3-Clause
+license-file:   LICENSE
+author:         Timothy Clem
+maintainer:     timothy.clem@gmail.com
+copyright:      2019 Timothy Clem
+category:       Web
+build-type:     Simple
+extra-source-files: README.md
+
+tested-with:    GHC == 8.6.5
+              , GHC == 8.8.1
+
+-- GHC extensions shared between targets
+common haskell
+  default-language:    Haskell2010
+  default-extensions:  DataKinds
+                     , DeriveFoldable
+                     , DeriveFunctor
+                     , DeriveGeneric
+                     , DeriveTraversable
+                     , FlexibleContexts
+                     , FlexibleInstances
+                     , MultiParamTypeClasses
+                     , OverloadedStrings
+                     , RecordWildCards
+                     , StandaloneDeriving
+                     , StrictData
+                     , TypeApplications
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
+
+common dependencies
+  build-depends:
+      base >=4.7 && <5
+    , aeson ^>= 1.4.5.0
+    , bytestring >= 0.10.8
+    , proto-lens-runtime >= 0.5 && <0.7
+    , text ^>= 1.2.4.0
+    , vector >= 0.12.0.3
+    , attoparsec >= 0.13.2.3
+    , base64-bytestring >= 1
+
+library
+  import: haskell, dependencies
+  exposed-modules:
+      Data.ProtoLens.JSONPB
+      Data.ProtoLens.JSONPB.Class
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
+  build-depends:
+
+executable example
+  import: haskell, dependencies
+  main-is: Main.hs
+  other-modules:
+      Proto.Haberdasher
+      Proto.Haberdasher_Fields
+      Proto.Haberdasher_JSON
+  hs-source-dirs:
+      app
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      proto-lens >= 0.5.0.0
+    , proto-lens-jsonpb
+    , microlens
+
+source-repository head
+  type: git
+  location: https://github.com/tclem/proto-lens-jsonpb
diff --git a/src/Data/ProtoLens/JSONPB.hs b/src/Data/ProtoLens/JSONPB.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ProtoLens/JSONPB.hs
@@ -0,0 +1,34 @@
+module Data.ProtoLens.JSONPB
+  ( -- * Typeclasses
+    FromJSONPB(..)
+  , ToJSONPB(..)
+    -- * Operators
+  , (.:)
+  , (.=)
+    -- * Options for controlling codec behavior (e.g., emitting default-valued
+    --   fields in JSON payloads)
+  , Options(..)
+  , defaultOptions
+    -- * JSONPB codec entry points
+  , eitherDecode
+  , encode
+    -- * Helper functions
+  -- , enumFieldEncoding
+  -- , enumFieldString
+  , object
+  , pair
+  , pairs
+  , parseField
+  , toAesonEncoding
+  , toAesonValue
+    -- * Aeson re-exports
+  , A.Value(..)
+  , A.ToJSON(..)
+  , A.FromJSON(..)
+  , A.typeMismatch
+  , A.withObject
+  ) where
+
+import qualified Data.Aeson as A
+import qualified Data.Aeson.Types as A
+import           Data.ProtoLens.JSONPB.Class
diff --git a/src/Data/ProtoLens/JSONPB/Class.hs b/src/Data/ProtoLens/JSONPB/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ProtoLens/JSONPB/Class.hs
@@ -0,0 +1,459 @@
+{-# LANGUAGE FlexibleInstances, OverloadedLists, RecordWildCards, ScopedTypeVariables, ViewPatterns #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+
+-- Ported from https://github.com/awakesecurity/proto3-suite (Apache v2 License)
+-- and modified to work with proto-lens.
+--
+-- | Support for the "JSONPB" canonical JSON encoding described at
+-- https://developers.google.com/protocol-buffers/docs/proto3#json.
+--
+-- This modules provides 'Data.Aeson'-like helper functions, typeclasses, and
+-- instances for converting to and from values of types which have a JSONPB
+-- representation and equivalent underlying 'Data.Aeson' representations.
+--
+-- This module also presents a (very minimal) surface syntax for Aeson-like
+-- operations; the idea is that we can write 'ToJSONPB' and 'FromJSONPB'
+-- instances in a very similar manner to 'A.ToJSON' and 'A.FromJSON' instances,
+-- except that doing so specifies JSONPB codecs instead of vanilla JSON codecs.
+--
+-- Example use:
+--
+-- @
+-- message Scalar32 {
+--   int32     i32 = 1;
+--   uint32    u32 = 2;
+--   sint32    s32 = 3;
+--   fixed32   f32 = 4;
+--   sfixed32 sf32 = 5;
+-- }
+--
+-- instance ToJSONPB Scalar32 where
+--   toJSONPB (Scalar32 i32 u32 s32 f32 sf32) = object
+--       [ "i32"  .= i32
+--       , "u32"  .= u32
+--       , "s32"  .= s32
+--       , "f32"  .= f32
+--       , "sf32" .= sf32
+--       ]
+--   toEncodingPB (Scalar32 i32 u32 s32 f32 sf32) = pairs
+--       [ "i32"  .= i32
+--       , "u32"  .= u32
+--       , "s32"  .= s32
+--       , "f32"  .= f32
+--       , "sf32" .= sf32
+--       ]
+--
+-- instance FromJSONPB Scalar32 where
+--   parseJSONPB = withObject "Scalar32" $ \obj ->
+--     pure Scalar32
+--     <*> obj .: "i32"
+--     <*> obj .: "u32"
+--     <*> obj .: "s32"
+--     <*> obj .: "f32"
+--     <*> obj .: "sf32"
+-- @
+module Data.ProtoLens.JSONPB.Class where
+
+import qualified Data.Aeson as A
+    ( Encoding
+    , FromJSON (..)
+    , FromJSONKey (..)
+    , FromJSONKeyFunction (..)
+    , ToJSON (..)
+    , Value (..)
+    , eitherDecode
+    , json
+    , (.!=)
+    )
+
+import qualified Data.Aeson.Encoding as E
+import qualified Data.Aeson.Internal as A (formatError, iparse)
+import qualified Data.Aeson.Parser as A (eitherDecodeWith)
+import qualified Data.Aeson.Types as A
+    (Object, Pair, Parser, Series, explicitParseField, explicitParseFieldMaybe, object, typeMismatch)
+import qualified Data.Attoparsec.ByteString as Atto (skipWhile)
+import qualified Data.Attoparsec.ByteString.Char8 as Atto (Parser, endOfInput)
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Base64 as B64
+import qualified Data.ByteString.Lazy as LBS
+import           Data.ProtoLens.Runtime.Data.ProtoLens (FieldDefault (..))
+import           Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Encoding as TL
+import qualified Data.Vector as V
+import           GHC.Int (Int32, Int64)
+import           GHC.Word (Word32, Word64)
+
+
+-- * Typeclass definitions
+
+-- | 'A.ToJSON' variant for JSONPB direct encoding via 'A.Encoding'
+class ToJSONPB a where
+  -- | 'A.toJSON' variant for JSONPB encoders.
+  toJSONPB :: a -> Options -> A.Value
+  -- | 'A.toEncoding' variant for JSONPB encoders. If an implementation is not
+  -- provided, uses 'toJSONPB' (which is less efficient since it indirects
+  -- through the 'A.Value' IR).
+  toEncodingPB :: a -> Options -> A.Encoding
+  toEncodingPB x = A.toEncoding . toJSONPB x
+
+-- | 'A.FromJSON' variant for JSONPB decoding from the 'A.Value' IR
+class FromJSONPB a where
+  -- | 'A.parseJSON' variant for JSONPB decoders.
+  parseJSONPB :: A.Value -> A.Parser a
+
+-- * JSONPB codec entry points
+
+-- | 'Data.Aeson.encode' variant for serializing a JSONPB value as a lazy
+-- 'LBS.ByteString'.
+encode :: ToJSONPB a => Options -> a -> LBS.ByteString
+encode opts x = E.encodingToLazyByteString (toEncodingPB x opts)
+
+{-# INLINE encode #-}
+-- | 'Data.Aeson.eitherDecode' variant for deserializing a JSONPB value from a
+-- lazy 'LBS.ByteString'.
+eitherDecode :: FromJSONPB a => LBS.ByteString -> Either String a
+eitherDecode =
+  eitherFormatError . A.eitherDecodeWith jsonEOF (A.iparse parseJSONPB)
+  where
+    eitherFormatError = either (Left . uncurry A.formatError) Right
+    {-# INLINE eitherFormatError #-}
+    -- NB: cribbed from aeson-1.1.1.0:Data.Aeson.Parser.Internal.jsonEOF, which
+    -- is not exported. It's simple, so we just inline it here. Might be worth
+    -- submitting a PR to export this.
+    jsonEOF :: Atto.Parser A.Value
+    jsonEOF = A.json <* skipSpace <* Atto.endOfInput
+      where
+        skipSpace :: Atto.Parser ()
+        skipSpace =
+          Atto.skipWhile $ \w ->
+            w == 0x20 || w == 0x0a || w == 0x0d || w == 0x09
+        {-# INLINE skipSpace #-}
+
+{-# INLINE eitherDecode #-}
+-- * Operator definitions
+-- | JSONPB-encoded monoidal key-value pairs
+class Monoid m =>
+      KeyValuePB m
+  where
+  pair :: ToJSONPB v => Text -> v -> Options -> m
+
+instance KeyValuePB A.Series where
+  pair k v opts = E.pair k (toEncodingPB v opts)
+
+instance KeyValuePB [A.Pair] where
+  pair k v opts = pure (k, toJSONPB v opts)
+
+-- | Construct a monoidal key-value pair, using 'mempty' to represent omission
+-- of default values (unless the given 'Options' force their emission).
+(.=) ::
+     (ToJSONPB v, KeyValuePB kvp, FieldDefault v, Eq v) => Text -> v -> Options -> kvp
+k .= v = mk
+  where
+    mk opts@Options {..} -- = pair k v opts
+      | not optEmitDefaultValuedFields && fieldDefault == v = mempty
+      | otherwise = pair k v opts
+
+-- | 'Data.Aeson..:' variant for JSONPB; if the given key is missing from the
+-- object, or if it is present but its value is null, we produce the default
+-- protobuf value for the field type
+(.:) :: (FromJSONPB a, FieldDefault a) => A.Object -> Text -> A.Parser a
+obj .: key = obj .:? key A..!= fieldDefault
+  where
+    (.:?) = A.explicitParseFieldMaybe parseJSONPB
+
+parseField :: FromJSONPB a => A.Object -> Text -> A.Parser a
+parseField = A.explicitParseField parseJSONPB
+
+-- * JSONPB rendering and parsing options
+data Options =
+  Options
+    { optEmitDefaultValuedFields :: Bool
+    }
+  deriving (Show)
+
+-- | Default options for JSONPB encoding. By default, all options are @False@.
+defaultOptions :: Options
+defaultOptions = Options {optEmitDefaultValuedFields = False}
+
+-- * Helper types and functions
+-- dropNamedPrefix :: Named a => Proxy a -> String -> String
+-- dropNamedPrefix p = drop (length (nameOf p :: String))
+
+object :: [Options -> [A.Pair]] -> Options -> A.Value
+object fs = A.object . mconcat fs
+
+pairs :: [Options -> A.Series] -> Options -> E.Encoding
+pairs fs = E.pairs . mconcat fs
+
+-- enumFieldString ::
+--      forall a. (Named a, Show a)
+--   => a
+--   -> A.Value
+-- enumFieldString = A.String . T.pack . dropNamedPrefix (Proxy @a) . show
+
+-- enumFieldEncoding ::
+--      forall a. (Named a, Show a)
+--   => a
+--   -> A.Encoding
+-- enumFieldEncoding = E.string . dropNamedPrefix (Proxy @a) . show
+
+-- | A 'Data.Aeson' 'A.Value' encoder for values which can be
+-- JSONPB-encoded
+toAesonValue :: ToJSONPB a => a -> A.Value
+toAesonValue = flip toJSONPB defaultOptions
+
+-- | A direct 'A.Encoding' for values which can be JSONPB-encoded
+toAesonEncoding :: ToJSONPB a => a -> A.Encoding
+toAesonEncoding = flip toEncodingPB defaultOptions
+
+-- | Parse a JSONPB floating point value; first parameter provides context for
+-- type mismatches
+parseFP :: (A.FromJSON a, A.FromJSONKey a) => String -> A.Value -> A.Parser a
+parseFP tyDesc v =
+  case v of
+    A.Number {} -> A.parseJSON v
+    A.String t ->
+      case A.fromJSONKey of
+        A.FromJSONKeyTextParser p -> p t
+        _                         -> fail "internal: parseKeyPB: unexpected FromJSONKey summand"
+    _ -> A.typeMismatch tyDesc v
+
+-- | Liberally parse an integer value (e.g. 42 or "42" as 42); first parameter
+-- provides context for type mismatches
+parseNumOrDecimalString :: (A.FromJSON a) => String -> A.Value -> A.Parser a
+parseNumOrDecimalString tyDesc v =
+  case v of
+    A.Number {} -> A.parseJSON v
+    A.String t ->
+      either fail pure . A.eitherDecode . TL.encodeUtf8 . TL.fromStrict $ t
+    _ -> A.typeMismatch tyDesc v
+
+-- * Common instances for jsonpb codec implementations
+-- ** Instances for scalar types
+--------------------------------------------------------------------------------
+-- Boolean scalar type
+instance ToJSONPB Bool where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB Bool where
+  parseJSONPB = A.parseJSON
+
+--------------------------------------------------------------------------------
+-- Integer scalar types
+--
+--   * 32 bit integer values render to JSON decimal numbers; either numbers or
+--     strings are accepted.
+--
+--   * 64 bit integer values render to JSON decimal strings; either numbers
+--     or strings are accepted.
+--
+-- int32 / sint32
+instance ToJSONPB Int32 where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB Int32 where
+  parseJSONPB = parseNumOrDecimalString "int32 / sint32"
+
+-- uint32
+instance ToJSONPB Word32 where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB Word32 where
+  parseJSONPB = parseNumOrDecimalString "uint32"
+
+-- int64 / sint64
+instance ToJSONPB Int64 where
+  toJSONPB x _ = A.String . T.pack . show $ x
+  toEncodingPB x _ = E.string (show x)
+
+instance FromJSONPB Int64 where
+  parseJSONPB = parseNumOrDecimalString "int64 / sint64"
+
+-- unit64
+instance ToJSONPB Word64 where
+  toJSONPB x _ = A.String . T.pack . show $ x
+  toEncodingPB x _ = E.string (show x)
+
+instance FromJSONPB Word64 where
+  parseJSONPB = parseNumOrDecimalString "int64 / sint64"
+
+-- -- fixed32
+-- instance ToJSONPB (Fixed Word32) where
+--   toJSONPB = coerce (toJSONPB @Word32)
+--   toEncodingPB = coerce (toEncodingPB @Word32)
+
+-- instance FromJSONPB (Fixed Word32) where
+--   parseJSONPB = coerce (parseJSONPB @Word32)
+
+-- -- fixed64
+-- instance ToJSONPB (Fixed Word64) where
+--   toJSONPB = coerce (toJSONPB @Word64)
+--   toEncodingPB = coerce (toEncodingPB @Word64)
+
+-- instance FromJSONPB (Fixed Word64) where
+--   parseJSONPB = coerce (parseJSONPB @Word64)
+
+-- -- sfixed32
+-- instance ToJSONPB (Fixed Int32) where
+--   toJSONPB = coerce (toJSONPB @Int32)
+--   toEncodingPB = coerce (toEncodingPB @Int32)
+
+-- instance FromJSONPB (Fixed Int32) where
+--   parseJSONPB = coerce (parseJSONPB @Int32)
+
+-- -- sfixed64
+-- instance ToJSONPB (Fixed Int64) where
+--   toJSONPB = coerce (toJSONPB @Int64)
+--   toEncodingPB = coerce (toEncodingPB @Int64)
+
+-- instance FromJSONPB (Fixed Int64) where
+--   parseJSONPB = coerce (parseJSONPB @Int64)
+
+--------------------------------------------------------------------------------
+-- Floating point scalar types
+--
+-- JSON value will be a number or one of the special string values "NaN",
+-- "Infinity", and "-Infinity". Either numbers or strings are accepted. Exponent
+-- notation is also accepted.
+-- float
+instance ToJSONPB Float where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB Float where
+  parseJSONPB = parseFP "float"
+
+-- double
+instance ToJSONPB Double where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB Double where
+  parseJSONPB = parseFP "double"
+
+--------------------------------------------------------------------------------
+-- Stringly types (string and bytes)
+-- string
+instance ToJSONPB TL.Text where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB TL.Text where
+  parseJSONPB = A.parseJSON
+
+instance ToJSONPB T.Text where
+  toJSONPB = const . A.toJSON
+  toEncodingPB = const . A.toEncoding
+
+instance FromJSONPB T.Text where
+  parseJSONPB = A.parseJSON
+
+-- bytes
+bsToJSONPB :: BS.ByteString -> A.Value
+bsToJSONPB (T.decodeUtf8' . B64.encode -> ebs) =
+  case ebs of
+    Right bs -> A.toJSON bs
+    Left e ->
+      error ("internal: failed to encode B64-encoded bytestring: " ++ show e)
+              -- NB: T.decodeUtf8' should never fail because we B64-encode the
+              -- incoming bytestring.
+
+instance ToJSONPB BS.ByteString where
+  toJSONPB bs _ = bsToJSONPB bs
+  toEncodingPB bs opts = E.value (toJSONPB bs opts)
+
+instance FromJSONPB BS.ByteString where
+  parseJSONPB (A.String b64enc) =
+    pure . B64.decodeLenient . T.encodeUtf8 $ b64enc
+  parseJSONPB v = A.typeMismatch "bytes" v
+
+-- --------------------------------------------------------------------------------
+-- -- Enumerated types
+-- enumToJSONPB ::
+--      (e -> Options -> a) -- ^ JSONPB encoder function to use
+--   -> a -- ^ null value to use for out-of-range enums
+--   -> Enumerated e -- ^ the enumerated value to encode
+--   -> Options -- ^ JSONPB encoding options
+--   -> a -- ^ the JSONPB-encoded value
+-- enumToJSONPB enc null_ (Enumerated e) opts =
+--   either err (\input -> enc input opts) e
+--   where
+--     err 0 = error "enumToJSONPB: The first enum value must be zero in proto3"
+--             -- TODO: Raise a compilation error when the first enum value in an
+--             -- enumeration is not zero.
+--             --
+--             -- See https://github.com/awakesecurity/proto3-suite/issues/28
+--             --
+--             -- The proto3 spec states that the default value is the first
+--             -- defined enum value, which must be 0. Since we currently don't
+--             -- raise a compilation error for this like we should, we have to
+--             -- handle this case.
+--             --
+--             -- For now, die horribly to mimic what should be a compilation
+--             -- error.
+--     err _ = null_
+--             -- From the JSONPB spec:
+--             --
+--             --   If a value is missing in the JSON-encoded data or if its value
+--             --   is null, it will be interpreted as the appropriate default
+--             --   value when parsed into a protocol buffer.
+--             --
+--             -- Thus, interpreting a wire value out of enum range as "missing",
+--             -- we yield null here to mean the default value.
+--
+-- instance ToJSONPB e => ToJSONPB (Enumerated e) where
+--   toJSONPB = enumToJSONPB toJSONPB A.Null
+--   toEncodingPB = enumToJSONPB toEncodingPB E.null_
+--
+-- instance (Bounded e, Enum e, FromJSONPB e) => FromJSONPB (Enumerated e) where
+--   parseJSONPB A.Null = pure def -- So CG does not have to handle this case in
+--                                 -- every generated instance
+--   parseJSONPB v      = Enumerated . Right <$> parseJSONPB v
+
+-- ** Instances for composite types
+--------------------------------------------------------------------------------
+-- Instances for repeated messages
+--
+-- JSON value will be the vector elements encoded as a JSON array. The null
+-- value is accepted as the empty list, @[]@.
+instance ToJSONPB a => ToJSONPB (V.Vector a) where
+  toJSONPB v opts = A.Array (V.map (\x -> toJSONPB x opts) v)
+  toEncodingPB v opts = E.list (\x -> toEncodingPB x opts) (V.toList v)
+
+instance FromJSONPB a => FromJSONPB (V.Vector a) where
+  parseJSONPB (A.Array vs) = mapM parseJSONPB vs
+  parseJSONPB A.Null       = pure []
+  parseJSONPB v            = A.typeMismatch "repeated" v
+
+--------------------------------------------------------------------------------
+-- Instances for nested messages
+instance ToJSONPB a => ToJSONPB (Maybe a) where
+  toJSONPB mx opts = maybe A.Null (\x -> toJSONPB x opts) mx
+  toEncodingPB mx opts = maybe E.null_ (\x -> toEncodingPB x opts) mx
+
+instance FromJSONPB a => FromJSONPB (Maybe a) where
+  parseJSONPB A.Null = pure Nothing
+  parseJSONPB v      = fmap Just (parseJSONPB v)
+
+instance ToJSONPB a => ToJSONPB [a] where
+  toJSONPB xs opts = A.Array $ V.fromList (fmap (\x -> toJSONPB x opts) xs)
+  toEncodingPB xs opts = E.list (\x -> toEncodingPB x opts) xs
+
+instance FromJSONPB a => FromJSONPB [a] where
+  parseJSONPB (A.Array xs) = mapM parseJSONPB (V.toList xs)
+  parseJSONPB A.Null       = pure []
+  parseJSONPB v            = A.typeMismatch "repeated" v
+
+-- A couple of orphaned FieldDefault instances
+-- NB: Not ideal, should contribute back to proto-lens or come up with another concept of default fields.
+instance FieldDefault [a] where
+  fieldDefault = mempty
+
+instance FieldDefault (Maybe a) where
+  fieldDefault = Nothing
