• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/compiler/rust/message.h"
9 
10 #include <string>
11 
12 #include "absl/log/absl_check.h"
13 #include "absl/log/absl_log.h"
14 #include "absl/strings/str_cat.h"
15 #include "absl/strings/string_view.h"
16 #include "google/protobuf/compiler/cpp/helpers.h"
17 #include "google/protobuf/compiler/cpp/names.h"
18 #include "google/protobuf/compiler/rust/accessors/accessor_case.h"
19 #include "google/protobuf/compiler/rust/accessors/accessors.h"
20 #include "google/protobuf/compiler/rust/context.h"
21 #include "google/protobuf/compiler/rust/enum.h"
22 #include "google/protobuf/compiler/rust/naming.h"
23 #include "google/protobuf/compiler/rust/oneof.h"
24 #include "google/protobuf/compiler/rust/upb_helpers.h"
25 #include "google/protobuf/descriptor.h"
26 
27 namespace google {
28 namespace protobuf {
29 namespace compiler {
30 namespace rust {
31 namespace {
32 
MessageNew(Context & ctx,const Descriptor & msg)33 void MessageNew(Context& ctx, const Descriptor& msg) {
34   switch (ctx.opts().kernel) {
35     case Kernel::kCpp:
36       ctx.Emit({{"new_thunk", ThunkName(ctx, msg, "new")}}, R"rs(
37         Self { inner: $pbr$::MessageInner { msg: unsafe { $new_thunk$() } } }
38       )rs");
39       return;
40 
41     case Kernel::kUpb:
42       ctx.Emit(R"rs(
43         let arena = $pbr$::Arena::new();
44         let raw_msg = unsafe {
45             $pbr$::upb_Message_New(
46                 <Self as $pbr$::AssociatedMiniTable>::mini_table(),
47                 arena.raw()).unwrap()
48         };
49         Self {
50           inner: $pbr$::MessageInner {
51             msg: raw_msg,
52             arena,
53           }
54         }
55       )rs");
56       return;
57   }
58 
59   ABSL_LOG(FATAL) << "unreachable";
60 }
61 
MessageSerialize(Context & ctx,const Descriptor & msg)62 void MessageSerialize(Context& ctx, const Descriptor& msg) {
63   switch (ctx.opts().kernel) {
64     case Kernel::kCpp:
65       ctx.Emit({}, R"rs(
66         let mut serialized_data = $pbr$::SerializedData::new();
67         let success = unsafe {
68           $pbr$::proto2_rust_Message_serialize(self.raw_msg(), &mut serialized_data)
69         };
70         if success {
71           Ok(serialized_data.into_vec())
72         } else {
73           Err($pb$::SerializeError)
74         }
75       )rs");
76       return;
77 
78     case Kernel::kUpb:
79       ctx.Emit({{"minitable", UpbMiniTableName(msg)}},
80                R"rs(
81         // SAFETY: `MINI_TABLE` is the one associated with `self.raw_msg()`.
82         let encoded = unsafe {
83           $pbr$::wire::encode(self.raw_msg(),
84               <Self as $pbr$::AssociatedMiniTable>::mini_table())
85         };
86         //~ TODO: This discards the info we have about the reason
87         //~ of the failure, we should try to keep it instead.
88         encoded.map_err(|_| $pb$::SerializeError)
89       )rs");
90       return;
91   }
92 
93   ABSL_LOG(FATAL) << "unreachable";
94 }
95 
MessageMutClear(Context & ctx,const Descriptor & msg)96 void MessageMutClear(Context& ctx, const Descriptor& msg) {
97   switch (ctx.opts().kernel) {
98     case Kernel::kCpp:
99       ctx.Emit({},
100                R"rs(
101           unsafe { $pbr$::proto2_rust_Message_clear(self.raw_msg()) }
102         )rs");
103       return;
104     case Kernel::kUpb:
105       ctx.Emit(
106           R"rs(
107           unsafe {
108             $pbr$::upb_Message_Clear(
109                 self.raw_msg(),
110                 <Self as $pbr$::AssociatedMiniTable>::mini_table())
111           }
112         )rs");
113       return;
114   }
115 }
116 
MessageClearAndParse(Context & ctx,const Descriptor & msg)117 void MessageClearAndParse(Context& ctx, const Descriptor& msg) {
118   switch (ctx.opts().kernel) {
119     case Kernel::kCpp:
120       ctx.Emit({},
121                R"rs(
122           let success = unsafe {
123             // SAFETY: `data.as_ptr()` is valid to read for `data.len()`.
124             let data = $pbr$::SerializedData::from_raw_parts(
125               $NonNull$::new(data.as_ptr() as *mut _).unwrap(),
126               data.len(),
127             );
128 
129             $pbr$::proto2_rust_Message_parse(self.raw_msg(), data)
130           };
131           success.then_some(()).ok_or($pb$::ParseError)
132         )rs");
133       return;
134 
135     case Kernel::kUpb:
136       ctx.Emit(
137           R"rs(
138         let mut msg = Self::new();
139 
140         // SAFETY:
141         // - `data.as_ptr()` is valid to read for `data.len()`
142         // - `mini_table` is the one used to construct `msg.raw_msg()`
143         // - `msg.arena().raw()` is held for the same lifetime as `msg`.
144         let status = unsafe {
145           $pbr$::wire::decode(
146               data,
147               msg.raw_msg(),
148               <Self as $pbr$::AssociatedMiniTable>::mini_table(),
149               msg.arena())
150         };
151         match status {
152           Ok(_) => {
153             //~ This swap causes the old self.inner.arena to be moved into `msg`
154             //~ which we immediately drop, which will release any previous
155             //~ message that was held here.
156             $std$::mem::swap(self, &mut msg);
157             Ok(())
158           }
159           Err(_) => Err($pb$::ParseError)
160         }
161       )rs");
162       return;
163   }
164 
165   ABSL_LOG(FATAL) << "unreachable";
166 }
167 
MessageDebug(Context & ctx,const Descriptor & msg)168 void MessageDebug(Context& ctx, const Descriptor& msg) {
169   switch (ctx.opts().kernel) {
170     case Kernel::kCpp:
171       ctx.Emit({},
172                R"rs(
173         $pbr$::debug_string(self.raw_msg(), f)
174       )rs");
175       return;
176 
177     case Kernel::kUpb:
178       ctx.Emit(
179           R"rs(
180         let string = unsafe {
181           $pbr$::debug_string(
182             self.raw_msg(),
183             <Self as $pbr$::AssociatedMiniTable>::mini_table()
184           )
185         };
186         write!(f, "{}", string)
187       )rs");
188       return;
189   }
190 
191   ABSL_LOG(FATAL) << "unreachable";
192 }
193 
CppMessageExterns(Context & ctx,const Descriptor & msg)194 void CppMessageExterns(Context& ctx, const Descriptor& msg) {
195   ABSL_CHECK(ctx.is_cpp());
196   ctx.Emit(
197       {{"new_thunk", ThunkName(ctx, msg, "new")},
198        {"default_instance_thunk", ThunkName(ctx, msg, "default_instance")},
199        {"repeated_new_thunk", ThunkName(ctx, msg, "repeated_new")},
200        {"repeated_free_thunk", ThunkName(ctx, msg, "repeated_free")},
201        {"repeated_len_thunk", ThunkName(ctx, msg, "repeated_len")},
202        {"repeated_get_thunk", ThunkName(ctx, msg, "repeated_get")},
203        {"repeated_get_mut_thunk", ThunkName(ctx, msg, "repeated_get_mut")},
204        {"repeated_add_thunk", ThunkName(ctx, msg, "repeated_add")},
205        {"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
206        {"repeated_copy_from_thunk", ThunkName(ctx, msg, "repeated_copy_from")},
207        {"repeated_reserve_thunk", ThunkName(ctx, msg, "repeated_reserve")},
208        {"map_size_info_thunk", ThunkName(ctx, msg, "size_info")}},
209       R"rs(
210       fn $new_thunk$() -> $pbr$::RawMessage;
211       fn $default_instance_thunk$() -> $pbr$::RawMessage;
212       fn $repeated_new_thunk$() -> $pbr$::RawRepeatedField;
213       fn $repeated_free_thunk$(raw: $pbr$::RawRepeatedField);
214       fn $repeated_len_thunk$(raw: $pbr$::RawRepeatedField) -> usize;
215       fn $repeated_add_thunk$(raw: $pbr$::RawRepeatedField) -> $pbr$::RawMessage;
216       fn $repeated_get_thunk$(raw: $pbr$::RawRepeatedField, index: usize) -> $pbr$::RawMessage;
217       fn $repeated_get_mut_thunk$(raw: $pbr$::RawRepeatedField, index: usize) -> $pbr$::RawMessage;
218       fn $repeated_clear_thunk$(raw: $pbr$::RawRepeatedField);
219       fn $repeated_copy_from_thunk$(dst: $pbr$::RawRepeatedField, src: $pbr$::RawRepeatedField);
220       fn $repeated_reserve_thunk$(raw: $pbr$::RawRepeatedField, additional: usize);
221       fn $map_size_info_thunk$(i: $pbr$::MapNodeSizeInfoIndex) -> $pbr$::MapNodeSizeInfo;
222     )rs");
223 }
224 
MessageDrop(Context & ctx,const Descriptor & msg)225 void MessageDrop(Context& ctx, const Descriptor& msg) {
226   if (ctx.is_upb()) {
227     // Nothing to do here; drop glue (which will run drop(self.arena)
228     // automatically) is sufficient.
229     return;
230   }
231 
232   ctx.Emit(R"rs(
233     unsafe { $pbr$::proto2_rust_Message_delete(self.raw_msg()); }
234   )rs");
235 }
236 
IntoProxiedForMessage(Context & ctx,const Descriptor & msg)237 void IntoProxiedForMessage(Context& ctx, const Descriptor& msg) {
238   switch (ctx.opts().kernel) {
239     case Kernel::kCpp:
240       ctx.Emit(R"rs(
241         impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$View<'msg> {
242           fn into_proxied(self, _private: $pbi$::Private) -> $Msg$ {
243             let dst = $Msg$::new();
244             unsafe { $pbr$::proto2_rust_Message_copy_from(dst.inner.msg, self.msg) };
245             dst
246           }
247         }
248 
249         impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$Mut<'msg> {
250           fn into_proxied(self, _private: $pbi$::Private) -> $Msg$ {
251             $pb$::IntoProxied::into_proxied($pb$::IntoView::into_view(self), _private)
252           }
253         }
254       )rs");
255       return;
256 
257     case Kernel::kUpb:
258       ctx.Emit(R"rs(
259         impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$View<'msg> {
260           fn into_proxied(self, _private: $pbi$::Private) -> $Msg$ {
261             let dst = $Msg$::new();
262             unsafe { $pbr$::upb_Message_DeepCopy(
263               dst.inner.msg,
264               self.msg,
265               <Self as $pbr$::AssociatedMiniTable>::mini_table(),
266               dst.inner.arena.raw(),
267             ) };
268             dst
269           }
270         }
271 
272         impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$Mut<'msg> {
273           fn into_proxied(self, _private: $pbi$::Private) -> $Msg$ {
274             $pb$::IntoProxied::into_proxied($pb$::IntoView::into_view(self), _private)
275           }
276         }
277       )rs");
278       return;
279   }
280 
281   ABSL_LOG(FATAL) << "unreachable";
282 }
283 
UpbGeneratedMessageTraitImpls(Context & ctx,const Descriptor & msg)284 void UpbGeneratedMessageTraitImpls(Context& ctx, const Descriptor& msg) {
285   if (ctx.opts().kernel == Kernel::kUpb) {
286     ctx.Emit({{"minitable", UpbMiniTableName(msg)}}, R"rs(
287       unsafe impl $pbr$::AssociatedMiniTable for $Msg$ {
288         #[inline(always)]
289         fn mini_table() -> *const $pbr$::upb_MiniTable {
290           // This is unsafe only for Rust 1.80 and below and thus can be dropped
291           // once our MSRV is 1.81+
292           #[allow(unused_unsafe)]
293           unsafe {
294             $std$::ptr::addr_of!($minitable$)
295           }
296         }
297       }
298 
299       unsafe impl $pbr$::AssociatedMiniTable for $Msg$View<'_> {
300         #[inline(always)]
301         fn mini_table() -> *const $pbr$::upb_MiniTable {
302           // This is unsafe only for Rust 1.80 and below and thus can be dropped
303           // once our MSRV is 1.81+
304           #[allow(unused_unsafe)]
305           unsafe {
306             $std$::ptr::addr_of!($minitable$)
307           }
308         }
309       }
310 
311       unsafe impl $pbr$::AssociatedMiniTable for $Msg$Mut<'_> {
312         #[inline(always)]
313         fn mini_table() -> *const $pbr$::upb_MiniTable {
314           // This is unsafe only for Rust 1.80 and below and thus can be dropped
315           // once our MSRV is 1.81+
316           #[allow(unused_unsafe)]
317           unsafe {
318             $std$::ptr::addr_of!($minitable$)
319           }
320         }
321       }
322     )rs");
323   }
324 }
325 
MessageMutMergeFrom(Context & ctx,const Descriptor & msg)326 void MessageMutMergeFrom(Context& ctx, const Descriptor& msg) {
327   switch (ctx.opts().kernel) {
328     case Kernel::kCpp:
329       ctx.Emit({},
330                R"rs(
331           impl $pb$::MergeFrom for $Msg$Mut<'_> {
332             fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) {
333               // SAFETY: self and src are both valid `$Msg$`s.
334               unsafe {
335                 $pbr$::proto2_rust_Message_merge_from(self.raw_msg(), src.as_view().raw_msg());
336               }
337             }
338           }
339         )rs");
340       return;
341     case Kernel::kUpb:
342       ctx.Emit(
343           R"rs(
344           impl $pb$::MergeFrom for $Msg$Mut<'_> {
345             fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) {
346               // SAFETY: self and src are both valid `$Msg$`s.
347               unsafe {
348                 assert!(
349                   $pbr$::upb_Message_MergeFrom(self.raw_msg(),
350                     src.as_view().raw_msg(),
351                     <Self as $pbr$::AssociatedMiniTable>::mini_table(),
352                     // Use a nullptr for the ExtensionRegistry.
353                     $std$::ptr::null(),
354                     self.arena().raw())
355                 );
356               }
357             }
358           }
359         )rs");
360       return;
361   }
362 }
363 
MessageProxiedInRepeated(Context & ctx,const Descriptor & msg)364 void MessageProxiedInRepeated(Context& ctx, const Descriptor& msg) {
365   switch (ctx.opts().kernel) {
366     case Kernel::kCpp:
367       ctx.Emit(
368           {
369               {"Msg", RsSafeName(msg.name())},
370               {"repeated_len_thunk", ThunkName(ctx, msg, "repeated_len")},
371               {"repeated_get_thunk", ThunkName(ctx, msg, "repeated_get")},
372               {"repeated_get_mut_thunk",
373                ThunkName(ctx, msg, "repeated_get_mut")},
374               {"repeated_add_thunk", ThunkName(ctx, msg, "repeated_add")},
375               {"repeated_new_thunk", ThunkName(ctx, msg, "repeated_new")},
376               {"repeated_free_thunk", ThunkName(ctx, msg, "repeated_free")},
377               {"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
378               {"repeated_copy_from_thunk",
379                ThunkName(ctx, msg, "repeated_copy_from")},
380               {"repeated_reserve_thunk",
381                ThunkName(ctx, msg, "repeated_reserve")},
382           },
383           R"rs(
384         unsafe impl $pb$::ProxiedInRepeated for $Msg$ {
385           fn repeated_new(_private: $pbi$::Private) -> $pb$::Repeated<Self> {
386             // SAFETY:
387             // - The thunk returns an unaliased and valid `RepeatedPtrField*`
388             unsafe {
389               $pb$::Repeated::from_inner($pbi$::Private,
390                 $pbr$::InnerRepeated::from_raw($repeated_new_thunk$()
391                 )
392               )
393             }
394           }
395 
396           unsafe fn repeated_free(_private: $pbi$::Private, f: &mut $pb$::Repeated<Self>) {
397             // SAFETY
398             // - `f.raw()` is a valid `RepeatedPtrField*`.
399             unsafe { $repeated_free_thunk$(f.as_view().as_raw($pbi$::Private)) }
400           }
401 
402           fn repeated_len(f: $pb$::View<$pb$::Repeated<Self>>) -> usize {
403             // SAFETY: `f.as_raw()` is a valid `RepeatedPtrField*`.
404             unsafe { $repeated_len_thunk$(f.as_raw($pbi$::Private)) }
405           }
406 
407           unsafe fn repeated_set_unchecked(
408             mut f: $pb$::Mut<$pb$::Repeated<Self>>,
409             i: usize,
410             v: impl $pb$::IntoProxied<Self>,
411           ) {
412             // SAFETY:
413             // - `f.as_raw()` is a valid `RepeatedPtrField*`.
414             // - `i < len(f)` is promised by caller.
415             // - `v.raw_msg()` is a valid `const Message&`.
416             unsafe {
417               $pbr$::proto2_rust_Message_copy_from(
418                 $repeated_get_mut_thunk$(f.as_raw($pbi$::Private), i),
419                 v.into_proxied($pbi$::Private).raw_msg(),
420               );
421             }
422           }
423 
424           unsafe fn repeated_get_unchecked(
425             f: $pb$::View<$pb$::Repeated<Self>>,
426             i: usize,
427           ) -> $pb$::View<Self> {
428             // SAFETY:
429             // - `f.as_raw()` is a valid `const RepeatedPtrField&`.
430             // - `i < len(f)` is promised by caller.
431             let msg = unsafe { $repeated_get_thunk$(f.as_raw($pbi$::Private), i) };
432             $pb$::View::<Self>::new($pbi$::Private, msg)
433           }
434           fn repeated_clear(mut f: $pb$::Mut<$pb$::Repeated<Self>>) {
435             // SAFETY:
436             // - `f.as_raw()` is a valid `RepeatedPtrField*`.
437             unsafe { $repeated_clear_thunk$(f.as_raw($pbi$::Private)) };
438           }
439 
440           fn repeated_push(mut f: $pb$::Mut<$pb$::Repeated<Self>>, v: impl $pb$::IntoProxied<Self>) {
441             // SAFETY:
442             // - `f.as_raw()` is a valid `RepeatedPtrField*`.
443             // - `v.raw_msg()` is a valid `const Message&`.
444             unsafe {
445               let new_elem = $repeated_add_thunk$(f.as_raw($pbi$::Private));
446               $pbr$::proto2_rust_Message_copy_from(new_elem, v.into_proxied($pbi$::Private).raw_msg());
447             }
448           }
449 
450           fn repeated_copy_from(
451             src: $pb$::View<$pb$::Repeated<Self>>,
452             mut dest: $pb$::Mut<$pb$::Repeated<Self>>,
453           ) {
454             // SAFETY:
455             // - `dest.as_raw()` is a valid `RepeatedPtrField*`.
456             // - `src.as_raw()` is a valid `const RepeatedPtrField&`.
457             unsafe {
458               $repeated_copy_from_thunk$(dest.as_raw($pbi$::Private), src.as_raw($pbi$::Private));
459             }
460           }
461 
462           fn repeated_reserve(
463             mut f: $pb$::Mut<$pb$::Repeated<Self>>,
464             additional: usize,
465           ) {
466             // SAFETY:
467             // - `f.as_raw()` is a valid `RepeatedPtrField*`.
468             unsafe { $repeated_reserve_thunk$(f.as_raw($pbi$::Private), additional) }
469           }
470         }
471       )rs");
472       return;
473     case Kernel::kUpb:
474       ctx.Emit(
475           {
476               {"new_thunk", ThunkName(ctx, msg, "new")},
477           },
478           R"rs(
479         unsafe impl $pb$::ProxiedInRepeated for $Msg$ {
480           fn repeated_new(_private: $pbi$::Private) -> $pb$::Repeated<Self> {
481             let arena = $pbr$::Arena::new();
482             unsafe {
483               $pb$::Repeated::from_inner(
484                   $pbi$::Private,
485                   $pbr$::InnerRepeated::from_raw_parts(
486                       $pbr$::upb_Array_New(arena.raw(), $pbr$::CType::Message),
487                       arena,
488                   ))
489             }
490           }
491 
492           unsafe fn repeated_free(_private: $pbi$::Private, _f: &mut $pb$::Repeated<Self>) {
493             // No-op: the memory will be dropped by the arena.
494           }
495 
496           fn repeated_len(f: $pb$::View<$pb$::Repeated<Self>>) -> usize {
497             // SAFETY: `f.as_raw()` is a valid `upb_Array*`.
498             unsafe { $pbr$::upb_Array_Size(f.as_raw($pbi$::Private)) }
499           }
500           unsafe fn repeated_set_unchecked(
501             mut f: $pb$::Mut<$pb$::Repeated<Self>>,
502             i: usize,
503             v: impl $pb$::IntoProxied<Self>,
504           ) {
505             unsafe {
506                 $pbr$::upb_Array_Set(
507                     f.as_raw($pbi$::Private),
508                     i,
509                     <Self as $pbr$::UpbTypeConversions>::into_message_value_fuse_if_required(
510                         f.raw_arena($pbi$::Private),
511                         v.into_proxied($pbi$::Private),
512                     ),
513                 )
514             }
515           }
516 
517           unsafe fn repeated_get_unchecked(
518             f: $pb$::View<$pb$::Repeated<Self>>,
519             i: usize,
520           ) -> $pb$::View<Self> {
521             // SAFETY:
522             // - `f.as_raw()` is a valid `const upb_Array*`.
523             // - `i < len(f)` is promised by the caller.
524             let msg_ptr = unsafe { $pbr$::upb_Array_Get(f.as_raw($pbi$::Private), i).msg_val }
525               .expect("upb_Array* element should not be NULL.");
526             $pb$::View::<Self>::new($pbi$::Private, msg_ptr)
527           }
528 
529           fn repeated_clear(mut f: $pb$::Mut<$pb$::Repeated<Self>>) {
530             // SAFETY:
531             // - `f.as_raw()` is a valid `upb_Array*`.
532             unsafe {
533               $pbr$::upb_Array_Resize(f.as_raw($pbi$::Private), 0, f.raw_arena($pbi$::Private))
534             };
535           }
536           fn repeated_push(mut f: $pb$::Mut<$pb$::Repeated<Self>>, v: impl $pb$::IntoProxied<Self>) {
537             // SAFETY:
538             // - `f.as_raw()` is a valid `upb_Array*`.
539             // - `msg_ptr` is a valid `upb_Message*`.
540             unsafe {
541               $pbr$::upb_Array_Append(
542                 f.as_raw($pbi$::Private),
543                 <Self as $pbr$::UpbTypeConversions>::into_message_value_fuse_if_required(f.raw_arena($pbi$::Private), v.into_proxied($pbi$::Private)),
544                 f.raw_arena($pbi$::Private)
545               );
546             };
547           }
548 
549           fn repeated_copy_from(
550             src: $pb$::View<$pb$::Repeated<Self>>,
551             dest: $pb$::Mut<$pb$::Repeated<Self>>,
552           ) {
553               // SAFETY:
554               // - Elements of `src` and `dest` have message minitable `MINI_TABLE`.
555               unsafe {
556                 $pbr$::repeated_message_copy_from(src, dest, <Self as $pbr$::AssociatedMiniTable>::mini_table());
557               }
558           }
559 
560           fn repeated_reserve(
561             mut f: $pb$::Mut<$pb$::Repeated<Self>>,
562             additional: usize,
563           ) {
564             // SAFETY:
565             // - `f.as_raw()` is a valid `upb_Array*`.
566             unsafe {
567               let size = $pbr$::upb_Array_Size(f.as_raw($pbi$::Private));
568               $pbr$::upb_Array_Reserve(f.as_raw($pbi$::Private), size + additional, f.raw_arena($pbi$::Private));
569             }
570           }
571         }
572       )rs");
573       return;
574   }
575   ABSL_LOG(FATAL) << "unreachable";
576 }
577 
MessageProxiedInMapValue(Context & ctx,const Descriptor & msg)578 void MessageProxiedInMapValue(Context& ctx, const Descriptor& msg) {
579   switch (ctx.opts().kernel) {
580     case Kernel::kCpp:
581       for (const auto& t : kMapKeyTypes) {
582         ctx.Emit(
583             {{"map_size_info_thunk", ThunkName(ctx, msg, "size_info")},
584              {"map_insert",
585               absl::StrCat("proto2_rust_map_insert_", t.thunk_ident)},
586              {"map_remove",
587               absl::StrCat("proto2_rust_map_remove_", t.thunk_ident)},
588              {"map_get", absl::StrCat("proto2_rust_map_get_", t.thunk_ident)},
589              {"map_iter_get",
590               absl::StrCat("proto2_rust_map_iter_get_", t.thunk_ident)},
591              {"key_expr", t.rs_to_ffi_key_expr},
592              {"key_is_string",
593               t.thunk_ident == "ProtoString" ? "true" : "false"},
594              io::Printer::Sub("ffi_key_t", [&] { ctx.Emit(t.rs_ffi_key_t); })
595                  .WithSuffix(""),
596              io::Printer::Sub("key_t", [&] { ctx.Emit(t.rs_key_t); })
597                  .WithSuffix(""),
598              io::Printer::Sub("from_ffi_key_expr",
599                               [&] { ctx.Emit(t.rs_from_ffi_key_expr); })
600                  .WithSuffix("")},
601             R"rs(
602             impl $pb$::ProxiedInMapValue<$key_t$> for $Msg$ {
603                 fn map_new(_private: $pbi$::Private) -> $pb$::Map<$key_t$, Self> {
604                     unsafe {
605                         $pb$::Map::from_inner(
606                             $pbi$::Private,
607                             $pbr$::InnerMap::new($pbr$::proto2_rust_map_new())
608                         )
609                     }
610                 }
611 
612                 unsafe fn map_free(_private: $pbi$::Private, map: &mut $pb$::Map<$key_t$, Self>) {
613                     use $pbr$::MapNodeSizeInfoIndexForType;
614                     unsafe { $pbr$::proto2_rust_map_free(map.as_raw($pbi$::Private), $key_is_string$, $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX)); }
615                 }
616 
617                 fn map_clear(mut map: $pb$::MapMut<$key_t$, Self>) {
618                     use $pbr$::MapNodeSizeInfoIndexForType;
619                     unsafe { $pbr$::proto2_rust_map_clear(map.as_raw($pbi$::Private), $key_is_string$, $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX)); }
620                 }
621 
622                 fn map_len(map: $pb$::MapView<$key_t$, Self>) -> usize {
623                     unsafe { $pbr$::proto2_rust_map_size(map.as_raw($pbi$::Private)) }
624                 }
625 
626                 fn map_insert(mut map: $pb$::MapMut<$key_t$, Self>, key: $pb$::View<'_, $key_t$>, value: impl $pb$::IntoProxied<Self>) -> bool {
627                     use $pbr$::MapNodeSizeInfoIndexForType;
628                     unsafe {
629                         $pbr$::$map_insert$(
630                             map.as_raw($pbi$::Private),
631                             $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX),
632                             $key_expr$,
633                             value.into_proxied($pbi$::Private).raw_msg())
634                     }
635                 }
636 
637                 fn map_get<'a>(map: $pb$::MapView<'a, $key_t$, Self>, key: $pb$::View<'_, $key_t$>) -> $Option$<$pb$::View<'a, Self>> {
638                     use $pbr$::MapNodeSizeInfoIndexForType;
639                     let key = $key_expr$;
640                     let mut value = $std$::mem::MaybeUninit::uninit();
641                     let found = unsafe {
642                         $pbr$::$map_get$(
643                             map.as_raw($pbi$::Private),
644                             $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX),
645                             key,
646                             value.as_mut_ptr())
647                     };
648                     if !found {
649                         return None;
650                     }
651                     Some($Msg$View::new($pbi$::Private, unsafe { value.assume_init() }))
652                 }
653 
654                 fn map_remove(mut map: $pb$::MapMut<$key_t$, Self>, key: $pb$::View<'_, $key_t$>) -> bool {
655                     use $pbr$::MapNodeSizeInfoIndexForType;
656                     unsafe {
657                         $pbr$::$map_remove$(
658                             map.as_raw($pbi$::Private),
659                             $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX),
660                             $key_expr$)
661                     }
662                 }
663 
664                 fn map_iter(map: $pb$::MapView<$key_t$, Self>) -> $pb$::MapIter<$key_t$, Self> {
665                     // SAFETY:
666                     // - The backing map for `map.as_raw` is valid for at least '_.
667                     // - A View that is live for '_ guarantees the backing map is unmodified for '_.
668                     // - The `iter` function produces an iterator that is valid for the key
669                     //   and value types, and live for at least '_.
670                     unsafe {
671                         $pb$::MapIter::from_raw(
672                             $pbi$::Private,
673                             $pbr$::proto2_rust_map_iter(map.as_raw($pbi$::Private))
674                         )
675                     }
676                 }
677 
678                 fn map_iter_next<'a>(iter: &mut $pb$::MapIter<'a, $key_t$, Self>) -> $Option$<($pb$::View<'a, $key_t$>, $pb$::View<'a, Self>)> {
679                     use $pbr$::MapNodeSizeInfoIndexForType;
680                     // SAFETY:
681                     // - The `MapIter` API forbids the backing map from being mutated for 'a,
682                     //   and guarantees that it's the correct key and value types.
683                     // - The thunk is safe to call as long as the iterator isn't at the end.
684                     // - The thunk always writes to key and value fields and does not read.
685                     // - The thunk does not increment the iterator.
686                     unsafe {
687                         iter.as_raw_mut($pbi$::Private).next_unchecked::<$key_t$, Self, _, _>(
688                             |iter, key, value| { $pbr$::$map_iter_get$(
689                                 iter, $map_size_info_thunk$($key_t$::SIZE_INFO_INDEX), key, value) },
690                             |ffi_key| $from_ffi_key_expr$,
691                             |raw_msg| $Msg$View::new($pbi$::Private, raw_msg)
692                         )
693                     }
694                 }
695             }
696       )rs");
697       }
698       return;
699     case Kernel::kUpb:
700       ctx.Emit(
701           {
702               {"new_thunk", ThunkName(ctx, msg, "new")},
703           },
704           R"rs(
705             impl $pbr$::UpbTypeConversions for $Msg$ {
706                 fn upb_type() -> $pbr$::CType {
707                     $pbr$::CType::Message
708                 }
709 
710                 fn to_message_value(
711                     val: $pb$::View<'_, Self>) -> $pbr$::upb_MessageValue {
712                     $pbr$::upb_MessageValue { msg_val: Some(val.raw_msg()) }
713                 }
714 
715                 unsafe fn into_message_value_fuse_if_required(
716                   raw_parent_arena: $pbr$::RawArena,
717                   mut val: Self) -> $pbr$::upb_MessageValue {
718                   // SAFETY: The arena memory is not freed due to `ManuallyDrop`.
719                   let parent_arena = core::mem::ManuallyDrop::new(
720                       unsafe { $pbr$::Arena::from_raw(raw_parent_arena) });
721 
722                   parent_arena.fuse(val.as_mutator_message_ref($pbi$::Private).arena());
723                   $pbr$::upb_MessageValue { msg_val: Some(val.raw_msg()) }
724                 }
725 
726                 unsafe fn from_message_value<'msg>(msg: $pbr$::upb_MessageValue)
727                     -> $pb$::View<'msg, Self> {
728                     $Msg$View::new(
729                         $pbi$::Private,
730                         unsafe { msg.msg_val }
731                             .expect("expected present message value in map"))
732                 }
733             }
734             )rs");
735   }
736 }
737 
GenerateDefaultInstanceImpl(Context & ctx,const Descriptor & msg)738 void GenerateDefaultInstanceImpl(Context& ctx, const Descriptor& msg) {
739   if (ctx.is_upb()) {
740     ctx.Emit("$pbr$::ScratchSpace::zeroed_block()");
741   } else {
742     ctx.Emit(
743         {{"default_instance_thunk", ThunkName(ctx, msg, "default_instance")}},
744         "unsafe { $default_instance_thunk$() }");
745   }
746 }
747 
748 }  // namespace
749 
GenerateRs(Context & ctx,const Descriptor & msg)750 void GenerateRs(Context& ctx, const Descriptor& msg) {
751   if (msg.map_key() != nullptr) {
752     // Don't generate code for synthetic MapEntry messages.
753     return;
754   }
755   ctx.Emit(
756       {{"Msg", RsSafeName(msg.name())},
757        {"Msg::new", [&] { MessageNew(ctx, msg); }},
758        {"Msg::serialize", [&] { MessageSerialize(ctx, msg); }},
759        {"MsgMut::clear", [&] { MessageMutClear(ctx, msg); }},
760        {"Msg::clear_and_parse", [&] { MessageClearAndParse(ctx, msg); }},
761        {"Msg::drop", [&] { MessageDrop(ctx, msg); }},
762        {"Msg::debug", [&] { MessageDebug(ctx, msg); }},
763        {"MsgMut::merge_from", [&] { MessageMutMergeFrom(ctx, msg); }},
764        {"default_instance_impl",
765         [&] { GenerateDefaultInstanceImpl(ctx, msg); }},
766        {"accessor_fns",
767         [&] {
768           for (int i = 0; i < msg.field_count(); ++i) {
769             GenerateAccessorMsgImpl(ctx, *msg.field(i), AccessorCase::OWNED);
770           }
771           for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
772             GenerateOneofAccessors(ctx, *msg.real_oneof_decl(i),
773                                    AccessorCase::OWNED);
774           }
775         }},
776        {"nested_in_msg",
777         [&] {
778           // If we have no nested types, enums, or oneofs, bail out without
779           // emitting an empty mod some_msg.
780           if (msg.nested_type_count() == 0 && msg.enum_type_count() == 0 &&
781               msg.real_oneof_decl_count() == 0) {
782             return;
783           }
784           ctx.Emit({{"mod_name", RsSafeName(CamelToSnakeCase(msg.name()))},
785                     {"nested_msgs",
786                      [&] {
787                        for (int i = 0; i < msg.nested_type_count(); ++i) {
788                          GenerateRs(ctx, *msg.nested_type(i));
789                        }
790                      }},
791                     {"nested_enums",
792                      [&] {
793                        for (int i = 0; i < msg.enum_type_count(); ++i) {
794                          GenerateEnumDefinition(ctx, *msg.enum_type(i));
795                        }
796                      }},
797                     {"oneofs",
798                      [&] {
799                        for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
800                          GenerateOneofDefinition(ctx, *msg.real_oneof_decl(i));
801                        }
802                      }}},
803                    R"rs(
804                  pub mod $mod_name$ {
805                    $nested_msgs$
806                    $nested_enums$
807 
808                    $oneofs$
809                  }  // mod $mod_name$
810                 )rs");
811         }},
812        {"raw_arena_getter_for_message",
813         [&] {
814           if (ctx.is_upb()) {
815             ctx.Emit({}, R"rs(
816                   fn arena(&self) -> &$pbr$::Arena {
817                     &self.inner.arena
818                   }
819                   )rs");
820           }
821         }},
822        {"raw_arena_getter_for_msgmut",
823         [&] {
824           if (ctx.is_upb()) {
825             ctx.Emit({}, R"rs(
826                   fn arena(&self) -> &$pbr$::Arena {
827                     self.inner.arena()
828                   }
829                   )rs");
830           }
831         }},
832        {"accessor_fns_for_views",
833         [&] {
834           for (int i = 0; i < msg.field_count(); ++i) {
835             GenerateAccessorMsgImpl(ctx, *msg.field(i), AccessorCase::VIEW);
836           }
837           for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
838             GenerateOneofAccessors(ctx, *msg.real_oneof_decl(i),
839                                    AccessorCase::VIEW);
840           }
841         }},
842        {"accessor_fns_for_muts",
843         [&] {
844           for (int i = 0; i < msg.field_count(); ++i) {
845             GenerateAccessorMsgImpl(ctx, *msg.field(i), AccessorCase::MUT);
846           }
847           for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
848             GenerateOneofAccessors(ctx, *msg.real_oneof_decl(i),
849                                    AccessorCase::MUT);
850           }
851         }},
852        {"into_proxied_impl", [&] { IntoProxiedForMessage(ctx, msg); }},
853        {"upb_generated_message_trait_impls",
854         [&] { UpbGeneratedMessageTraitImpls(ctx, msg); }},
855        {"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }},
856        {"map_value_impl", [&] { MessageProxiedInMapValue(ctx, msg); }},
857        {"unwrap_upb",
858         [&] {
859           if (ctx.is_upb()) {
860             ctx.Emit(".unwrap_or_else(||$pbr$::ScratchSpace::zeroed_block())");
861           }
862         }},
863        {"upb_arena",
864         [&] {
865           if (ctx.is_upb()) {
866             ctx.Emit(", inner.msg_ref().arena().raw()");
867           }
868         }}},
869       R"rs(
870         #[allow(non_camel_case_types)]
871         pub struct $Msg$ {
872           inner: $pbr$::MessageInner
873         }
874 
875         impl $pb$::Message for $Msg$ {}
876 
877         impl $std$::default::Default for $Msg$ {
878           fn default() -> Self {
879             Self::new()
880           }
881         }
882 
883         impl $pb$::Parse for $Msg$ {
884           fn parse(serialized: &[u8]) -> $Result$<Self, $pb$::ParseError> {
885             Self::parse(serialized)
886           }
887         }
888 
889         impl $std$::fmt::Debug for $Msg$ {
890           fn fmt(&self, f: &mut $std$::fmt::Formatter<'_>) -> $std$::fmt::Result {
891             $Msg::debug$
892           }
893         }
894 
895         impl $pb$::MergeFrom for $Msg$ {
896           fn merge_from<'src>(&mut self, src: impl $pb$::AsView<Proxied = Self>) {
897             let mut m = self.as_mut();
898             $pb$::MergeFrom::merge_from(&mut m, src)
899           }
900         }
901 
902         impl $pb$::Serialize for $Msg$ {
903           fn serialize(&self) -> $Result$<Vec<u8>, $pb$::SerializeError> {
904             $pb$::AsView::as_view(self).serialize()
905           }
906         }
907 
908         impl $pb$::Clear for $Msg$ {
909           fn clear(&mut self) {
910             self.as_mut().clear()
911           }
912         }
913 
914         impl $pb$::ClearAndParse for $Msg$ {
915           fn clear_and_parse(&mut self, data: &[u8]) -> $Result$<(), $pb$::ParseError> {
916             $Msg::clear_and_parse$
917           }
918         }
919 
920         // SAFETY:
921         // - `$Msg$` is `Sync` because it does not implement interior mutability.
922         //    Neither does `$Msg$Mut`.
923         unsafe impl Sync for $Msg$ {}
924 
925         // SAFETY:
926         // - `$Msg$` is `Send` because it uniquely owns its arena and does
927         //   not use thread-local data.
928         unsafe impl Send for $Msg$ {}
929 
930         impl $pb$::Proxied for $Msg$ {
931           type View<'msg> = $Msg$View<'msg>;
932         }
933 
934         impl $pbi$::SealedInternal for $Msg$ {}
935 
936         impl $pb$::MutProxied for $Msg$ {
937           type Mut<'msg> = $Msg$Mut<'msg>;
938         }
939 
940         #[derive(Copy, Clone)]
941         #[allow(dead_code)]
942         pub struct $Msg$View<'msg> {
943           msg: $pbr$::RawMessage,
944           _phantom: $Phantom$<&'msg ()>,
945         }
946 
947         impl<'msg> $pbi$::SealedInternal for $Msg$View<'msg> {}
948 
949         impl<'msg> $pb$::MessageView<'msg> for $Msg$View<'msg> {
950           type Message = $Msg$;
951         }
952 
953         impl $std$::fmt::Debug for $Msg$View<'_> {
954           fn fmt(&self, f: &mut $std$::fmt::Formatter<'_>) -> $std$::fmt::Result {
955             $Msg::debug$
956           }
957         }
958 
959         impl $pb$::Serialize for $Msg$View<'_> {
960           fn serialize(&self) -> $Result$<Vec<u8>, $pb$::SerializeError> {
961             $Msg::serialize$
962           }
963         }
964 
965         impl $std$::default::Default for $Msg$View<'_> {
966           fn default() -> $Msg$View<'static> {
967             $Msg$View::new($pbi$::Private, $default_instance_impl$)
968           }
969         }
970 
971         #[allow(dead_code)]
972         impl<'msg> $Msg$View<'msg> {
973           #[doc(hidden)]
974           pub fn new(_private: $pbi$::Private, msg: $pbr$::RawMessage) -> Self {
975             Self { msg, _phantom: $std$::marker::PhantomData }
976           }
977 
978           fn raw_msg(&self) -> $pbr$::RawMessage {
979             self.msg
980           }
981 
982           pub fn to_owned(&self) -> $Msg$ {
983             $pb$::IntoProxied::into_proxied(*self, $pbi$::Private)
984           }
985 
986           $accessor_fns_for_views$
987         }
988 
989         // SAFETY:
990         // - `$Msg$View` is `Sync` because it does not support mutation.
991         unsafe impl Sync for $Msg$View<'_> {}
992 
993         // SAFETY:
994         // - `$Msg$View` is `Send` because while its alive a `$Msg$Mut` cannot.
995         // - `$Msg$View` does not use thread-local data.
996         unsafe impl Send for $Msg$View<'_> {}
997 
998         impl<'msg> $pb$::Proxy<'msg> for $Msg$View<'msg> {}
999         impl<'msg> $pb$::ViewProxy<'msg> for $Msg$View<'msg> {}
1000 
1001         impl<'msg> $pb$::AsView for $Msg$View<'msg> {
1002           type Proxied = $Msg$;
1003           fn as_view(&self) -> $pb$::View<'msg, $Msg$> {
1004             *self
1005           }
1006         }
1007 
1008         impl<'msg> $pb$::IntoView<'msg> for $Msg$View<'msg> {
1009           fn into_view<'shorter>(self) -> $Msg$View<'shorter>
1010           where
1011               'msg: 'shorter {
1012             self
1013           }
1014         }
1015 
1016         $into_proxied_impl$
1017 
1018         $repeated_impl$
1019         $map_value_impl$
1020 
1021         #[allow(dead_code)]
1022         #[allow(non_camel_case_types)]
1023         pub struct $Msg$Mut<'msg> {
1024           inner: $pbr$::MutatorMessageRef<'msg>,
1025         }
1026 
1027         impl<'msg> $pbi$::SealedInternal for $Msg$Mut<'msg> {}
1028 
1029         impl<'msg> $pb$::MessageMut<'msg> for $Msg$Mut<'msg> {
1030           type Message = $Msg$;
1031         }
1032 
1033         impl $std$::fmt::Debug for $Msg$Mut<'_> {
1034           fn fmt(&self, f: &mut $std$::fmt::Formatter<'_>) -> $std$::fmt::Result {
1035             $Msg::debug$
1036           }
1037         }
1038 
1039         impl $pb$::Serialize for $Msg$Mut<'_> {
1040           fn serialize(&self) -> $Result$<Vec<u8>, $pb$::SerializeError> {
1041             $pb$::AsView::as_view(self).serialize()
1042           }
1043         }
1044 
1045         impl $pb$::Clear for $Msg$Mut<'_> {
1046           fn clear(&mut self) {
1047             $MsgMut::clear$
1048           }
1049         }
1050 
1051         $MsgMut::merge_from$
1052 
1053         #[allow(dead_code)]
1054         impl<'msg> $Msg$Mut<'msg> {
1055           #[doc(hidden)]
1056           pub fn from_parent(
1057                      _private: $pbi$::Private,
1058                      parent: $pbr$::MutatorMessageRef<'msg>,
1059                      msg: $pbr$::RawMessage)
1060             -> Self {
1061             Self {
1062               inner: $pbr$::MutatorMessageRef::from_parent(parent, msg)
1063             }
1064           }
1065 
1066           #[doc(hidden)]
1067           pub fn new(_private: $pbi$::Private, msg: &'msg mut $pbr$::MessageInner) -> Self {
1068             Self{ inner: $pbr$::MutatorMessageRef::new(msg) }
1069           }
1070 
1071           fn raw_msg(&self) -> $pbr$::RawMessage {
1072             self.inner.msg()
1073           }
1074 
1075           #[doc(hidden)]
1076           pub fn as_mutator_message_ref(&mut self, _private: $pbi$::Private)
1077             -> $pbr$::MutatorMessageRef<'msg> {
1078             self.inner
1079           }
1080 
1081           pub fn to_owned(&self) -> $Msg$ {
1082             $pb$::AsView::as_view(self).to_owned()
1083           }
1084 
1085           $raw_arena_getter_for_msgmut$
1086 
1087           $accessor_fns_for_muts$
1088         }
1089 
1090         // SAFETY:
1091         // - `$Msg$Mut` does not perform any shared mutation.
1092         // - `$Msg$Mut` is not `Send`, and so even in the presence of mutator
1093         //   splitting, synchronous access of an arena is impossible.
1094         unsafe impl Sync for $Msg$Mut<'_> {}
1095 
1096         impl<'msg> $pb$::Proxy<'msg> for $Msg$Mut<'msg> {}
1097         impl<'msg> $pb$::MutProxy<'msg> for $Msg$Mut<'msg> {}
1098 
1099         impl<'msg> $pb$::AsView for $Msg$Mut<'msg> {
1100           type Proxied = $Msg$;
1101           fn as_view(&self) -> $pb$::View<'_, $Msg$> {
1102             $Msg$View { msg: self.raw_msg(), _phantom: $std$::marker::PhantomData }
1103           }
1104         }
1105 
1106         impl<'msg> $pb$::IntoView<'msg> for $Msg$Mut<'msg> {
1107           fn into_view<'shorter>(self) -> $pb$::View<'shorter, $Msg$>
1108           where
1109               'msg: 'shorter {
1110             $Msg$View { msg: self.raw_msg(), _phantom: $std$::marker::PhantomData }
1111           }
1112         }
1113 
1114         impl<'msg> $pb$::AsMut for $Msg$Mut<'msg> {
1115           type MutProxied = $Msg$;
1116           fn as_mut(&mut self) -> $Msg$Mut<'msg> {
1117             $Msg$Mut { inner: self.inner }
1118           }
1119         }
1120 
1121         impl<'msg> $pb$::IntoMut<'msg> for $Msg$Mut<'msg> {
1122           fn into_mut<'shorter>(self) -> $Msg$Mut<'shorter>
1123           where
1124               'msg: 'shorter {
1125             self
1126           }
1127         }
1128 
1129         #[allow(dead_code)]
1130         impl $Msg$ {
1131           pub fn new() -> Self {
1132             $Msg::new$
1133           }
1134 
1135           fn raw_msg(&self) -> $pbr$::RawMessage {
1136             self.inner.msg
1137           }
1138 
1139           #[doc(hidden)]
1140           pub fn as_mutator_message_ref(&mut self, _private: $pbi$::Private) -> $pbr$::MutatorMessageRef {
1141             $pbr$::MutatorMessageRef::new(&mut self.inner)
1142           }
1143 
1144           $raw_arena_getter_for_message$
1145 
1146           pub fn parse(data: &[u8]) -> $Result$<Self, $pb$::ParseError> {
1147             let mut msg = Self::new();
1148             $pb$::ClearAndParse::clear_and_parse(&mut msg, data).map(|_| msg)
1149           }
1150 
1151           pub fn as_view(&self) -> $Msg$View {
1152             $Msg$View::new($pbi$::Private, self.inner.msg)
1153           }
1154 
1155           pub fn as_mut(&mut self) -> $Msg$Mut {
1156             $Msg$Mut::new($pbi$::Private, &mut self.inner)
1157           }
1158 
1159           $accessor_fns$
1160         }  // impl $Msg$
1161 
1162         //~ We implement drop unconditionally, so that `$Msg$: Drop` regardless
1163         //~ of kernel.
1164         impl $std$::ops::Drop for $Msg$ {
1165           fn drop(&mut self) {
1166             $Msg::drop$
1167           }
1168         }
1169 
1170         impl $std$::clone::Clone for $Msg$ {
1171           fn clone(&self) -> Self {
1172             self.as_view().to_owned()
1173           }
1174         }
1175 
1176         impl $pb$::AsView for $Msg$ {
1177           type Proxied = Self;
1178           fn as_view(&self) -> $Msg$View {
1179             self.as_view()
1180           }
1181         }
1182 
1183         impl $pb$::AsMut for $Msg$ {
1184           type MutProxied = Self;
1185           fn as_mut(&mut self) -> $Msg$Mut {
1186             self.as_mut()
1187           }
1188         }
1189 
1190         $upb_generated_message_trait_impls$
1191 
1192         $nested_in_msg$
1193       )rs");
1194 
1195   if (ctx.is_cpp()) {
1196     ctx.Emit(
1197         {
1198             {"message_externs", [&] { CppMessageExterns(ctx, msg); }},
1199             {"accessor_externs",
1200              [&] {
1201                for (int i = 0; i < msg.field_count(); ++i) {
1202                  GenerateAccessorExternC(ctx, *msg.field(i));
1203                }
1204              }},
1205             {"oneof_externs",
1206              [&] {
1207                for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
1208                  GenerateOneofExternC(ctx, *msg.real_oneof_decl(i));
1209                }
1210              }},
1211         },
1212         R"rs(
1213         extern "C" {
1214           $message_externs$
1215           $accessor_externs$
1216           $oneof_externs$
1217         }
1218     )rs");
1219   } else {
1220     ctx.Emit({{"minitable_symbol_name", UpbMiniTableName(msg)}},
1221              R"rs(
1222           extern "C" {
1223             /// Opaque static extern for this message's MiniTable, generated
1224             /// by the upb C MiniTable codegen. The only valid way to
1225             /// reference this static is with `std::ptr::addr_of!(..)`.
1226             static $minitable_symbol_name$: $pbr$::upb_MiniTable;
1227           }
1228       )rs");
1229   }
1230 
1231   ctx.printer().PrintRaw("\n");
1232   if (ctx.is_cpp()) {
1233     ctx.Emit({{"Msg", RsSafeName(msg.name())}}, R"rs(
1234       impl<'a> $Msg$Mut<'a> {
1235         pub unsafe fn __unstable_wrap_cpp_grant_permission_to_break(
1236             msg: &'a mut *mut $std$::ffi::c_void) -> Self {
1237           Self {
1238             inner: $pbr$::MutatorMessageRef::wrap_raw(
1239                 $pbr$::RawMessage::new(*msg as *mut _).unwrap())
1240           }
1241         }
1242         pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> *mut $std$::ffi::c_void {
1243           self.raw_msg().as_ptr() as *mut _
1244         }
1245       }
1246 
1247       impl<'a> $Msg$View<'a> {
1248         pub fn __unstable_wrap_cpp_grant_permission_to_break(
1249           msg: &'a *const $std$::ffi::c_void) -> Self {
1250           Self::new($pbi$::Private, $pbr$::RawMessage::new(*msg as *mut _).unwrap())
1251         }
1252         pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> *const $std$::ffi::c_void {
1253           self.msg.as_ptr() as *const _
1254         }
1255       }
1256 
1257       impl $pb$::OwnedMessageInterop for $Msg$ {
1258         unsafe fn __unstable_take_ownership_of_raw_message(msg: *mut $std$::ffi::c_void) -> Self {
1259           Self { inner: $pbr$::MessageInner { msg: $pbr$::RawMessage::new(msg as *mut _).unwrap() } }
1260         }
1261 
1262         fn __unstable_leak_raw_message(self) -> *mut $std$::ffi::c_void {
1263           let s = $std$::mem::ManuallyDrop::new(self);
1264           s.raw_msg().as_ptr() as *mut _
1265         }
1266       }
1267 
1268       impl<'a> $pb$::MessageMutInterop<'a> for $Msg$Mut<'a> {
1269         unsafe fn __unstable_wrap_raw_message_mut(
1270             msg: &'a mut *mut $std$::ffi::c_void) -> Self {
1271           Self {
1272             inner: $pbr$::MutatorMessageRef::wrap_raw(
1273                 $pbr$::RawMessage::new(*msg as *mut _).unwrap())
1274           }
1275         }
1276         unsafe fn __unstable_wrap_raw_message_mut_unchecked_lifetime(
1277             msg: *mut $std$::ffi::c_void) -> Self {
1278           Self {
1279             inner: $pbr$::MutatorMessageRef::wrap_raw(
1280                 $pbr$::RawMessage::new(msg as *mut _).unwrap())
1281           }
1282         }
1283         fn __unstable_as_raw_message_mut(&mut self) -> *mut $std$::ffi::c_void {
1284           self.raw_msg().as_ptr() as *mut _
1285         }
1286       }
1287 
1288       impl<'a> $pb$::MessageViewInterop<'a> for $Msg$View<'a> {
1289         unsafe fn __unstable_wrap_raw_message(
1290           msg: &'a *const $std$::ffi::c_void) -> Self {
1291           Self::new($pbi$::Private, $pbr$::RawMessage::new(*msg as *mut _).unwrap())
1292         }
1293         unsafe fn __unstable_wrap_raw_message_unchecked_lifetime(
1294           msg: *const $std$::ffi::c_void) -> Self {
1295           Self::new($pbi$::Private, $pbr$::RawMessage::new(msg as *mut _).unwrap())
1296         }
1297         fn __unstable_as_raw_message(&self) -> *const $std$::ffi::c_void {
1298           self.msg.as_ptr() as *const _
1299         }
1300       }
1301 
1302       impl $pbi$::MatcherEq for $Msg$ {
1303         fn matches(&self, o: &Self) -> bool {
1304           $pbi$::MatcherEq::matches(
1305             &$pb$::AsView::as_view(self),
1306             &$pb$::AsView::as_view(o))
1307         }
1308       }
1309 
1310       impl<'a> $pbi$::MatcherEq for $Msg$Mut<'a> {
1311         fn matches(&self, o: &Self) -> bool {
1312           $pbi$::MatcherEq::matches(
1313             &$pb$::AsView::as_view(self),
1314             &$pb$::AsView::as_view(o))
1315         }
1316       }
1317 
1318       impl<'a> $pbi$::MatcherEq for $Msg$View<'a> {
1319         fn matches(&self, o: &Self) -> bool {
1320           unsafe {
1321             $pbr$::raw_message_equals(self.msg, o.msg)
1322           }
1323         }
1324       }
1325     )rs");
1326   } else {
1327     ctx.Emit({{"Msg", RsSafeName(msg.name())}}, R"rs(
1328       // upb kernel doesn't support any owned message or message mut interop.
1329       impl $pb$::OwnedMessageInterop for $Msg$ {}
1330       impl<'a> $pb$::MessageMutInterop<'a> for $Msg$Mut<'a> {}
1331 
1332       impl<'a> $pb$::MessageViewInterop<'a> for $Msg$View<'a> {
1333         unsafe fn __unstable_wrap_raw_message(
1334           msg: &'a *const $std$::ffi::c_void) -> Self {
1335           Self::new($pbi$::Private, $pbr$::RawMessage::new(*msg as *mut _).unwrap())
1336         }
1337         unsafe fn __unstable_wrap_raw_message_unchecked_lifetime(
1338           msg: *const $std$::ffi::c_void) -> Self {
1339           Self::new($pbi$::Private, $pbr$::RawMessage::new(msg as *mut _).unwrap())
1340         }
1341         fn __unstable_as_raw_message(&self) -> *const $std$::ffi::c_void {
1342           self.msg.as_ptr() as *const _
1343         }
1344       }
1345 
1346       impl $pbi$::MatcherEq for $Msg$ {
1347         fn matches(&self, o: &Self) -> bool {
1348           $pbi$::MatcherEq::matches(
1349             &$pb$::AsView::as_view(self),
1350             &$pb$::AsView::as_view(o))
1351         }
1352       }
1353 
1354       impl<'a> $pbi$::MatcherEq for $Msg$Mut<'a> {
1355         fn matches(&self, o: &Self) -> bool {
1356           $pbi$::MatcherEq::matches(
1357             &$pb$::AsView::as_view(self),
1358             &$pb$::AsView::as_view(o))
1359         }
1360       }
1361 
1362       impl<'a> $pbi$::MatcherEq for $Msg$View<'a> {
1363         fn matches(&self, o: &Self) -> bool {
1364           unsafe {
1365             $pbr$::upb_Message_IsEqual(
1366                 self.msg,
1367                 o.msg,
1368                 <$Msg$ as $pbr$::AssociatedMiniTable>::mini_table(),
1369                 0)
1370           }
1371         }
1372       }
1373     )rs");
1374   }
1375 }  // NOLINT(readability/fn_size)
1376 
1377 // Generates code for a particular message in `.pb.thunk.cc`.
GenerateThunksCc(Context & ctx,const Descriptor & msg)1378 void GenerateThunksCc(Context& ctx, const Descriptor& msg) {
1379   ABSL_CHECK(ctx.is_cpp());
1380   if (msg.map_key() != nullptr) {
1381     // Don't generate code for synthetic MapEntry messages.
1382     return;
1383   }
1384 
1385   ctx.Emit(
1386       {{"abi", "\"C\""},  // Workaround for syntax highlight bug in VSCode.
1387        {"Msg", RsSafeName(msg.name())},
1388        {"QualifiedMsg", cpp::QualifiedClassName(&msg)},
1389        {"new_thunk", ThunkName(ctx, msg, "new")},
1390        {"default_instance_thunk", ThunkName(ctx, msg, "default_instance")},
1391        {"repeated_new_thunk", ThunkName(ctx, msg, "repeated_new")},
1392        {"repeated_free_thunk", ThunkName(ctx, msg, "repeated_free")},
1393        {"repeated_len_thunk", ThunkName(ctx, msg, "repeated_len")},
1394        {"repeated_get_thunk", ThunkName(ctx, msg, "repeated_get")},
1395        {"repeated_get_mut_thunk", ThunkName(ctx, msg, "repeated_get_mut")},
1396        {"repeated_add_thunk", ThunkName(ctx, msg, "repeated_add")},
1397        {"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
1398        {"repeated_copy_from_thunk", ThunkName(ctx, msg, "repeated_copy_from")},
1399        {"repeated_reserve_thunk", ThunkName(ctx, msg, "repeated_reserve")},
1400        {"map_size_info_thunk", ThunkName(ctx, msg, "size_info")},
1401        {"nested_msg_thunks",
1402         [&] {
1403           for (int i = 0; i < msg.nested_type_count(); ++i) {
1404             GenerateThunksCc(ctx, *msg.nested_type(i));
1405           }
1406         }},
1407        {"accessor_thunks",
1408         [&] {
1409           for (int i = 0; i < msg.field_count(); ++i) {
1410             GenerateAccessorThunkCc(ctx, *msg.field(i));
1411           }
1412         }},
1413        {"oneof_thunks",
1414         [&] {
1415           for (int i = 0; i < msg.real_oneof_decl_count(); ++i) {
1416             GenerateOneofThunkCc(ctx, *msg.real_oneof_decl(i));
1417           }
1418         }}},
1419       R"cc(
1420         //~ $abi$ is a workaround for a syntax highlight bug in VSCode.
1421         // However, ~ that confuses clang-format (it refuses to keep the
1422         // newline after ~ `$abi${`). Disabling clang-format for the block.
1423         // clang-format off
1424         extern $abi$ {
1425         void* $new_thunk$() { return new $QualifiedMsg$(); }
1426 
1427         const google::protobuf::MessageLite* $default_instance_thunk$() {
1428           return &$QualifiedMsg$::default_instance();
1429         }
1430 
1431         void* $repeated_new_thunk$() {
1432           return new google::protobuf::RepeatedPtrField<$QualifiedMsg$>();
1433         }
1434 
1435         void $repeated_free_thunk$(void* ptr) {
1436           delete static_cast<google::protobuf::RepeatedPtrField<$QualifiedMsg$>*>(ptr);
1437         }
1438 
1439         size_t $repeated_len_thunk$(google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field) {
1440           return field->size();
1441         }
1442         const $QualifiedMsg$* $repeated_get_thunk$(
1443           google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field,
1444           size_t index) {
1445           return &field->Get(index);
1446         }
1447         $QualifiedMsg$* $repeated_get_mut_thunk$(
1448           google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field,
1449           size_t index) {
1450           return field->Mutable(index);
1451         }
1452         $QualifiedMsg$* $repeated_add_thunk$(google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field) {
1453           return field->Add();
1454         }
1455         void $repeated_clear_thunk$(google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field) {
1456           field->Clear();
1457         }
1458         void $repeated_copy_from_thunk$(
1459           google::protobuf::RepeatedPtrField<$QualifiedMsg$>& dst,
1460           const google::protobuf::RepeatedPtrField<$QualifiedMsg$>& src) {
1461           dst = src;
1462         }
1463         void $repeated_reserve_thunk$(
1464           google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field,
1465           size_t additional) {
1466           field->Reserve(field->size() + additional);
1467         }
1468         google::protobuf::internal::MapNodeSizeInfoT $map_size_info_thunk$(int32_t i) {
1469           static constexpr google::protobuf::internal::MapNodeSizeInfoT size_infos[] = {)cc"
1470       // LINT.IfChange(size_info_mapping)
1471       R"cc(
1472         google::protobuf::internal::RustMapHelper::SizeInfo<int32_t, $QualifiedMsg$>(),
1473             google::protobuf::internal::RustMapHelper::SizeInfo<int64_t,
1474                                                       $QualifiedMsg$>(),
1475             google::protobuf::internal::RustMapHelper::SizeInfo<bool, $QualifiedMsg$>(),
1476             google::protobuf::internal::RustMapHelper::SizeInfo<std::string,
1477                                                       $QualifiedMsg$>()
1478       )cc"
1479       // LINT.ThenChange(//depot/google3/third_party/protobuf/rust/cpp.rs:size_info_mapping)
1480       R"cc(
1481         }
1482         ;
1483         return size_infos[i];
1484         }
1485 
1486         $accessor_thunks$
1487 
1488             $oneof_thunks$
1489         }  // extern $abi$
1490         // clang-format on
1491 
1492         $nested_msg_thunks$
1493       )cc");
1494 }
1495 
1496 }  // namespace rust
1497 }  // namespace compiler
1498 }  // namespace protobuf
1499 }  // namespace google
1500