/*
 *
 *    Copyright (c) 2020-2023 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file contains definitions for working with data encoded in CHIP TLV format.
 *
 *      CHIP TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It
 *      shares many properties with the commonly used JSON serialization format while being considerably
 *      more compact over the wire.
 */

#pragma once

#include "TLVCommon.h"

#include "TLVBackingStore.h"
#include "TLVReader.h"

/**
 * @namespace chip::TLV
 *
 * Definitions for working with data encoded in CHIP TLV format.
 *
 * CHIP TLV is a generalized encoding method for simple structured data. It shares many properties
 * with the commonly used JSON serialization format while being considerably more compact over the wire.
 */

namespace chip {
namespace TLV {

/**
 * Provides a memory efficient encoder for writing data in CHIP TLV format.
 *
 * TLVWriter implements a forward-only, stream-style encoder for CHIP TLV data.  Applications
 * write data to an encoding by calling one of the writer's Put() methods, passing associated
 * tag and value information as necessary.  Similarly applications can encode TLV container types
 * (structures, arrays or paths) by calling the writer's OpenContainer() or EnterContainer()
 * methods.
 *
 * A TLVWriter object can write data directly to a fixed output buffer, or to memory provided by
 * a TLVBackingStore.
 */
class DLL_EXPORT TLVWriter
{
    friend class TLVUpdater;

public:
    /**
     * Initializes a TLVWriter object to write into a single output buffer.
     *
     * @note Applications must call Finalize() on the writer before using the contents of the output
     * buffer.
     *
     * @param[in]   buf     A pointer to the buffer into which TLV should be written.
     * @param[in]   maxLen  The maximum number of bytes that should be written to the output buffer.
     *
     */
    void Init(uint8_t * buf, size_t maxLen);

    /**
     * Initializes a TLVWriter object to write into a single output buffer
     * represented by a MutableSpan.  See documentation for the two-arg Init()
     * form for details.
     *
     */
    void Init(const MutableByteSpan & data) { Init(data.data(), data.size()); }

    /**
     * Initializes a TLVWriter object to write into a single output buffer
     * represented by a fixed-size byte array.  See documentation for the
     * two-arg Init() form for details.
     *
     */
    template <size_t N>
    void Init(uint8_t (&data)[N])
    {
        Init(data, N);
    }

    /**
     * Initializes a TLVWriter object to write into memory provided by a TLVBackingStore.
     *
     * @note Applications must call Finalize() on the writer before using the contents of the buffer.
     *
     * @param[in]   backingStore    A TLVBackingStore providing memory, which must outlive the TVLWriter.
     * @param[in]   maxLen          The maximum number of bytes that should be written to the output buffer.
     *
     * @retval #CHIP_NO_ERROR  If the method succeeded.
     * @retval other           Other error codes returned by TLVBackingStore::OnInit().
     */
    CHIP_ERROR Init(TLVBackingStore & backingStore, uint32_t maxLen = UINT32_MAX);

    /**
     * Finish the writing of a TLV encoding.
     *
     * The Finalize() method completes the process of writing a TLV encoding to the underlying output
     * buffer.  The method must be called by the application before it uses the contents of the buffer.
     * Finalize() can only be called when there are no container writers open for the current writer.
     * (See @p OpenContainer()).
     *
     * @retval #CHIP_NO_ERROR      If the encoding was finalized successfully.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              FinalizeBuffer() function.
     */
    CHIP_ERROR Finalize();

    /**
     * Reserve some buffer for encoding future fields.
     *
     * @retval #CHIP_NO_ERROR        Successfully reserved required buffer size.
     * @retval #CHIP_ERROR_NO_MEMORY The reserved buffer size cannot fits into the remaining buffer size.
     */
    CHIP_ERROR ReserveBuffer(uint32_t aBufferSize)
    {
        VerifyOrReturnError(mRemainingLen >= aBufferSize, CHIP_ERROR_NO_MEMORY);
        mReservedSize += aBufferSize;
        mRemainingLen -= aBufferSize;
        return CHIP_NO_ERROR;
    }

