Skip to content

Commit

Permalink
Add support for tracking unknown fields. (google#129)
Browse files Browse the repository at this point in the history
- Every message has a new field containing a list of unknown fields:
  ```unknownFields :: Message msg => Lens' msg [TaggedValue]```
- Unknown fields are preserved by `decodeMessage`, `encodeMessage`,
  and `showMessage`
- Unknown fields still cause an error for `readMessage`.

A few TODOs:
- For now, unknown groups are printed sub-optimally by `showMessage`: the
  start/end group tags (and everything in between) all get displayed as
  individual fields, rather than being organized into a sub-struct.
- The `discardUnknownFields` function isn't recursive, unlike in other
  languages.
- The Ord instance doesn't try to do anything special, just treating
  the unknown fields as a list of values.  If it really matters then
  `discardUnknownFields` can help resolve the ambiguity.
  • Loading branch information
judah committed Sep 1, 2017
1 parent 0b56a97 commit f394db2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Data/ProtoLens/Compiler/Definitions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ data MessageInfo n = MessageInfo
, messageOneofFields :: [OneofInfo]
-- ^ The oneofs in this message, associated with the fields that
-- belong to them.
, messageUnknownFields :: Name
-- ^ The name of the Haskell field in this message that holds the
-- unknown fields.
} deriving Functor

-- | Information about a single field of a proto message.
Expand Down Expand Up @@ -225,6 +228,8 @@ messageDefs protoPrefix hsPrefix d
map (fieldInfo hsPrefix')
$ Map.findWithDefault [] Nothing allFields
, messageOneofFields = collectOneofFields hsPrefix' d allFields
, messageUnknownFields =
fromString $ "_" ++ hsPrefix' ++ "_unknownFields"
}

fieldInfo :: String -> FieldDescriptorProto -> FieldInfo
Expand Down
6 changes: 5 additions & 1 deletion src/Data/ProtoLens/Compiler/Generate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ generateMessageDecls syntaxType env protoName info =
[ (recordFieldName f, recordFieldType f)
| f <- allFields
]
++ [(messageUnknownFields info, "Data.ProtoLens.FieldSet")]
]
["Prelude.Show", "Prelude.Eq", "Prelude.Ord"]
] ++
Expand Down Expand Up @@ -221,7 +222,9 @@ generateMessageDecls syntaxType env protoName info =
[ fieldUpdate (unQual $ haskellRecordFieldName $ oneofFieldName o)
"Prelude.Nothing"
| o <- messageOneofFields info
]
] ++
[ fieldUpdate (unQual $ messageUnknownFields info)
"[]"]
]
]
-- instance Message.Message Bar where
Expand Down Expand Up @@ -691,6 +694,7 @@ descriptorExpr syntaxType env protoName m
@@ ("Data.Text.pack" @@ stringExp (T.unpack protoName))
@@ ("Data.Map.fromList" @@ list fieldsByTag)
@@ ("Data.Map.fromList" @@ list fieldsByTextFormatName)
@@ rawFieldAccessor (unQual $ messageUnknownFields m)
where
fieldsByTag =
[tuple
Expand Down

0 comments on commit f394db2

Please sign in to comment.