           [field-name (when-not (empty? meta-string) (read-string meta-string))])))))
 
 (defn protobuf-load
+  "Load a protobuf of the given type from an array of bytes."
   ([^PersistentProtocolBufferMap$Def type ^bytes data]
      (when data
        (PersistentProtocolBufferMap/create type data)))

           (com.google.protobuf Descriptors$Descriptor Descriptors$FieldDescriptor CodedInputStream)
           (java.io InputStream OutputStream)))

(defn protobuf? [obj]
  (instance? PersistentProtocolBufferMap obj))

(defn protodef? [obj]
  (instance? PersistentProtocolBufferMap$Def obj))

(defn protodef [class]
  (if (or (protodef? class) (nil? class))
    class
    (PersistentProtocolBufferMap$Def/create class)))

(defmacro defprotobuf [sym & args]
  (let [class (apply str (interpose "$" (map name args)))]
    `(def ~sym (protodef ~class))))

(defn protobuf
  ([^PersistentProtocolBufferMap$Def type]
     (PersistentProtocolBufferMap/construct type {}))
  ([^PersistentProtocolBufferMap$Def type m]

  ([^PersistentProtocolBufferMap$Def type k v & kvs]
     (PersistentProtocolBufferMap/construct type (apply array-map k v kvs))))

(defn protodefault
  "Return the default empty protobuf of the given type."
  [type key]
  (let [type ^PersistentProtocolBufferMap$Def (protodef type)]
    (.defaultValue type key)))

(defn protofields
  "Return a map of the protobuf fields to the clojure.protobuf.Extensions metadata for each field."
  [type]
  (let [type ^PersistentProtocolBufferMap$Def (protodef type)
        type ^Descriptors$Descriptor (.getMessageType type)]
    (into {}
