-- | This module add unknown field support to the library. There are-- no user API things here.-- This should support-- 1) Storing unknown bytestrings in messages-- a) Mergeable-- b) Default-- c) Show-- 2) loading the unknown bytestrings into a (Map FieldId) from wire-- a) If wiretypes differ this is an error so report it-- b) Take extra care to ensure a _copy_ of the input is kept (?)-- 3) save unknown bytestring back to the wire-- 4) API ?-- a) Provide ability to "wireGet" the data as a real type-- b) clear the data-- c) has any unkown data ?-- 5) Extend reflection to indicate presence of support for unkown data-- 6) Extend Options and command line to flag this-- 7) Extend hprotoc to add in this fieldmoduleText.ProtocolBuffers.Unknown(UnknownField(..),UnknownMessage(..),UnknownFieldValue(..),wireSizeUnknownField,wirePutUnknownField,loadUnknown)whereimportqualifiedData.ByteString.LazyasLimportqualifiedData.FoldableasFimportData.GenericsimportData.Map(Map)importqualifiedData.MapasMimportData.Monoid(mappend)importData.Sequence(Seq,(|>))importqualifiedData.SequenceasSeqimportData.TypeableimportText.ProtocolBuffers.BasicimportText.ProtocolBuffers.WireMessageimportText.ProtocolBuffers.GetasGet(Get,bytesRead)err::String->berrmsg=error$"Text.ProtocolBuffers.Unknown error\n"++msgclassUnknownMessagemsgwheregetUnknownField::msg->UnknownFieldputUnknownField::UnknownField->msg->msgnewtypeUnknownField=UnknownField(MapFieldIdUnknownFieldValue)deriving(Eq,Ord,Show,Read,Data,Typeable)dataUnknownFieldValue=UFV!WireType!(SeqByteString)deriving(Eq,Ord,Show,Read,Data,Typeable)instanceMergeableUnknownFieldwheremergeEmpty=UnknownFieldM.emptymergeAppend(UnknownFieldm1)(UnknownFieldm2)=UnknownField(M.unionWithmergeUnknownFieldValuem1m2)mergeUnknownFieldValue::UnknownFieldValue->UnknownFieldValue->UnknownFieldValuemergeUnknownFieldValue(UFVwt1s1)(UFVwt2s2)=ifwt1/=wt2thenerr$"mergeUnknownFieldValue: WireType mismatch "++show(wt1,wt2)elseUFVwt2(mappends1s2)instanceDefaultUnknownFieldwheredefaultValue=UnknownFieldM.empty-- | This is used by the generated codewireSizeUnknownField::UnknownField->WireSizewireSizeUnknownField(UnknownFieldm)=F.foldl'aSize0(M.assocsm)whereaSizeold(fi,(UFVwtraw))=old+lettagSize=size'Varint(getWireTag(mkWireTagfiwt))inF.foldl'(\oldValnew->oldVal+L.lengthnew)(fromIntegral(Seq.lengthraw)*tagSize)raw-- | This is used by the generated codewirePutUnknownField::UnknownField->PutwirePutUnknownField(UnknownFieldm)=mapM_aPut(M.assocsm)whereaPut(fi,(UFVwtraw))=F.mapM_(\bs->putVarUInt(getWireTag$mkWireTagfiwt)>>putLazyByteStringbs)rawloadUnknown::(Typeablea,UnknownMessagea)=>FieldId->WireType->a->GetaloadUnknownfieldIdwireTypemsg=dolet(UnknownFielduf)=getUnknownFieldmsgbadwtwt=dohere<-bytesReadfail$"Conflicting wire types at byte position "++showhere++" for unknown field of message: "++show(typeOfmsg,fieldId,wireType,wt)caseM.lookupfieldIdufofNothing->dobs<-wireGetFromWirefieldIdwireTypeletv'=UFVwireType(Seq.singletonbs)uf'=M.insertfieldIdv'ufseqv'$sequf'$return$putUnknownField(UnknownFielduf')msgJust(UFVwtraw)|wt/=wireType->badwtwt|otherwise->dobs<-wireGetFromWirefieldIdwireTypeletv'=UFVwt(raw|>bs)uf'=M.insertfieldIdv'ufseqv'$sequf'$return$putUnknownField(UnknownFielduf')msg