    /**
     * Release previously reserved buffer.
     *
     * @retval #CHIP_NO_ERROR        Successfully released reserved buffer size.
     * @retval #CHIP_ERROR_NO_MEMORY The released buffer is larger than previously reserved buffer size.
     */
    CHIP_ERROR UnreserveBuffer(uint32_t aBufferSize)
    {
        VerifyOrReturnError(mReservedSize >= aBufferSize, CHIP_ERROR_NO_MEMORY);
        mReservedSize -= aBufferSize;
        mRemainingLen += aBufferSize;
        return CHIP_NO_ERROR;
    }

    /**
     * Encodes a TLV signed integer value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, int8_t v);

    /**
     * Encodes a TLV signed integer value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     * @param[in]   preserveSize    True if the value should be encoded in the same number of bytes as
     *                              at the input type.  False if value should be encoded in the minimum
     *                              number of bytes necessary to represent the value.  Note: Applications
     *                              are strongly encouraged to set this parameter to false.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, int8_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v)
     */
    CHIP_ERROR Put(Tag tag, int16_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, int16_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v)
     */
    CHIP_ERROR Put(Tag tag, int32_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, int32_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v)
     */
    CHIP_ERROR Put(Tag tag, int64_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, int8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, int64_t v, bool preserveSize);

    /**
     * Encodes a TLV unsigned integer value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag. Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, uint8_t v);

    /**
     * Encodes a TLV unsigned integer value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     * @param[in]   preserveSize    True if the value should be encoded in the same number of bytes as
     *                              at the input type.  False if value should be encoded in the minimum
     *                              number of bytes necessary to represent the value.  Note: Applications
     *                              are strongly encouraged to set this parameter to false.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, uint8_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v)
     */
    CHIP_ERROR Put(Tag tag, uint16_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, uint16_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v)
     */
    CHIP_ERROR Put(Tag tag, uint32_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, uint32_t v, bool preserveSize);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v)
     */
    CHIP_ERROR Put(Tag tag, uint64_t v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, uint8_t v, bool preserveSize)
     */
    CHIP_ERROR Put(Tag tag, uint64_t v, bool preserveSize);

    /**
     * Encodes a TLV floating point value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, double v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, double v)
     */
    CHIP_ERROR Put(Tag tag, float v);

    /**
     * Encodes a TLV byte string value using ByteSpan class.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   data            A ByteSpan object containing the bytes string to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR Put(Tag tag, ByteSpan data);

    /**
     * static_cast to enumerations' underlying type when data is an enumeration.
     */
    template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
    CHIP_ERROR Put(Tag tag, T data)
    {
        return Put(tag, to_underlying(data));
    }

    /**
     *
     * Encodes an unsigned integer with bits corresponding to the flags set when data is a BitFlags
     */
    template <typename T>
    CHIP_ERROR Put(Tag tag, BitFlags<T> data)
    {
        return Put(tag, data.Raw());
    }

    /**
     *
     * Encodes an unsigned integer with bits corresponding to the flags set when data is a BitMask
     */
    template <typename T>
    CHIP_ERROR Put(Tag tag, BitMask<T> data)
    {
        return Put(tag, data.Raw());
    }

    /**
     * Encodes a TLV boolean value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   v               The value to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutBoolean(Tag tag, bool v);

    /**
     * @overload CHIP_ERROR TLVWriter::Put(Tag tag, bool v)
     */
    CHIP_ERROR Put(Tag tag, bool v)
    {
        /*
         * In TLV, boolean values are encoded as standalone tags without actual values, so we have a separate
         * PutBoolean method.
         */
        return PutBoolean(tag, v);
    }

