|
| Text.ProtocolBuffers.Extensions |
|
|
|
|
| Description |
The Extensions module contributes two main things. The first
is the definition and implementation of extensible message
features. This means that the ExtField data type is exported but
its constructor is (in an ideal world) hidden.
This first part also includes the keys for the extension fields:
the Key data type. These are typically defined in code generated
by hprotoc from '.proto' file definitions.
The second main part is the MessageAPI class which defines
getVal and isSet. These allow uniform access to normal and
extension fields for users.
Access to extension fields is strictly though keys. There is not
currently any way to query or change or clear any other extension
field data.
This module is likely to get broken up into pieces.
|
|
| Synopsis |
|
| getKeyFieldId :: Key c msg v -> FieldId | | | getKeyFieldType :: Key c msg v -> FieldType | | | getKeyDefaultValue :: Key c msg v -> v | | | | | class ExtKey c where | | | | class MessageAPI msg a b | msg a -> b where | | | | wireSizeExtField :: ExtField -> WireSize | | | wirePutExtField :: ExtField -> Put | | | getMessageExt :: (Mergeable message, ReflectDescriptor message, Typeable message, ExtendMessage message) => (FieldId -> message -> Get message) -> Get message | | | getBareMessageExt :: (Mergeable message, ReflectDescriptor message, Typeable message, ExtendMessage message) => (FieldId -> message -> Get message) -> Get message | | | loadExtension :: (ReflectDescriptor a, ExtendMessage a) => FieldId -> WireType -> a -> Get a | | | class (Mergeable a, Default a, Wire a, Show a, Typeable a, Eq a, Ord a) => GPB a | | | newtype ExtField = ExtField (Map FieldId ExtFieldValue) | | | class Typeable msg => ExtendMessage msg where | |
|
|
|
| Query functions for Key
|
|
|
| This allows reflection, in this case it gives the numerical
FieldId of the key, from 1 to 2^29-1 (excluding 19,000 through
19,999).
|
|
|
| This allows reflection, in this case it gives the FieldType
enumeration value (1 to 18) of the
Text.DescriptorProtos.FieldDescriptorProto.Type of the field.
|
|
|
| This will return the default value for a given Key, which is
set in the '.proto' file, or if unset it is the defaultValue of
that type.
|
|
| External types and classes
|
|
|
The Key data type is used with the ExtKey class to put, get,
and clear external fields of messages. The Key can also be used
with the MessagesAPI to get a possibly default value and to check
whether a key has been set in a message.
The Key type (opaque to the user) has a phantom type of Maybe
or Seq that corresponds to Optional or Repeated fields. And a
second phantom type that matches the message type it must be used
with. The third type parameter corresonds to the Haskell value
type.
The Key is a GADT that puts all the needed class instances into
scope. The actual content is the FieldId ( numeric key), the
FieldType (for sanity checks), and Maybe v (a non-standard
default value).
When code is generated all of the known keys are taken into account
in the deserialization from the wire. Unknown extension fields are
read as a collection of raw byte sequences. If a key is then
presented it will be used to parse the bytes.
There is no guarantee for what happens if two Keys disagree about
the type of a field; in particular there may be undefined values
and runtime errors. The data constructor for Key has to be
exported to the generated code, but is not exposed to the user by
Text.ProtocolBuffers.
| | Constructors | | Instances | |
|
|
|
The ExtKey class has three functions for user of the API:
putExt, getExt, and clearExt. The wireGetKey is used in
generated code.
There are two instances of this class, Maybe for optional message
fields and Seq for repeated message fields. This class allows
for uniform treatment of these two kinds of extension fields.
| | | Methods | | putExt :: Key c msg v -> c v -> msg -> msg | Source |
| Change or clear the value of a key in a message. Passing
Nothing with an optional key or an empty Seq with a repeated
key clears the value. This function thus maintains the invariant
that having a field number in the ExtField map means that the
field is set and not empty.
This should be only way to set the contents of a extension field.
| | | Access the key in the message. Optional have type (Key Maybe
msg v) and return type (Maybe v) while repeated fields have
type (Key Seq msg v) and return type (Seq v).
There are a few sources of errors with the lookup of the key:
- It may find unparsed bytes from loading the message. getExt
will attempt to parse the bytes as the key's value type, and
may fail. The parsing is done with the parseWireExt method
(which is not exported to user API).
- The wrong optional-key versus repeated-key type is a failure
- The wrong type of the value might be found in the map and
* cause a failure
The failures above should only happen if two different keys are
used with the same field number.
| | | | |
| | Instances | |
|
|
| class MessageAPI msg a b | msg a -> b where | Source |
|
| | Methods | | Access data in a message. The first argument is always the
message. The second argument can be one of 4 categories.
- The field name of a required field acts a simple retrieval of
the data from the message.
- The field name of an optional field will retreive the data if
it is set or lookup the default value if it is not set.
- The field name of a repeated field always retrieves the
(possibly empty) Seq of values.
- A Key for an optional or repeated value will act as the field
name does above, but if there is a type mismatch or parse error
it will use the defaultValue for optional types and an empty
sequence for repeated types.
| | | Check whether data is present in the message.
- Required fields always return True.
- Optional fields return whether a value is present.
- Repeated field return False if there are no values, otherwise
they return True.
- Keys return as optional or repeated, but checks only if the
field # is present. This assumes that there are no collisions
where more that one key refers to the same field number of this
message type.
|
| | Instances | |
|
|
| Internal types, functions, and classes
|
|
|
| This is used by the generated code
|
|
|
| This is used by the generated code. The data is serialized in
order of increasing field number.
|
|
|
| This is used by the generated code to get messages that have extensions
|
|
|
| This is used by the generated code to get messages that have extensions
|
|
|
| get a value from the wire into the message's ExtField. This is
used by getMessageExt and getBareMessageExt above.
|
|
|
| The Key and GPWitness GADTs use GPB as a shorthand for many
classes.
| | Instances | |
|
|
|
| ExtField is a newtype'd map from the numeric FieldId key to the
ExtFieldValue. This allows for the needed class instances.
| | Constructors | | Instances | |
|
|
|
ExtendMessage abstracts the operations of storing and
retrieving the ExtField from the message, and provides the
reflection needed to know the valid field numbers.
This only used internally.
| | | Methods | | | Instances | |
|
|
| Produced by Haddock version 2.3.0 |