           [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/parseFrom type in)))))


(defn protobuf-dump
  "Return the byte representation of the given protobuf."
  [^PersistentProtocolBufferMap p]
  (.toByteArray p))

(defn protobuf-seq
  "Lazily read a sequence of length-delimited protobufs of the specified type from the given input stream."
  [^PersistentProtocolBufferMap$Def type in]
  (lazy-seq
   (io!
    (let [^InputStream in (input-stream in)]
      (when-let [p (PersistentProtocolBufferMap/parseDelimitedFrom type in)]
        (cons p (protobuf-seq type in)))))))

(defn protobuf-write
  "Write the given protobufs to the given output stream, prefixing each with its length to delimit them."
  [out & ps]
  (io!
   (let [^OutputStream out (output-stream out)]
     (doseq [^PersistentProtocolBufferMap p ps]
       (.writeDelimitedTo p out))
     (.flush out))))

(defn append
  "Merge the given map into the protobuf. Equivalent to appending the byte representations."
  [^PersistentProtocolBufferMap p map]
  (.append p map))