    /**
     * Encodes a TLV byte string value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   buf             A pointer to a buffer containing the bytes string to be encoded.
     * @param[in]   len             The number of bytes to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutBytes(Tag tag, const uint8_t * buf, uint32_t len);

    /**
     * Encodes a TLV UTF8 string value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   buf             A pointer to the null-terminated UTF-8 string to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutString(Tag tag, const char * buf);

    /**
     * Encodes a TLV UTF8 string value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   buf             A pointer to the UTF-8 string to be encoded.
     * @param[in]   len             The length (in bytes) of the string to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutString(Tag tag, const char * buf, uint32_t len);

    /**
     * Encodes a TLV UTF8 string value that's passed in as a Span.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   str             A Span containing a pointer and a length of the string to be encoded.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutString(Tag tag, Span<const char> str);

    /**
     * @brief
     *   Encode the string output formatted according to the format in the TLV element.
     *
     * PutStringF is an analog of a sprintf where the output is stored in
     * a TLV element as opposed to a character buffer.  When extended
     * printf functionality is available, the function is able to output
     * the result string into a discontinuous underlying storage.  The
     * implementation supports the following printf enhancements:
     *
     * -- The platform supplies a callback-based `vcbprintf` that provides
     *    the ability to call a custom callback in place of putchar.
     *
     * -- The platform supplies a variant of `vsnprintf` called
     *    `vsnprintf_ex`, that behaves exactly like vsnprintf except it
     *    has provisions for omitting the first `n` characters of the
     *    output.
     *
     * Note that while the callback-based function may be the simplest and
     * use the least amount of code, the `vsprintf_ex` variety of
     * functions will consume less stack.
     *
     * If neither of the above is available, the function will allocate a
     * temporary buffer to hold the output, using Platform::MemoryAlloc().
     *
     * @param[in] tag The TLV tag to be encoded with the value, or @p
     *                AnonymousTag() if the value should be encoded without
     *                a tag.  Tag values should be constructed with one of
     *                the tag definition functions ProfileTag(),
     *                ContextTag() or CommonTag().
     *
     * @param[in] fmt The format string used to format the argument list.
     *                Follows the same syntax and rules as the format
     *                string for `printf` family of functions.
     *
     * @param[in] ... A list of arguments to be formatted in the output value
     *                according to fmt.
     *
     * @retval #CHIP_NO_ERROR  If the method succeeded.
     *
     * @retval other If underlying calls to TLVWriter methods --
     *               `WriteElementHead` or `GetNewBuffer` -- failed, their
     *               error is immediately forwarded up the call stack.
     */
    // The ENFORCE_FORMAT args are "off by one" because this is a class method,
    // with an implicit "this" as first arg.
    CHIP_ERROR PutStringF(Tag tag, const char * fmt, ...) ENFORCE_FORMAT(3, 4);

    /**
     * @brief
     *   Encode the string output formatted according to the format in the TLV element.
     *
     * PutStringF is an analog of a sprintf where the output is stored in
     * a TLV element as opposed to a character buffer.  When extended
     * printf functionality is available, the function is able to output
     * the result string into a discontinuous underlying storage.  The
     * implementation supports the following printf enhancements:
     *
     * -- The platform supplies a callback-based `vcbprintf` that provides
     *    the ability to call a custom callback in place of putchar.
     *
     * -- The platform supplies a variant of `vsnprintf` called
     *    `vsnprintf_ex`, that behaves exactly like vsnprintf except it
     *    has provisions for omitting the first `n` characters of the
     *    output.
     *
     * Note that while the callback-based function may be the simplest and
     * use the least amount of code, the `vsprintf_ex` variety of
     * functions will consume less stack.
     *
     * If neither of the above is available, the function will allocate a
     * temporary buffer to hold the output, using Platform::MemoryAlloc().
     *
     * @param[in] tag The TLV tag to be encoded with the value, or @p
     *                AnonymousTag() if the value should be encoded without
     *                a tag.  Tag values should be constructed with one of
     *                the tag definition functions ProfileTag(),
     *                ContextTag() or CommonTag().
     *
     * @param[in] fmt The format string used to format the argument list.
     *                Follows the same syntax and rules as the format
     *                string for `printf` family of functions.
     *
     * @param[in] ap A list of arguments to be formatted in the output value
     *                according to fmt.
     *
     * @retval #CHIP_NO_ERROR  If the method succeeded.
     *
     * @retval other If underlying calls to TLVWriter methods --
     *               `WriteElementHead` or `GetNewBuffer` -- failed, their
     *               error is immediately forwarded up the call stack.
     */
    // The ENFORCE_FORMAT args are "off by one" because this is a class method,
    // with an implicit "this" as first arg.
    CHIP_ERROR VPutStringF(Tag tag, const char * fmt, va_list ap) ENFORCE_FORMAT(3, 0);

