PDL: Save copies in packet builders

Test: bluetooth_packet_parser_test
Change-Id: Ibf673a73109d003819445cb980d0fc85b1b7557c
diff --git a/gd/packet/parser/fields/vector_field.cc b/gd/packet/parser/fields/vector_field.cc
index b43e36a..589a5ed 100644
--- a/gd/packet/parser/fields/vector_field.cc
+++ b/gd/packet/parser/fields/vector_field.cc
@@ -132,6 +132,15 @@
   return true;
 }
 
+bool VectorField::GenBuilderMember(std::ostream& s) const {
+  if (type_def_ != nullptr) {
+    s << "const std::vector<" << type_def_->GetTypeName() << "> " << GetName();
+  } else {
+    s << "const std::vector<" << util::GetTypeForSize(element_size_) << "> " << GetName();
+  }
+  return true;
+}
+
 bool VectorField::HasParameterValidator() const {
   // Does not have parameter validator yet.
   // TODO: See comment in GenParameterValidator
diff --git a/gd/packet/parser/fields/vector_field.h b/gd/packet/parser/fields/vector_field.h
index d29759a..b7c0dfd 100644
--- a/gd/packet/parser/fields/vector_field.h
+++ b/gd/packet/parser/fields/vector_field.h
@@ -45,6 +45,8 @@
 
   virtual bool GenBuilderParameter(std::ostream& s) const override;
 
+  virtual bool GenBuilderMember(std::ostream& s) const override;
+
   virtual bool HasParameterValidator() const override;
 
   virtual void GenParameterValidator(std::ostream& s) const override;
diff --git a/gd/packet/parser/test/generated_packet_test.cc b/gd/packet/parser/test/generated_packet_test.cc
index b510522..250db6a 100644
--- a/gd/packet/parser/test/generated_packet_test.cc
+++ b/gd/packet/parser/test/generated_packet_test.cc
@@ -448,6 +448,10 @@
   auto packet = FixedArrayEnumBuilder::Create(fixed_array);
   ASSERT_EQ(fixed_array_enum.size(), packet->size());
 
+  // Verify that the packet is independent from the array.
+  std::array<ForArrays, 5> copy_array(fixed_array);
+  fixed_array[1] = ForArrays::ONE;
+
   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
   BitInserter it(*packet_bytes);
   packet->Serialize(it);
@@ -461,9 +465,9 @@
   auto view = FixedArrayEnumView::Create(packet_bytes_view);
   ASSERT_TRUE(view.IsValid());
   auto array = view.GetEnumArray();
-  ASSERT_EQ(fixed_array.size(), array.size());
-  for (size_t i = 0; i < fixed_array.size(); i++) {
-    ASSERT_EQ(array[i], fixed_array[i]);
+  ASSERT_EQ(copy_array.size(), array.size());
+  for (size_t i = 0; i < copy_array.size(); i++) {
+    ASSERT_EQ(array[i], copy_array[i]);
   }
 }
 
@@ -490,6 +494,10 @@
   auto packet = SizedArrayEnumBuilder::Create(sized_array);
   ASSERT_EQ(sized_array_enum.size(), packet->size());
 
+  // Copy the original vector and modify it to make sure the packet is independent.
+  std::vector<ForArrays> copy_array(sized_array);
+  sized_array[1] = ForArrays::ONE;
+
   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
   BitInserter it(*packet_bytes);
   packet->Serialize(it);
@@ -503,9 +511,9 @@
   auto view = SizedArrayEnumView::Create(packet_bytes_view);
   ASSERT_TRUE(view.IsValid());
   auto array = view.GetEnumArray();
-  ASSERT_EQ(sized_array.size(), array.size());
-  for (size_t i = 0; i < sized_array.size(); i++) {
-    ASSERT_EQ(array[i], sized_array[i]);
+  ASSERT_EQ(copy_array.size(), array.size());
+  for (size_t i = 0; i < copy_array.size(); i++) {
+    ASSERT_EQ(array[i], copy_array[i]);
   }
 }
 
@@ -731,6 +739,10 @@
   auto packet = OneStructBuilder::Create(trn);
   ASSERT_EQ(one_struct.size(), packet->size());
 
+  // Copy the original struct, then modify it to verify independence from the packet.
+  TwoRelatedNumbers copy_trn(trn);
+  trn.id_ = 2;
+
   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
   BitInserter it(*packet_bytes);
   packet->Serialize(it);
@@ -744,8 +756,8 @@
   auto view = OneStructView::Create(packet_bytes_view);
   ASSERT_TRUE(view.IsValid());
   auto one = view.GetOne();
-  ASSERT_EQ(one.id_, trn.id_);
-  ASSERT_EQ(one.count_, trn.count_);
+  ASSERT_EQ(one.id_, copy_trn.id_);
+  ASSERT_EQ(one.count_, copy_trn.count_);
 }
 
 vector<uint8_t> two_structs{
@@ -800,7 +812,14 @@
     count_array.push_back(trn);
   }
 
+  // Make a copy
+  std::vector<TwoRelatedNumbers> copy_array(count_array);
+
   auto packet = ArrayOfStructBuilder::Create(count_array);
+
+  // Change the original vector to make sure a copy was made.
+  count_array[0].id_ = count_array[0].id_ + 1;
+
   ASSERT_EQ(array_of_struct.size(), packet->size());
 
   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
@@ -816,10 +835,10 @@
   auto view = ArrayOfStructView::Create(packet_bytes_view);
   ASSERT_TRUE(view.IsValid());
   auto array = view.GetArray();
-  ASSERT_EQ(count_array.size(), array.size());
-  for (size_t i = 0; i < count_array.size(); i++) {
-    ASSERT_EQ(array[i].id_, count_array[i].id_);
-    ASSERT_EQ(array[i].count_, count_array[i].count_);
+  ASSERT_EQ(copy_array.size(), array.size());
+  for (size_t i = 0; i < copy_array.size(); i++) {
+    ASSERT_EQ(array[i].id_, copy_array[i].id_);
+    ASSERT_EQ(array[i].count_, copy_array[i].count_);
   }
 }