@@ -84,6 +84,12 @@ async def deexternalize_payloads_async(
8484# Internal recursive walkers – sync
8585# ------------------------------------------------------------------
8686
87+ def _is_map_field (fd ) -> bool :
88+ """Return True if the field descriptor represents a protobuf map field."""
89+ mt = fd .message_type
90+ return mt is not None and fd .is_repeated and mt .GetOptions ().map_entry
91+
92+
8793def _walk_and_externalize (
8894 msg : proto_message .Message ,
8995 store : PayloadStore ,
@@ -95,7 +101,21 @@ def _walk_and_externalize(
95101 if fd .message_type is None :
96102 continue
97103
98- if fd .is_repeated :
104+ if _is_map_field (fd ):
105+ # Map fields: iterate values. ScalarMap values are not
106+ # messages and will be skipped by the isinstance check.
107+ for map_value in getattr (msg , fd .name ).values ():
108+ if isinstance (map_value , proto_message .Message ):
109+ if isinstance (map_value , wrappers_pb2 .StringValue ):
110+ _try_externalize_field (
111+ fd .name , map_value , store ,
112+ threshold , max_bytes , instance_id ,
113+ )
114+ else :
115+ _walk_and_externalize (
116+ map_value , store , threshold , max_bytes , instance_id
117+ )
118+ elif fd .is_repeated :
99119 value = getattr (msg , fd .name )
100120 for item in value :
101121 if isinstance (item , proto_message .Message ):
@@ -162,7 +182,14 @@ def _walk_and_deexternalize(
162182 if fd .message_type is None :
163183 continue
164184
165- if fd .is_repeated :
185+ if _is_map_field (fd ):
186+ for map_value in getattr (msg , fd .name ).values ():
187+ if isinstance (map_value , proto_message .Message ):
188+ if isinstance (map_value , wrappers_pb2 .StringValue ):
189+ _try_deexternalize_field (map_value , store )
190+ else :
191+ _walk_and_deexternalize (map_value , store )
192+ elif fd .is_repeated :
166193 value = getattr (msg , fd .name )
167194 for item in value :
168195 if isinstance (item , proto_message .Message ):
@@ -207,7 +234,19 @@ async def _walk_and_externalize_async(
207234 if fd .message_type is None :
208235 continue
209236
210- if fd .is_repeated :
237+ if _is_map_field (fd ):
238+ for map_value in getattr (msg , fd .name ).values ():
239+ if isinstance (map_value , proto_message .Message ):
240+ if isinstance (map_value , wrappers_pb2 .StringValue ):
241+ await _try_externalize_field_async (
242+ fd .name , map_value , store ,
243+ threshold , max_bytes , instance_id ,
244+ )
245+ else :
246+ await _walk_and_externalize_async (
247+ map_value , store , threshold , max_bytes , instance_id ,
248+ )
249+ elif fd .is_repeated :
211250 value = getattr (msg , fd .name )
212251 for item in value :
213252 if isinstance (item , proto_message .Message ):
@@ -273,7 +312,14 @@ async def _walk_and_deexternalize_async(
273312 if fd .message_type is None :
274313 continue
275314
276- if fd .is_repeated :
315+ if _is_map_field (fd ):
316+ for map_value in getattr (msg , fd .name ).values ():
317+ if isinstance (map_value , proto_message .Message ):
318+ if isinstance (map_value , wrappers_pb2 .StringValue ):
319+ await _try_deexternalize_field_async (map_value , store )
320+ else :
321+ await _walk_and_deexternalize_async (map_value , store )
322+ elif fd .is_repeated :
277323 value = getattr (msg , fd .name )
278324 for item in value :
279325 if isinstance (item , proto_message .Message ):
0 commit comments