    /**
     * Encodes a TLV null value.
     *
     * @param[in]   tag             The TLV tag to be encoded with the value, or @p AnonymousTag() if the
     *                              value should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutNull(Tag tag);

    /**
     * Copies a TLV element from a reader object into the writer.
     *
     * The CopyElement() method encodes a new TLV element whose type, tag and value are taken from a TLVReader
     * object. When the method is called, the supplied reader object is expected to be positioned on the
     * source TLV element. The newly encoded element will have the same type, tag and contents as the input
     * container.  If the supplied element is a TLV container (structure, array or path), the entire contents
     * of the container will be copied.
     *
     * @note This method requires the supplied TVLReader object to be reading from a single, contiguous
     * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any
     * other mode has undefined behavior.
     *
     * @param[in]   reader          A reference to a TLVReader object identifying a pre-encoded TLV
     *                              element that should be copied.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If the supplied reader is not positioned on an element.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_TLV_UNDERRUN
     *                              If the underlying TLV encoding associated with the supplied reader ended
     *                              prematurely.
     * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     *                              If the supplied reader encountered an invalid or unsupported TLV element
     *                              type.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the supplied reader encountered a TLV tag in an invalid context,
     *                              or if the supplied tag is invalid or inappropriate in the context in
     *                              which the new container is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer()
     *                              function associated with the reader object.
     *
     */
    CHIP_ERROR CopyElement(TLVReader & reader);

    /**
     * Copies a TLV element from a reader object into the writer.
     *
     * The CopyElement() method encodes a new TLV element whose type and value are taken from a TLVReader
     * object. When the method is called, the supplied reader object is expected to be positioned on the
     * source TLV element. The newly encoded element will have the same type and contents as the input
     * container, however the tag will be set to the specified argument.  If the supplied element is a
     * TLV container (structure, array or path), the entire contents of the container will be copied.
     *
     * @note This method requires the supplied TVLReader object to be reading from a single, contiguous
     * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any
     * other mode has undefined behavior.
     *
     * @param[in]   tag             The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                              the container should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   reader          A reference to a TLVReader object identifying a pre-encoded TLV
     *                              element whose type and value should be copied.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If the supplied reader is not positioned on an element.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_TLV_UNDERRUN
     *                              If the underlying TLV encoding associated with the supplied reader ended
     *                              prematurely.
     * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     *                              If the supplied reader encountered an invalid or unsupported TLV element
     *                              type.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the supplied reader encountered a TLV tag in an invalid context,
     *                              or if the supplied tag is invalid or inappropriate in the context in
     *                              which the new container is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer()
     *                              function associated with the reader object.
     *
     */
    CHIP_ERROR CopyElement(Tag tag, TLVReader & reader);

