Add checkout and rollback API in IM message builder (#5564)

Problem:
Need checkpoint API to get the previous IM TLV buffer state, when writen
data is oversized, need rollback API to get last good IM TLV buffer
State.

Summary of Changes:
-- Add Checkpoint API to Checkpoint the current tlv state into a TLVWriter
-- Add Rollback the request state into the checkpointed TLVWriter
-- Add unit test
Note: this is one sliced PR from PR 4800
diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp
index 38da5d4..4a8cf2b 100644
--- a/src/app/tests/TestMessageDef.cpp
+++ b/src/app/tests/TestMessageDef.cpp
@@ -1151,6 +1151,56 @@
     ParseReadRequest(apSuite, reader);
 }
 
+void CheckPointRollbackTest(nlTestSuite * apSuite, void * apContext)
+{
+    CHIP_ERROR err        = CHIP_NO_ERROR;
+    size_t NumDataElement = 0;
+    chip::System::PacketBufferTLVWriter writer;
+    chip::System::PacketBufferTLVReader reader;
+    AttributeDataList::Parser attributeDataListParser;
+    chip::TLV::TLVWriter checkpoint;
+    writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
+    AttributeDataList::Builder attributeDataListBuilder;
+    attributeDataListBuilder.Init(&writer);
+
+    // encode one attribute element
+    AttributeDataElement::Builder attributeDataElementBuilder1 = attributeDataListBuilder.CreateAttributeDataElementBuilder();
+    NL_TEST_ASSERT(apSuite, attributeDataListBuilder.GetError() == CHIP_NO_ERROR);
+    BuildAttributeDataElement(apSuite, attributeDataElementBuilder1);
+    // checkpoint
+    attributeDataListBuilder.Checkpoint(checkpoint);
+    // encode another attribute element
+    AttributeDataElement::Builder attributeDataElementBuilder2 = attributeDataListBuilder.CreateAttributeDataElementBuilder();
+    NL_TEST_ASSERT(apSuite, attributeDataListBuilder.GetError() == CHIP_NO_ERROR);
+    BuildAttributeDataElement(apSuite, attributeDataElementBuilder2);
+    // rollback to previous checkpoint
+    attributeDataListBuilder.Rollback(checkpoint);
+
+    attributeDataListBuilder.EndOfAttributeDataList();
+    NL_TEST_ASSERT(apSuite, attributeDataListBuilder.GetError() == CHIP_NO_ERROR);
+
+    chip::System::PacketBufferHandle buf;
+    err = writer.Finalize(&buf);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+    DebugPrettyPrint(buf);
+
+    reader.Init(std::move(buf));
+    err = reader.Next();
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+    err = attributeDataListParser.Init(reader);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    attributeDataListParser.CheckSchemaValidity();
+
+    while (CHIP_NO_ERROR == (err = attributeDataListParser.Next()))
+    {
+        ++NumDataElement;
+    }
+
+    NL_TEST_ASSERT(apSuite, NumDataElement == 1);
+}
+
 /**
  *   Test Suite. It lists all the test functions.
  */
@@ -1176,6 +1226,7 @@
                 NL_TEST_DEF("ReportDataTest", ReportDataTest),
                 NL_TEST_DEF("InvokeCommandTest", InvokeCommandTest),
                 NL_TEST_DEF("ReadRequestTest", ReadRequestTest),
+                NL_TEST_DEF("CheckPointRollbackTest", CheckPointRollbackTest),
                 NL_TEST_SENTINEL()
         };
 // clang-format on