@@ -1876,6 +1876,387 @@ TEST_F(StressTest, LargeRepeatedField)
18761876 }
18771877}
18781878
1879+ // =====================================================================
1880+ // Packed and unpacked repeated field parse tests
1881+ // Wire bytes are built manually to exercise each encoding path directly.
1882+ // The existing RepeatedRoundTripTest suite always serializes packed (proto3
1883+ // default). These tests feed raw unpacked wire to verify the new unpacked
1884+ // path, and mixed (packed-first) wire to verify both encodings accumulate
1885+ // into the same field.
1886+ // =====================================================================
1887+
1888+ // Additional wire-building helpers for repeated fields.
1889+
1890+ // N separate (tag, varint64) pairs — unpacked repeated varint.
1891+ static std::string MakeUnpackedVarintRepeated (int field_number, const std::vector<uint64_t >& values)
1892+ {
1893+ std::string out;
1894+ for (uint64_t v : values) out += MakeVarintField (field_number, v);
1895+ return out;
1896+ }
1897+
1898+ // Single (tag, length, varints…) — packed repeated varint.
1899+ static std::string MakePackedVarintRepeated (int field_number, const std::vector<uint64_t >& values)
1900+ {
1901+ std::string payload;
1902+ {
1903+ google::protobuf::io::StringOutputStream sos (&payload);
1904+ google::protobuf::io::CodedOutputStream cos (&sos);
1905+ for (uint64_t v : values) cos.WriteVarint64 (v);
1906+ }
1907+ return MakeLenDelimField (field_number, payload);
1908+ }
1909+
1910+ // N separate fixed32 tags — unpacked repeated fixed32.
1911+ static std::string MakeUnpackedFixed32Repeated (int field_number, const std::vector<uint32_t >& values)
1912+ {
1913+ std::string out;
1914+ for (uint32_t v : values) out += MakeFixed32Field (field_number, v);
1915+ return out;
1916+ }
1917+
1918+ // Single packed repeated fixed32.
1919+ static std::string MakePackedFixed32Repeated (int field_number, const std::vector<uint32_t >& values)
1920+ {
1921+ std::string payload;
1922+ {
1923+ google::protobuf::io::StringOutputStream sos (&payload);
1924+ google::protobuf::io::CodedOutputStream cos (&sos);
1925+ for (uint32_t v : values) cos.WriteLittleEndian32 (v);
1926+ }
1927+ return MakeLenDelimField (field_number, payload);
1928+ }
1929+
1930+ // N separate fixed64 tags — unpacked repeated fixed64.
1931+ static std::string MakeUnpackedFixed64Repeated (int field_number, const std::vector<uint64_t >& values)
1932+ {
1933+ std::string out;
1934+ for (uint64_t v : values) out += MakeFixed64Field (field_number, v);
1935+ return out;
1936+ }
1937+
1938+ // Single packed repeated fixed64.
1939+ static std::string MakePackedFixed64Repeated (int field_number, const std::vector<uint64_t >& values)
1940+ {
1941+ std::string payload;
1942+ {
1943+ google::protobuf::io::StringOutputStream sos (&payload);
1944+ google::protobuf::io::CodedOutputStream cos (&sos);
1945+ for (uint64_t v : values) cos.WriteLittleEndian64 (v);
1946+ }
1947+ return MakeLenDelimField (field_number, payload);
1948+ }
1949+
1950+ class PackedUnpackedTest : public ::testing::Test {};
1951+
1952+ // ---- Unpacked: all 14 scalar types ----
1953+
1954+ TEST_F (PackedUnpackedTest, Unpacked_Int32)
1955+ {
1956+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::Int32Value, true );
1957+ std::string wire = MakeUnpackedVarintRepeated (1 , {10 , 20 , 30 });
1958+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
1959+
1960+ LVMessage msg (meta);
1961+ ASSERT_TRUE (msg.ParseFromString (wire));
1962+ auto vals = GetRepeatedValue<int >(msg, 1 );
1963+ ASSERT_EQ (vals.size (), 3u );
1964+ EXPECT_EQ (vals[0 ], 10 );
1965+ EXPECT_EQ (vals[1 ], 20 );
1966+ EXPECT_EQ (vals[2 ], 30 );
1967+ }
1968+
1969+ TEST_F (PackedUnpackedTest, Unpacked_Int64)
1970+ {
1971+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::Int64Value, true );
1972+ std::string wire = MakeUnpackedVarintRepeated (1 , {
1973+ static_cast <uint64_t >(1000000000000LL ),
1974+ static_cast <uint64_t >(2000000000000LL )});
1975+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
1976+
1977+ LVMessage msg (meta);
1978+ ASSERT_TRUE (msg.ParseFromString (wire));
1979+ auto vals = GetRepeatedValue<int64_t >(msg, 1 );
1980+ ASSERT_EQ (vals.size (), 2u );
1981+ EXPECT_EQ (vals[0 ], 1000000000000LL );
1982+ EXPECT_EQ (vals[1 ], 2000000000000LL );
1983+ }
1984+
1985+ TEST_F (PackedUnpackedTest, Unpacked_UInt32)
1986+ {
1987+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::UInt32Value, true );
1988+ std::string wire = MakeUnpackedVarintRepeated (1 , {100u , 200u , 300u });
1989+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
1990+
1991+ LVMessage msg (meta);
1992+ ASSERT_TRUE (msg.ParseFromString (wire));
1993+ auto vals = GetRepeatedValue<uint32_t >(msg, 1 );
1994+ ASSERT_EQ (vals.size (), 3u );
1995+ EXPECT_EQ (vals[0 ], 100u );
1996+ EXPECT_EQ (vals[1 ], 200u );
1997+ EXPECT_EQ (vals[2 ], 300u );
1998+ }
1999+
2000+ TEST_F (PackedUnpackedTest, Unpacked_UInt64)
2001+ {
2002+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::UInt64Value, true );
2003+ std::string wire = MakeUnpackedVarintRepeated (1 , {1000u , 2000u , 3000u });
2004+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2005+
2006+ LVMessage msg (meta);
2007+ ASSERT_TRUE (msg.ParseFromString (wire));
2008+ auto vals = GetRepeatedValue<uint64_t >(msg, 1 );
2009+ ASSERT_EQ (vals.size (), 3u );
2010+ EXPECT_EQ (vals[0 ], 1000ULL );
2011+ EXPECT_EQ (vals[1 ], 2000ULL );
2012+ EXPECT_EQ (vals[2 ], 3000ULL );
2013+ }
2014+
2015+ TEST_F (PackedUnpackedTest, Unpacked_Bool)
2016+ {
2017+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::BoolValue, true );
2018+ std::string wire = MakeUnpackedVarintRepeated (1 , {1 , 0 , 1 }); // true, false, true
2019+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2020+
2021+ LVMessage msg (meta);
2022+ ASSERT_TRUE (msg.ParseFromString (wire));
2023+ auto vals = GetRepeatedValue<bool >(msg, 1 );
2024+ ASSERT_EQ (vals.size (), 3u );
2025+ EXPECT_EQ (vals[0 ], true );
2026+ EXPECT_EQ (vals[1 ], false );
2027+ EXPECT_EQ (vals[2 ], true );
2028+ }
2029+
2030+ TEST_F (PackedUnpackedTest, Unpacked_Enum)
2031+ {
2032+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::EnumValue, true );
2033+ std::string wire = MakeUnpackedVarintRepeated (1 , {0 , 1 , 2 });
2034+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2035+
2036+ LVMessage msg (meta);
2037+ ASSERT_TRUE (msg.ParseFromString (wire));
2038+ auto vals = GetRepeatedValue<int >(msg, 1 );
2039+ ASSERT_EQ (vals.size (), 3u );
2040+ EXPECT_EQ (vals[0 ], 0 );
2041+ EXPECT_EQ (vals[1 ], 1 );
2042+ EXPECT_EQ (vals[2 ], 2 );
2043+ }
2044+
2045+ TEST_F (PackedUnpackedTest, Unpacked_SInt32)
2046+ {
2047+ using WFL = google::protobuf::internal::WireFormatLite;
2048+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::SInt32Value, true );
2049+ // Zigzag-encode the values before putting them on the wire.
2050+ std::string wire = MakeUnpackedVarintRepeated (1 , {
2051+ WFL::ZigZagEncode32 (-1 ),
2052+ WFL::ZigZagEncode32 (1 ),
2053+ WFL::ZigZagEncode32 (-100 )});
2054+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2055+
2056+ LVMessage msg (meta);
2057+ ASSERT_TRUE (msg.ParseFromString (wire));
2058+ auto vals = GetRepeatedValue<int32_t >(msg, 1 );
2059+ ASSERT_EQ (vals.size (), 3u );
2060+ EXPECT_EQ (vals[0 ], -1 );
2061+ EXPECT_EQ (vals[1 ], 1 );
2062+ EXPECT_EQ (vals[2 ], -100 );
2063+ }
2064+
2065+ TEST_F (PackedUnpackedTest, Unpacked_SInt64)
2066+ {
2067+ using WFL = google::protobuf::internal::WireFormatLite;
2068+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::SInt64Value, true );
2069+ std::string wire = MakeUnpackedVarintRepeated (1 , {
2070+ WFL::ZigZagEncode64 (-1LL ),
2071+ WFL::ZigZagEncode64 (1LL ),
2072+ WFL::ZigZagEncode64 (-1000000000000LL )});
2073+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2074+
2075+ LVMessage msg (meta);
2076+ ASSERT_TRUE (msg.ParseFromString (wire));
2077+ auto vals = GetRepeatedValue<int64_t >(msg, 1 );
2078+ ASSERT_EQ (vals.size (), 3u );
2079+ EXPECT_EQ (vals[0 ], -1LL );
2080+ EXPECT_EQ (vals[1 ], 1LL );
2081+ EXPECT_EQ (vals[2 ], -1000000000000LL );
2082+ }
2083+
2084+ TEST_F (PackedUnpackedTest, Unpacked_Float)
2085+ {
2086+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::FloatValue, true );
2087+ float f0 = 1 .5f , f1 = -2 .5f , f2 = 0 .0f ;
2088+ uint32_t u0, u1, u2;
2089+ memcpy (&u0, &f0, 4 ); memcpy (&u1, &f1, 4 ); memcpy (&u2, &f2, 4 );
2090+ std::string wire = MakeUnpackedFixed32Repeated (1 , {u0, u1, u2});
2091+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2092+
2093+ LVMessage msg (meta);
2094+ ASSERT_TRUE (msg.ParseFromString (wire));
2095+ auto vals = GetRepeatedValue<float >(msg, 1 );
2096+ ASSERT_EQ (vals.size (), 3u );
2097+ EXPECT_FLOAT_EQ (vals[0 ], 1 .5f );
2098+ EXPECT_FLOAT_EQ (vals[1 ], -2 .5f );
2099+ EXPECT_FLOAT_EQ (vals[2 ], 0 .0f );
2100+ }
2101+
2102+ TEST_F (PackedUnpackedTest, Unpacked_Double)
2103+ {
2104+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::DoubleValue, true );
2105+ double d0 = 3.14 , d1 = -2.718 ;
2106+ uint64_t u0, u1;
2107+ memcpy (&u0, &d0, 8 ); memcpy (&u1, &d1, 8 );
2108+ std::string wire = MakeUnpackedFixed64Repeated (1 , {u0, u1});
2109+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2110+
2111+ LVMessage msg (meta);
2112+ ASSERT_TRUE (msg.ParseFromString (wire));
2113+ auto vals = GetRepeatedValue<double >(msg, 1 );
2114+ ASSERT_EQ (vals.size (), 2u );
2115+ EXPECT_DOUBLE_EQ (vals[0 ], 3.14 );
2116+ EXPECT_DOUBLE_EQ (vals[1 ], -2.718 );
2117+ }
2118+
2119+ TEST_F (PackedUnpackedTest, Unpacked_Fixed32)
2120+ {
2121+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::Fixed32Value, true );
2122+ std::string wire = MakeUnpackedFixed32Repeated (1 , {0xDEADBEEFu , 42u , 0u });
2123+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2124+
2125+ LVMessage msg (meta);
2126+ ASSERT_TRUE (msg.ParseFromString (wire));
2127+ auto vals = GetRepeatedValue<uint32_t >(msg, 1 );
2128+ ASSERT_EQ (vals.size (), 3u );
2129+ EXPECT_EQ (vals[0 ], 0xDEADBEEFu );
2130+ EXPECT_EQ (vals[1 ], 42u );
2131+ EXPECT_EQ (vals[2 ], 0u );
2132+ }
2133+
2134+ TEST_F (PackedUnpackedTest, Unpacked_Fixed64)
2135+ {
2136+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::Fixed64Value, true );
2137+ std::string wire = MakeUnpackedFixed64Repeated (1 , {0xDEADBEEFCAFEBABEULL , 0ULL });
2138+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2139+
2140+ LVMessage msg (meta);
2141+ ASSERT_TRUE (msg.ParseFromString (wire));
2142+ auto vals = GetRepeatedValue<uint64_t >(msg, 1 );
2143+ ASSERT_EQ (vals.size (), 2u );
2144+ EXPECT_EQ (vals[0 ], 0xDEADBEEFCAFEBABEULL );
2145+ EXPECT_EQ (vals[1 ], 0ULL );
2146+ }
2147+
2148+ TEST_F (PackedUnpackedTest, Unpacked_SFixed32)
2149+ {
2150+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::SFixed32Value, true );
2151+ int32_t v0 = -12345 , v1 = 67890 ;
2152+ std::string wire = MakeUnpackedFixed32Repeated (1 , {
2153+ static_cast <uint32_t >(v0), static_cast <uint32_t >(v1)});
2154+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2155+
2156+ LVMessage msg (meta);
2157+ ASSERT_TRUE (msg.ParseFromString (wire));
2158+ auto vals = GetRepeatedValue<int32_t >(msg, 1 );
2159+ ASSERT_EQ (vals.size (), 2u );
2160+ EXPECT_EQ (vals[0 ], -12345 );
2161+ EXPECT_EQ (vals[1 ], 67890 );
2162+ }
2163+
2164+ TEST_F (PackedUnpackedTest, Unpacked_SFixed64)
2165+ {
2166+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::SFixed64Value, true );
2167+ int64_t v0 = -9876543210LL , v1 = 1234567890LL ;
2168+ std::string wire = MakeUnpackedFixed64Repeated (1 , {
2169+ static_cast <uint64_t >(v0), static_cast <uint64_t >(v1)});
2170+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2171+
2172+ LVMessage msg (meta);
2173+ ASSERT_TRUE (msg.ParseFromString (wire));
2174+ auto vals = GetRepeatedValue<int64_t >(msg, 1 );
2175+ ASSERT_EQ (vals.size (), 2u );
2176+ EXPECT_EQ (vals[0 ], -9876543210LL );
2177+ EXPECT_EQ (vals[1 ], 1234567890LL );
2178+ }
2179+
2180+ // ---- Mixed: packed batch first, then individual unpacked elements ----
2181+ // The protobuf spec allows mixing both encodings for the same repeated field.
2182+ // The packed path creates the entry; the unpacked path finds and appends to it.
2183+
2184+ TEST_F (PackedUnpackedTest, Mixed_PackedThenUnpacked_Int32)
2185+ {
2186+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::Int32Value, true );
2187+ // Packed batch [1, 2, 3], then two unpacked elements 4 and 5.
2188+ std::string wire = MakePackedVarintRepeated (1 , {1 , 2 , 3 })
2189+ + MakeUnpackedVarintRepeated (1 , {4 , 5 });
2190+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2191+
2192+ LVMessage msg (meta);
2193+ ASSERT_TRUE (msg.ParseFromString (wire));
2194+ auto vals = GetRepeatedValue<int >(msg, 1 );
2195+ ASSERT_EQ (vals.size (), 5u );
2196+ EXPECT_EQ (vals[0 ], 1 );
2197+ EXPECT_EQ (vals[1 ], 2 );
2198+ EXPECT_EQ (vals[2 ], 3 );
2199+ EXPECT_EQ (vals[3 ], 4 );
2200+ EXPECT_EQ (vals[4 ], 5 );
2201+ }
2202+
2203+ TEST_F (PackedUnpackedTest, Mixed_PackedThenUnpacked_Float)
2204+ {
2205+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::FloatValue, true );
2206+ float f0 = 1 .0f , f1 = 2 .0f , f2 = 3 .0f ;
2207+ uint32_t u0, u1, u2;
2208+ memcpy (&u0, &f0, 4 ); memcpy (&u1, &f1, 4 ); memcpy (&u2, &f2, 4 );
2209+ // Packed [1.0, 2.0], then unpacked 3.0.
2210+ std::string wire = MakePackedFixed32Repeated (1 , {u0, u1})
2211+ + MakeUnpackedFixed32Repeated (1 , {u2});
2212+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2213+
2214+ LVMessage msg (meta);
2215+ ASSERT_TRUE (msg.ParseFromString (wire));
2216+ auto vals = GetRepeatedValue<float >(msg, 1 );
2217+ ASSERT_EQ (vals.size (), 3u );
2218+ EXPECT_FLOAT_EQ (vals[0 ], 1 .0f );
2219+ EXPECT_FLOAT_EQ (vals[1 ], 2 .0f );
2220+ EXPECT_FLOAT_EQ (vals[2 ], 3 .0f );
2221+ }
2222+
2223+ TEST_F (PackedUnpackedTest, Mixed_PackedThenUnpacked_Double)
2224+ {
2225+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::DoubleValue, true );
2226+ double d0 = 1.0 , d1 = 2.0 , d2 = 3.0 ;
2227+ uint64_t u0, u1, u2;
2228+ memcpy (&u0, &d0, 8 ); memcpy (&u1, &d1, 8 ); memcpy (&u2, &d2, 8 );
2229+ std::string wire = MakePackedFixed64Repeated (1 , {u0, u1})
2230+ + MakeUnpackedFixed64Repeated (1 , {u2});
2231+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2232+
2233+ LVMessage msg (meta);
2234+ ASSERT_TRUE (msg.ParseFromString (wire));
2235+ auto vals = GetRepeatedValue<double >(msg, 1 );
2236+ ASSERT_EQ (vals.size (), 3u );
2237+ EXPECT_DOUBLE_EQ (vals[0 ], 1.0 );
2238+ EXPECT_DOUBLE_EQ (vals[1 ], 2.0 );
2239+ EXPECT_DOUBLE_EQ (vals[2 ], 3.0 );
2240+ }
2241+
2242+ TEST_F (PackedUnpackedTest, Mixed_PackedThenUnpacked_SInt32)
2243+ {
2244+ using WFL = google::protobuf::internal::WireFormatLite;
2245+ auto meta = MakeSingleFieldMetadata (1 , LVMessageMetadataType::SInt32Value, true );
2246+ // Packed batch [-1, 0], then unpacked 1.
2247+ std::string wire = MakePackedVarintRepeated (1 , {WFL::ZigZagEncode32 (-1 ), WFL::ZigZagEncode32 (0 )})
2248+ + MakeUnpackedVarintRepeated (1 , {WFL::ZigZagEncode32 (1 )});
2249+ std::cout << " [wire] " << wire.size () << " byte(s):\n " << HexDump (wire);
2250+
2251+ LVMessage msg (meta);
2252+ ASSERT_TRUE (msg.ParseFromString (wire));
2253+ auto vals = GetRepeatedValue<int32_t >(msg, 1 );
2254+ ASSERT_EQ (vals.size (), 3u );
2255+ EXPECT_EQ (vals[0 ], -1 );
2256+ EXPECT_EQ (vals[1 ], 0 );
2257+ EXPECT_EQ (vals[2 ], 1 );
2258+ }
2259+
18792260// =====================================================================
18802261// main
18812262// =====================================================================
0 commit comments