    /**
     * Begins encoding a new TLV container element.
     *
     * The StartContainer() method is used to write TLV container elements (structure, arrays or paths)
     * to an encoding.  The method takes the type and tag (if any) of the new container, and a reference
     * to a TLVType value which will be used to save the current context of the writer while it is being
     * used to write the container.
     *
     * Once the StartContainer() method returns, the application should use the current TLVWriter object to
     * write the elements of the container.  When finish, the application must call the EndContainer()
     * method to finish the encoding of the container.
     *
     * @param[in]   tag             The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                              the container should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   containerType   The type of container to encode.  Must be one of @p kTLVType_Structure,
     *                              @p kTLVType_Array or @p kTLVType_List.
     * @param[out]  outerContainerType
     *                              A reference to a TLVType value that will receive the context of the
     *                              writer.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_WRONG_TLV_TYPE
     *                              If the value specified for containerType is incorrect.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR StartContainer(Tag tag, TLVType containerType, TLVType & outerContainerType);

    /**
     * Completes the encoding of a TLV container element.
     *
     * The EndContainer() method completes the encoding of a TLV container element and restores the state
     * of a TLVWrite object after an earlier call to StartContainer().  For every call to StartContainer()
     * applications must make a corresponding call to EndContainer(), passing the TLVType value returned
     * by the StartContainer() call.  When EndContainer() returns, the writer object can be used to write
     * additional TLV elements that follow the container element.
     *
     * @note Any changes made to the configuration of the writer between the calls to StartContainer()
     * and EndContainer() are NOT undone by the call to EndContainer().  For example, a change to the
     * implicit profile id (@p ImplicitProfileId) will not be reversed when a container is ended.  Thus
     * it is the application's responsibility to adjust the configuration accordingly at the appropriate
     * times.
     *
     * @param[in] outerContainerType
     *                              The TLVType value that was returned by the StartContainer() method.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If a corresponding StartContainer() call was not made.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR EndContainer(TLVType outerContainerType);

    /**
     * Initializes a new TLVWriter object for writing the members of a TLV container element.
     *
     * The OpenContainer() method is used to write TLV container elements (structure, arrays or paths)
     * to an encoding.  The method takes the type and tag (if any) of the new container, and a reference
     * to a new writer object (the <em>container writer</em>) that will be initialized for the purpose
     * of writing the container's elements.  Applications write the members of the new container using
     * the container writer and then call CloseContainer() to complete the container encoding.
     *
     * While the container writer is open, applications must not make calls on or otherwise alter the state
     * of the parent writer.
     *
     * The container writer inherits various configuration properties from the parent writer.  These are:
     *
     * @li The implicit profile id (ImplicitProfileId)
     * @li The application data pointer (AppData)
     * @li The GetNewBuffer and FinalizeBuffer function pointers
     *
     * @note The StartContainer() method can be used as an alternative to OpenContainer() to write a
     * container element without initializing a new writer object.
     *
     * @param[in]   tag             The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                              the container should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   containerType   The type of container to encode.  Must be one of @p kTLVType_Structure,
     *                              @p kTLVType_Array or @p kTLVType_List.
     * @param[out]  containerWriter A reference to a TLVWriter object that will be initialized for
     *                              writing the members of the new container element. Any data
     *                              associated with the supplied object is overwritten.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_WRONG_TLV_TYPE
     *                              If the value specified for containerType is incorrect.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR OpenContainer(Tag tag, TLVType containerType, TLVWriter & containerWriter);

    /**
     * Completes the writing of a TLV container after a call to OpenContainer().
     *
     * The CloseContainer() method restores the state of a parent TLVWriter object after a call to
     * OpenContainer().  For every call to OpenContainer() applications must make a corresponding
     * call to CloseContainer(), passing a reference to the same container writer to both methods.
     *
     * When CloseContainer() returns, applications may continue to use the parent writer to write
     * additional TLV elements that appear after the container element.  At this point the supplied
     * container writer should be considered 'de-initialized' and must not be used without
     * re-initialization.
     *
     * @param[in] containerWriter   A reference to the TLVWriter object that was supplied to the
     *                              OpenContainer() method.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If the supplied container writer is not in the correct state.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If another container writer has been opened on the supplied
     *                              container writer and not yet closed.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If completing the encoding of the container would exceed the
     *                              limit on the maximum number of bytes specified when the writer
     *                              was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack
     *                              of memory.
     * @retval other                Other CHIP or platform-specific errors returned by the
     *                              configured TLVBackingStore.
     *
     */
    CHIP_ERROR CloseContainer(TLVWriter & containerWriter);

