 
 (defn take-varint
   "Takes a varint from `buffer`."
-  ^long [^Buffer buffer]
+  ^long [^MikronBuffer buffer]
   (loop [value math/c0
          shift (long 0)]
     (if (>= shift 64)

  #?(:clj {:inline (fn [buffer]
                     (when-not (util/can-have-meta? buffer)
                       (throw (ex-info "Invalid buffer" {:buffer buffer})))
                     `(.-byte-buffer ~(vary-meta buffer assoc :tag `Buffer)))})
  ^mikron.buffer.IMikronByteBuffer [^Buffer buffer]
  (.-byte-buffer buffer))

(defn get-bit-position
  "Gets the bit position of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-position* (get-bit-buffer ~buffer)))})
  ^long [^Buffer buffer]
  (get-bit-position* (get-bit-buffer buffer)))

(defn set-bit-position
  "Sets the bit position of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-position* (get-bit-buffer ~buffer) ~value))})
  [^Buffer buffer ^long value]
  (set-bit-position* (get-bit-buffer buffer) value))

(defn get-bit-index
  "Gets the bit index of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-index* (get-bit-buffer ~buffer)))})
  ^long [^Buffer buffer]
  (get-bit-index* (get-bit-buffer buffer)))

(defn set-bit-index
  "Sets the bit index of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-index* (get-bit-buffer ~buffer) ~value))})
  [^Buffer buffer ^long value]
  (set-bit-index* (get-bit-buffer buffer) value))

(defn get-bit-value
  "Gets the bit value of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-value* (get-bit-buffer ~buffer)))})
  ^long [^Buffer buffer]
  (get-bit-value* (get-bit-buffer buffer)))

(defn set-bit-value
  "Sets the bit value of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-value* (get-bit-buffer ~buffer) ~value))})
  [^Buffer buffer ^long value]
  (set-bit-value* (get-bit-buffer buffer) value))

;; Public delegated operations

    #?(:clj  (.order buffer (if value ByteOrder/LITTLE_ENDIAN ByteOrder/BIG_ENDIAN))
       :cljs (set! le value))))

(deftype MikronBuffer [^mikron.buffer.IMikronBitBuffer  bit-buffer
                       ^mikron.buffer.IMikronByteBuffer byte-buffer])

(defn get-bit-buffer
  "Gets the bit buffer of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     (when-not (util/can-have-meta? buffer)
                       (throw (ex-info "Invalid buffer" {:buffer buffer})))
                     `(.-bit-buffer ~(vary-meta buffer assoc :tag `MikronBuffer)))})
  ^mikron.buffer.IMikronBitBuffer [^MikronBuffer buffer]
  (.-bit-buffer buffer))

(defn get-byte-buffer