    /**
     * Encodes a TLV container element from a pre-encoded set of member elements
     *
     * The PutPreEncodedContainer() method encodes a new TLV container element (a structure, array or path)
     * containing a set of member elements taken from a pre-encoded buffer.  The input buffer is expected to
     * contain zero or more full-encoded TLV elements, with tags that conform to the rules associated with
     * the specified container type (e.g. structure members must have tags, while array members must not).
     *
     * The method encodes the entirety of the container element in one call.  When PutPreEncodedContainer()
     * returns, the writer object can be used to write additional TLV elements following the container element.
     *
     * @param[in]   tag             The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                              the container should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   containerType   The type of container to encode.  Must be one of @p kTLVType_Structure,
     *                              @p kTLVType_Array or @p kTLVType_List.
     * @param[in]   data            A pointer to a buffer containing zero of more encoded TLV elements that
     *                              will become the members of the new container.
     * @param[in]   dataLen         The number of bytes in the @p data buffer.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_WRONG_TLV_TYPE
     *                              If the value specified for containerType is incorrect.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the specified tag value is invalid or inappropriate in the context
     *                              in which the value is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR PutPreEncodedContainer(Tag tag, TLVType containerType, const uint8_t * data, uint32_t dataLen);

    /**
     * Copies a TLV container element from TLVReader object
     *
     * The CopyContainer() encodes a new TLV container element by copying a pre-encoded container element
     * located at the current position of a TLVReader object. The method writes the entirety of the new
     * container element in one call, copying the container's type, tag and elements from the source
     * encoding. When the method returns, the writer object can be used to write additional TLV elements
     * following the container element.
     *
     * @note This method requires the supplied TVLReader object to be reading from a single, contiguous
     * input buffer that contains the entirety of the underlying TLV encoding.
     *
     * @param[in]   container       A reference to a TLVReader object identifying the pre-encoded TLV
     *                              container to be copied.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INVALID_ARGUMENT
     *                              If the supplied reader uses a TLVBackingStore rather than a simple buffer.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If the supplied reader is not positioned on a container element.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_TLV_UNDERRUN
     *                              If the underlying TLV encoding associated with the supplied reader ended
     *                              prematurely.
     * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     *                              If the supplied reader encountered an invalid or unsupported TLV element
     *                              type.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the supplied reader encountered a TLV tag in an invalid context,
     *                              or if the tag associated with the source container is invalid or
     *                              inappropriate in the context in which the new container is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR CopyContainer(TLVReader & container);

    /**
     * Encodes a TLV container element from a pre-encoded set of member elements
     *
     * The CopyContainer() method encodes a new TLV container element (a structure, array or path)
     * containing a set of member elements taken from a TLVReader object. When the method is called, the
     * supplied reader object is expected to be positioned on a TLV container element. The newly encoded
     * container will have the same type and members as the input container.  The tag for the new
     * container is specified as an input parameter.
     *
     * When the method returns, the writer object can be used to write additional TLV elements following
     * the container element.
     *
     * @note This method requires the supplied TVLReader object to be reading from a single, contiguous
     * input buffer that contains the entirety of the underlying TLV encoding.
     *
     * @param[in]   tag             The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                              the container should be encoded without a tag.  Tag values should be
     *                              constructed with one of the tag definition functions ProfileTag(),
     *                              ContextTag() or CommonTag().
     * @param[in]   container       A reference to a TLVReader object identifying a pre-encoded TLV
     *                              container whose type and members should be copied.
     *
     * @retval #CHIP_NO_ERROR      If the method succeeded.
     * @retval #CHIP_ERROR_INVALID_ARGUMENT
     *                              If the supplied reader uses a TLVBackingStore rather than a simple buffer.
     * @retval #CHIP_ERROR_INCORRECT_STATE
     *                              If the supplied reader is not positioned on a container element.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                              If a container writer has been opened on the current writer and not
     *                              yet closed.
     * @retval #CHIP_ERROR_TLV_UNDERRUN
     *                              If the underlying TLV encoding associated with the supplied reader ended
     *                              prematurely.
     * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     *                              If the supplied reader encountered an invalid or unsupported TLV element
     *                              type.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                              If the supplied reader encountered a TLV tag in an invalid context,
     *                              or if the supplied tag is invalid or inappropriate in the context in
     *                              which the new container is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                              If writing the value would exceed the limit on the maximum number of
     *                              bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                              If an attempt to allocate an output buffer failed due to lack of
     *                              memory.
     * @retval other                Other CHIP or platform-specific errors returned by the configured
     *                              TLVBackingStore.
     *
     */
    CHIP_ERROR CopyContainer(Tag tag, TLVReader & container);

    /**
     * Encodes a TLV container element that contains member elements from a pre-encoded container
     *
     * The CopyContainer() method encodes a new TLV container element (a structure, array or path)
     * containing a set of member elements taken from the contents of a supplied pre-encoded container.
     * When the method is called, data in the supplied input buffer is parsed as a TLV container element
     * an a new container is written that has the same type and members as the input container.  The tag
     * for the new container is specified as an input parameter.
     *
     * When the method returns, the writer object can be used to write additional TLV elements following
     * the container element.
     *
     * @param[in] tag                   The TLV tag to be encoded with the container, or @p AnonymousTag() if
     *                                  the container should be encoded without a tag.  Tag values should be
     *                                  constructed with one of the tag definition functions ProfileTag(),
     *                                  ContextTag() or CommonTag().
     * @param[in] encodedContainer      A buffer containing a pre-encoded TLV container whose type and members
     *                                  should be copied.
     * @param[in] encodedContainerLen   The length in bytes of the pre-encoded container.
     *
     * @retval #CHIP_NO_ERROR          If the method succeeded.
     * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN
     *                                  If a container writer has been opened on the current writer and not
     *                                  yet closed.
     * @retval #CHIP_ERROR_TLV_UNDERRUN
     *                                  If the encoded container ended prematurely.
     * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT
     *                                  If the encoded container contained an invalid or unsupported TLV element type.
     * @retval #CHIP_ERROR_INVALID_TLV_TAG
     *                                  If the encoded container contained a TLV tag in an invalid context,
     *                                  or if the supplied tag is invalid or inappropriate in the context in
     *                                  which the new container is being written.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL
     *                                  If writing the value would exceed the limit on the maximum number of
     *                                  bytes specified when the writer was initialized.
     * @retval #CHIP_ERROR_NO_MEMORY
     *                                  If an attempt to allocate an output buffer failed due to lack of
     *                                  memory.
     * @retval other                    Other CHIP or platform-specific errors returned by the configured
     *                                  TLVBackingStore.
     *
     */
    CHIP_ERROR CopyContainer(Tag tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen);

    /**
     * Returns the type of container within which the TLVWriter is currently writing.
     *
     * The GetContainerType() method returns the type of the TLV container within which the TLVWriter
     * is currently writing.  If the TLVWriter is not writing elements within a container (i.e. if writing
     * at the outer-most level of an encoding) the method returns kTLVType_NotSpecified.
     *
     * @return  The TLVType of the current container, or kTLVType_NotSpecified if the TLVWriter is not
     *          writing elements within a container.
     */
    TLVType GetContainerType() const { return mContainerType; }

    /**
     * Returns the total number of bytes written since the writer was initialized.
     *
     * @return Total number of bytes written since the writer was initialized.
     */
    uint32_t GetLengthWritten() const { return mLenWritten; }

    /**
     * Returns the total remaining number of bytes for current tlv writer
     *
     * @return the total remaining number of bytes.
     */
    uint32_t GetRemainingFreeLength() const { return mRemainingLen; }
    /**
     * The profile id of tags that should be encoded in implicit form.
     *
     * When a writer is asked to encode a new element, if the profile id of the tag associated with the
     * new element matches the value of the @p ImplicitProfileId member, the writer will encode the tag
     * in implicit form, omitting the profile id in the process.
     *
     * By default, the @p ImplicitProfileId property is set to kProfileIdNotSpecified, which instructs
     * the writer not to emit implicitly encoded tags.  Applications can set @p ImplicitProfileId at any
     * time to enable encoding tags in implicit form starting at the current point in the encoding.  The
     * appropriate profile id to set is usually dependent on the context of the application or protocol
     * being spoken.
     *
     * @note The value of the @p ImplicitProfileId member affects the encoding of profile-specific
     * tags only; the encoding of context-specific tags is unchanged.
     */
    uint32_t ImplicitProfileId;

    /**
     * A pointer field that can be used for application-specific data.
     */
    void * AppData;

protected:
    TLVBackingStore * mBackingStore;
    uint8_t * mBufStart;
    uint8_t * mWritePoint;
    uint32_t mRemainingLen;
    uint32_t mLenWritten;
    uint32_t mMaxLen;
    uint32_t mReservedSize;
    TLVType mContainerType;

private:
    bool mContainerOpen;
    bool mCloseContainerReserved;

protected:
    bool IsContainerOpen() const { return mContainerOpen; }
    void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; }

    enum
    {
        kEndOfContainerMarkerSize = 1, /**< Size of the EndOfContainer marker, used in reserving space. */
    };

    /**
     * @brief
     *   Determine whether the container should reserve space for the
     *   CloseContainer symbol at the point of starting / opening the
     *   container.
     */
    bool IsCloseContainerReserved() const { return mCloseContainerReserved; }

    /**
     * @brief
     * Set whether the container should reserve the space for the
     * CloseContainer symbol at the point of starting / opening the
     * container.
     */
    void SetCloseContainerReserved(bool aCloseContainerReserved) { mCloseContainerReserved = aCloseContainerReserved; }

#if CONFIG_HAVE_VCBPRINTF
    static void TLVWriterPutcharCB(uint8_t c, void * appState);
#endif
    CHIP_ERROR WriteElementHead(TLVElementType elemType, Tag tag, uint64_t lenOrVal);
    CHIP_ERROR WriteElementWithData(TLVType type, Tag tag, const uint8_t * data, uint32_t dataLen);
    CHIP_ERROR WriteData(const uint8_t * p, uint32_t len);
};

/*
 * A TLVWriter that is backed by a scoped memory buffer that is owned by the writer.
 */
class ScopedBufferTLVWriter : public TLVWriter
{
public:
    /*
     * Construct and initialize the writer by taking ownership of the provided scoped buffer.
     */
    ScopedBufferTLVWriter(Platform::ScopedMemoryBuffer<uint8_t> && buffer, size_t dataLen)
    {
        mBuffer = std::move(buffer);
        Init(mBuffer.Get(), dataLen);
    }

    /*
     * Finalize the writer and take back the buffer owned by the writer. This transfers its
     * ownership to the provided buffer reference. This also re-initializes the writer with
     * a null buffer to prevent further inadvertent use of the writer.
     */
    CHIP_ERROR Finalize(Platform::ScopedMemoryBuffer<uint8_t> & buffer)
    {
        ReturnErrorOnFailure(TLVWriter::Finalize());
        buffer = std::move(mBuffer);
        Init(nullptr, 0);
        return CHIP_NO_ERROR;
    }

private:
    Platform::ScopedMemoryBuffer<uint8_t> mBuffer;
};

} // namespace TLV
} // namespace chip
