• 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 "upb/util/def_to_proto.h"
9 
10 #include <inttypes.h>
11 #include <math.h>
12 
13 #include "google/protobuf/descriptor.upb.h"
14 #include "upb/base/descriptor_constants.h"
15 #include "upb/port/vsnprintf_compat.h"
16 #include "upb/reflection/def.h"
17 #include "upb/reflection/enum_reserved_range.h"
18 #include "upb/reflection/extension_range.h"
19 #include "upb/reflection/internal/field_def.h"
20 #include "upb/reflection/internal/file_def.h"
21 #include "upb/reflection/message.h"
22 #include "upb/reflection/message_reserved_range.h"
23 
24 // Must be last.
25 #include "upb/port/def.inc"
26 
27 typedef struct {
28   upb_Arena* arena;
29   jmp_buf err;
30 } upb_ToProto_Context;
31 
32 #define CHK_OOM(val) \
33   if (!(val)) UPB_LONGJMP(ctx->err, 1);
34 
35 // We want to copy the options verbatim into the destination options proto.
36 // We use serialize+parse as our deep copy.
37 #define SET_OPTIONS(proto, desc_type, options_type, src)                  \
38   {                                                                       \
39     size_t size;                                                          \
40     /* MEM: could use a temporary arena here instead. */                  \
41     char* pb = google_protobuf_##options_type##_serialize(src, ctx->arena, &size); \
42     CHK_OOM(pb);                                                          \
43     google_protobuf_##options_type* dst =                                          \
44         google_protobuf_##options_type##_parse(pb, size, ctx->arena);              \
45     CHK_OOM(dst);                                                         \
46     google_protobuf_##desc_type##_set_options(proto, dst);                         \
47   }
48 
strviewdup2(upb_ToProto_Context * ctx,upb_StringView str)49 static upb_StringView strviewdup2(upb_ToProto_Context* ctx,
50                                   upb_StringView str) {
51   char* p = upb_Arena_Malloc(ctx->arena, str.size);
52   CHK_OOM(p);
53   memcpy(p, str.data, str.size);
54   return (upb_StringView){.data = p, .size = str.size};
55 }
56 
strviewdup(upb_ToProto_Context * ctx,const char * s)57 static upb_StringView strviewdup(upb_ToProto_Context* ctx, const char* s) {
58   return strviewdup2(ctx, (upb_StringView){.data = s, .size = strlen(s)});
59 }
60 
qual_dup(upb_ToProto_Context * ctx,const char * s)61 static upb_StringView qual_dup(upb_ToProto_Context* ctx, const char* s) {
62   size_t n = strlen(s);
63   char* p = upb_Arena_Malloc(ctx->arena, n + 1);
64   CHK_OOM(p);
65   p[0] = '.';
66   memcpy(p + 1, s, n);
67   return (upb_StringView){.data = p, .size = n + 1};
68 }
69 
70 UPB_PRINTF(2, 3)
printf_dup(upb_ToProto_Context * ctx,const char * fmt,...)71 static upb_StringView printf_dup(upb_ToProto_Context* ctx, const char* fmt,
72                                  ...) {
73   const size_t max = 32;
74   char* p = upb_Arena_Malloc(ctx->arena, max);
75   CHK_OOM(p);
76   va_list args;
77   va_start(args, fmt);
78   size_t n = _upb_vsnprintf(p, max, fmt, args);
79   va_end(args);
80   UPB_ASSERT(n < max);
81   return (upb_StringView){.data = p, .size = n};
82 }
83 
upb_isprint(char ch)84 static bool upb_isprint(char ch) { return ch >= 0x20 && ch <= 0x7f; }
85 
special_escape(char ch)86 static int special_escape(char ch) {
87   switch (ch) {
88     // This is the same set of special escapes recognized by
89     // absl::CEscape().
90     case '\n':
91       return 'n';
92     case '\r':
93       return 'r';
94     case '\t':
95       return 't';
96     case '\\':
97       return '\\';
98     case '\'':
99       return '\'';
100     case '"':
101       return '"';
102     default:
103       return -1;
104   }
105 }
106 
default_bytes(upb_ToProto_Context * ctx,upb_StringView val)107 static upb_StringView default_bytes(upb_ToProto_Context* ctx,
108                                     upb_StringView val) {
109   size_t n = 0;
110   for (size_t i = 0; i < val.size; i++) {
111     char ch = val.data[i];
112     if (special_escape(ch) >= 0)
113       n += 2;  // '\C'
114     else if (upb_isprint(ch))
115       n += 1;
116     else
117       n += 4;  // '\123'
118   }
119   char* p = upb_Arena_Malloc(ctx->arena, n);
120   CHK_OOM(p);
121   char* dst = p;
122   const char* src = val.data;
123   const char* end = src + val.size;
124   while (src < end) {
125     unsigned char ch = *src++;
126     if (special_escape(ch) >= 0) {
127       *dst++ = '\\';
128       *dst++ = (char)special_escape(ch);
129     } else if (upb_isprint(ch)) {
130       *dst++ = ch;
131     } else {
132       *dst++ = '\\';
133       *dst++ = '0' + (ch >> 6);
134       *dst++ = '0' + ((ch >> 3) & 0x7);
135       *dst++ = '0' + (ch & 0x7);
136     }
137   }
138   return (upb_StringView){.data = p, .size = n};
139 }
140 
default_string(upb_ToProto_Context * ctx,const upb_FieldDef * f)141 static upb_StringView default_string(upb_ToProto_Context* ctx,
142                                      const upb_FieldDef* f) {
143   upb_MessageValue d = upb_FieldDef_Default(f);
144   upb_CType type = upb_FieldDef_CType(f);
145 
146   if (type == kUpb_CType_Float || type == kUpb_CType_Double) {
147     double val = type == kUpb_CType_Float ? d.float_val : d.double_val;
148     if (val == INFINITY) {
149       return strviewdup(ctx, "inf");
150     } else if (val == -INFINITY) {
151       return strviewdup(ctx, "-inf");
152     } else if (val != val) {
153       return strviewdup(ctx, "nan");
154     }
155   }
156 
157   switch (upb_FieldDef_CType(f)) {
158     case kUpb_CType_Bool:
159       return strviewdup(ctx, d.bool_val ? "true" : "false");
160     case kUpb_CType_Enum: {
161       const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
162       const upb_EnumValueDef* ev =
163           upb_EnumDef_FindValueByNumber(e, d.int32_val);
164       return strviewdup(ctx, upb_EnumValueDef_Name(ev));
165     }
166     case kUpb_CType_Int64:
167       return printf_dup(ctx, "%" PRId64, d.int64_val);
168     case kUpb_CType_UInt64:
169       return printf_dup(ctx, "%" PRIu64, d.uint64_val);
170     case kUpb_CType_Int32:
171       return printf_dup(ctx, "%" PRId32, d.int32_val);
172     case kUpb_CType_UInt32:
173       return printf_dup(ctx, "%" PRIu32, d.uint32_val);
174     case kUpb_CType_Float:
175       return printf_dup(ctx, "%.9g", d.float_val);
176     case kUpb_CType_Double:
177       return printf_dup(ctx, "%.17g", d.double_val);
178     case kUpb_CType_String:
179       return strviewdup2(ctx, d.str_val);
180     case kUpb_CType_Bytes:
181       return default_bytes(ctx, d.str_val);
182     default:
183       UPB_UNREACHABLE();
184   }
185 }
186 
resrange_toproto(upb_ToProto_Context * ctx,const upb_MessageReservedRange * r)187 static google_protobuf_DescriptorProto_ReservedRange* resrange_toproto(
188     upb_ToProto_Context* ctx, const upb_MessageReservedRange* r) {
189   google_protobuf_DescriptorProto_ReservedRange* proto =
190       google_protobuf_DescriptorProto_ReservedRange_new(ctx->arena);
191   CHK_OOM(proto);
192 
193   google_protobuf_DescriptorProto_ReservedRange_set_start(
194       proto, upb_MessageReservedRange_Start(r));
195   google_protobuf_DescriptorProto_ReservedRange_set_end(proto,
196                                                upb_MessageReservedRange_End(r));
197 
198   return proto;
199 }
200 
enumresrange_toproto(upb_ToProto_Context * ctx,const upb_EnumReservedRange * r)201 static google_protobuf_EnumDescriptorProto_EnumReservedRange* enumresrange_toproto(
202     upb_ToProto_Context* ctx, const upb_EnumReservedRange* r) {
203   google_protobuf_EnumDescriptorProto_EnumReservedRange* proto =
204       google_protobuf_EnumDescriptorProto_EnumReservedRange_new(ctx->arena);
205   CHK_OOM(proto);
206 
207   google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(
208       proto, upb_EnumReservedRange_Start(r));
209   google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(
210       proto, upb_EnumReservedRange_End(r));
211 
212   return proto;
213 }
214 
fielddef_toproto(upb_ToProto_Context * ctx,const upb_FieldDef * f)215 static google_protobuf_FieldDescriptorProto* fielddef_toproto(upb_ToProto_Context* ctx,
216                                                      const upb_FieldDef* f) {
217   google_protobuf_FieldDescriptorProto* proto =
218       google_protobuf_FieldDescriptorProto_new(ctx->arena);
219   CHK_OOM(proto);
220 
221   google_protobuf_FieldDescriptorProto_set_name(proto,
222                                        strviewdup(ctx, upb_FieldDef_Name(f)));
223   google_protobuf_FieldDescriptorProto_set_number(proto, upb_FieldDef_Number(f));
224 
225   if (upb_FieldDef_IsRequired(f) &&
226       upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) {
227     google_protobuf_FieldDescriptorProto_set_label(
228         proto, UPB_DESC(FieldDescriptorProto_LABEL_OPTIONAL));
229   } else {
230     google_protobuf_FieldDescriptorProto_set_label(proto, upb_FieldDef_Label(f));
231   }
232   if (upb_FieldDef_Type(f) == kUpb_FieldType_Group &&
233       upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) {
234     google_protobuf_FieldDescriptorProto_set_type(proto, kUpb_FieldType_Message);
235   } else {
236     google_protobuf_FieldDescriptorProto_set_type(proto, upb_FieldDef_Type(f));
237   }
238 
239   if (upb_FieldDef_HasJsonName(f)) {
240     google_protobuf_FieldDescriptorProto_set_json_name(
241         proto, strviewdup(ctx, upb_FieldDef_JsonName(f)));
242   }
243 
244   if (upb_FieldDef_IsSubMessage(f)) {
245     google_protobuf_FieldDescriptorProto_set_type_name(
246         proto,
247         qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(f))));
248   } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum) {
249     google_protobuf_FieldDescriptorProto_set_type_name(
250         proto, qual_dup(ctx, upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f))));
251   }
252 
253   if (upb_FieldDef_IsExtension(f)) {
254     google_protobuf_FieldDescriptorProto_set_extendee(
255         proto,
256         qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_ContainingType(f))));
257   }
258 
259   if (upb_FieldDef_HasDefault(f)) {
260     google_protobuf_FieldDescriptorProto_set_default_value(proto,
261                                                   default_string(ctx, f));
262   }
263 
264   const upb_OneofDef* o = upb_FieldDef_ContainingOneof(f);
265   if (o) {
266     google_protobuf_FieldDescriptorProto_set_oneof_index(proto, upb_OneofDef_Index(o));
267   }
268 
269   if (_upb_FieldDef_IsProto3Optional(f)) {
270     google_protobuf_FieldDescriptorProto_set_proto3_optional(proto, true);
271   }
272 
273   if (upb_FieldDef_HasOptions(f)) {
274     SET_OPTIONS(proto, FieldDescriptorProto, FieldOptions,
275                 upb_FieldDef_Options(f));
276   }
277 
278   return proto;
279 }
280 
oneofdef_toproto(upb_ToProto_Context * ctx,const upb_OneofDef * o)281 static google_protobuf_OneofDescriptorProto* oneofdef_toproto(upb_ToProto_Context* ctx,
282                                                      const upb_OneofDef* o) {
283   google_protobuf_OneofDescriptorProto* proto =
284       google_protobuf_OneofDescriptorProto_new(ctx->arena);
285   CHK_OOM(proto);
286 
287   google_protobuf_OneofDescriptorProto_set_name(proto,
288                                        strviewdup(ctx, upb_OneofDef_Name(o)));
289 
290   if (upb_OneofDef_HasOptions(o)) {
291     SET_OPTIONS(proto, OneofDescriptorProto, OneofOptions,
292                 upb_OneofDef_Options(o));
293   }
294 
295   return proto;
296 }
297 
enumvaldef_toproto(upb_ToProto_Context * ctx,const upb_EnumValueDef * e)298 static google_protobuf_EnumValueDescriptorProto* enumvaldef_toproto(
299     upb_ToProto_Context* ctx, const upb_EnumValueDef* e) {
300   google_protobuf_EnumValueDescriptorProto* proto =
301       google_protobuf_EnumValueDescriptorProto_new(ctx->arena);
302   CHK_OOM(proto);
303 
304   google_protobuf_EnumValueDescriptorProto_set_name(
305       proto, strviewdup(ctx, upb_EnumValueDef_Name(e)));
306   google_protobuf_EnumValueDescriptorProto_set_number(proto, upb_EnumValueDef_Number(e));
307 
308   if (upb_EnumValueDef_HasOptions(e)) {
309     SET_OPTIONS(proto, EnumValueDescriptorProto, EnumValueOptions,
310                 upb_EnumValueDef_Options(e));
311   }
312 
313   return proto;
314 }
315 
enumdef_toproto(upb_ToProto_Context * ctx,const upb_EnumDef * e)316 static google_protobuf_EnumDescriptorProto* enumdef_toproto(upb_ToProto_Context* ctx,
317                                                    const upb_EnumDef* e) {
318   google_protobuf_EnumDescriptorProto* proto =
319       google_protobuf_EnumDescriptorProto_new(ctx->arena);
320   CHK_OOM(proto);
321 
322   google_protobuf_EnumDescriptorProto_set_name(proto,
323                                       strviewdup(ctx, upb_EnumDef_Name(e)));
324 
325   int n = upb_EnumDef_ValueCount(e);
326   google_protobuf_EnumValueDescriptorProto** vals =
327       google_protobuf_EnumDescriptorProto_resize_value(proto, n, ctx->arena);
328   CHK_OOM(vals);
329   for (int i = 0; i < n; i++) {
330     vals[i] = enumvaldef_toproto(ctx, upb_EnumDef_Value(e, i));
331   }
332 
333   n = upb_EnumDef_ReservedRangeCount(e);
334   google_protobuf_EnumDescriptorProto_EnumReservedRange** res_ranges =
335       google_protobuf_EnumDescriptorProto_resize_reserved_range(proto, n, ctx->arena);
336   for (int i = 0; i < n; i++) {
337     res_ranges[i] = enumresrange_toproto(ctx, upb_EnumDef_ReservedRange(e, i));
338   }
339 
340   n = upb_EnumDef_ReservedNameCount(e);
341   upb_StringView* res_names =
342       google_protobuf_EnumDescriptorProto_resize_reserved_name(proto, n, ctx->arena);
343   for (int i = 0; i < n; i++) {
344     res_names[i] = upb_EnumDef_ReservedName(e, i);
345   }
346 
347   if (upb_EnumDef_HasOptions(e)) {
348     SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions,
349                 upb_EnumDef_Options(e));
350   }
351 
352   return proto;
353 }
354 
extrange_toproto(upb_ToProto_Context * ctx,const upb_ExtensionRange * e)355 static google_protobuf_DescriptorProto_ExtensionRange* extrange_toproto(
356     upb_ToProto_Context* ctx, const upb_ExtensionRange* e) {
357   google_protobuf_DescriptorProto_ExtensionRange* proto =
358       google_protobuf_DescriptorProto_ExtensionRange_new(ctx->arena);
359   CHK_OOM(proto);
360 
361   google_protobuf_DescriptorProto_ExtensionRange_set_start(proto,
362                                                   upb_ExtensionRange_Start(e));
363   google_protobuf_DescriptorProto_ExtensionRange_set_end(proto,
364                                                 upb_ExtensionRange_End(e));
365 
366   if (upb_ExtensionRange_HasOptions(e)) {
367     SET_OPTIONS(proto, DescriptorProto_ExtensionRange, ExtensionRangeOptions,
368                 upb_ExtensionRange_Options(e));
369   }
370 
371   return proto;
372 }
373 
msgdef_toproto(upb_ToProto_Context * ctx,const upb_MessageDef * m)374 static google_protobuf_DescriptorProto* msgdef_toproto(upb_ToProto_Context* ctx,
375                                               const upb_MessageDef* m) {
376   google_protobuf_DescriptorProto* proto = google_protobuf_DescriptorProto_new(ctx->arena);
377   CHK_OOM(proto);
378 
379   google_protobuf_DescriptorProto_set_name(proto,
380                                   strviewdup(ctx, upb_MessageDef_Name(m)));
381 
382   int n;
383 
384   n = upb_MessageDef_FieldCount(m);
385   google_protobuf_FieldDescriptorProto** fields =
386       google_protobuf_DescriptorProto_resize_field(proto, n, ctx->arena);
387   CHK_OOM(fields);
388   for (int i = 0; i < n; i++) {
389     fields[i] = fielddef_toproto(ctx, upb_MessageDef_Field(m, i));
390   }
391 
392   n = upb_MessageDef_OneofCount(m);
393   google_protobuf_OneofDescriptorProto** oneofs =
394       google_protobuf_DescriptorProto_resize_oneof_decl(proto, n, ctx->arena);
395   for (int i = 0; i < n; i++) {
396     oneofs[i] = oneofdef_toproto(ctx, upb_MessageDef_Oneof(m, i));
397   }
398 
399   n = upb_MessageDef_NestedMessageCount(m);
400   google_protobuf_DescriptorProto** nested_msgs =
401       google_protobuf_DescriptorProto_resize_nested_type(proto, n, ctx->arena);
402   for (int i = 0; i < n; i++) {
403     nested_msgs[i] = msgdef_toproto(ctx, upb_MessageDef_NestedMessage(m, i));
404   }
405 
406   n = upb_MessageDef_NestedEnumCount(m);
407   google_protobuf_EnumDescriptorProto** nested_enums =
408       google_protobuf_DescriptorProto_resize_enum_type(proto, n, ctx->arena);
409   for (int i = 0; i < n; i++) {
410     nested_enums[i] = enumdef_toproto(ctx, upb_MessageDef_NestedEnum(m, i));
411   }
412 
413   n = upb_MessageDef_NestedExtensionCount(m);
414   google_protobuf_FieldDescriptorProto** nested_exts =
415       google_protobuf_DescriptorProto_resize_extension(proto, n, ctx->arena);
416   for (int i = 0; i < n; i++) {
417     nested_exts[i] =
418         fielddef_toproto(ctx, upb_MessageDef_NestedExtension(m, i));
419   }
420 
421   n = upb_MessageDef_ExtensionRangeCount(m);
422   google_protobuf_DescriptorProto_ExtensionRange** ext_ranges =
423       google_protobuf_DescriptorProto_resize_extension_range(proto, n, ctx->arena);
424   for (int i = 0; i < n; i++) {
425     ext_ranges[i] = extrange_toproto(ctx, upb_MessageDef_ExtensionRange(m, i));
426   }
427 
428   n = upb_MessageDef_ReservedRangeCount(m);
429   google_protobuf_DescriptorProto_ReservedRange** res_ranges =
430       google_protobuf_DescriptorProto_resize_reserved_range(proto, n, ctx->arena);
431   for (int i = 0; i < n; i++) {
432     res_ranges[i] = resrange_toproto(ctx, upb_MessageDef_ReservedRange(m, i));
433   }
434 
435   n = upb_MessageDef_ReservedNameCount(m);
436   upb_StringView* res_names =
437       google_protobuf_DescriptorProto_resize_reserved_name(proto, n, ctx->arena);
438   for (int i = 0; i < n; i++) {
439     res_names[i] = upb_MessageDef_ReservedName(m, i);
440   }
441 
442   if (upb_MessageDef_HasOptions(m)) {
443     SET_OPTIONS(proto, DescriptorProto, MessageOptions,
444                 upb_MessageDef_Options(m));
445   }
446 
447   return proto;
448 }
449 
methoddef_toproto(upb_ToProto_Context * ctx,const upb_MethodDef * m)450 static google_protobuf_MethodDescriptorProto* methoddef_toproto(upb_ToProto_Context* ctx,
451                                                        const upb_MethodDef* m) {
452   google_protobuf_MethodDescriptorProto* proto =
453       google_protobuf_MethodDescriptorProto_new(ctx->arena);
454   CHK_OOM(proto);
455 
456   google_protobuf_MethodDescriptorProto_set_name(proto,
457                                         strviewdup(ctx, upb_MethodDef_Name(m)));
458 
459   google_protobuf_MethodDescriptorProto_set_input_type(
460       proto,
461       qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_InputType(m))));
462   google_protobuf_MethodDescriptorProto_set_output_type(
463       proto,
464       qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_OutputType(m))));
465 
466   if (upb_MethodDef_ClientStreaming(m)) {
467     google_protobuf_MethodDescriptorProto_set_client_streaming(proto, true);
468   }
469 
470   if (upb_MethodDef_ServerStreaming(m)) {
471     google_protobuf_MethodDescriptorProto_set_server_streaming(proto, true);
472   }
473 
474   if (upb_MethodDef_HasOptions(m)) {
475     SET_OPTIONS(proto, MethodDescriptorProto, MethodOptions,
476                 upb_MethodDef_Options(m));
477   }
478 
479   return proto;
480 }
481 
servicedef_toproto(upb_ToProto_Context * ctx,const upb_ServiceDef * s)482 static google_protobuf_ServiceDescriptorProto* servicedef_toproto(
483     upb_ToProto_Context* ctx, const upb_ServiceDef* s) {
484   google_protobuf_ServiceDescriptorProto* proto =
485       google_protobuf_ServiceDescriptorProto_new(ctx->arena);
486   CHK_OOM(proto);
487 
488   google_protobuf_ServiceDescriptorProto_set_name(
489       proto, strviewdup(ctx, upb_ServiceDef_Name(s)));
490 
491   size_t n = upb_ServiceDef_MethodCount(s);
492   google_protobuf_MethodDescriptorProto** methods =
493       google_protobuf_ServiceDescriptorProto_resize_method(proto, n, ctx->arena);
494   for (size_t i = 0; i < n; i++) {
495     methods[i] = methoddef_toproto(ctx, upb_ServiceDef_Method(s, i));
496   }
497 
498   if (upb_ServiceDef_HasOptions(s)) {
499     SET_OPTIONS(proto, ServiceDescriptorProto, ServiceOptions,
500                 upb_ServiceDef_Options(s));
501   }
502 
503   return proto;
504 }
505 
filedef_toproto(upb_ToProto_Context * ctx,const upb_FileDef * f)506 static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context* ctx,
507                                                    const upb_FileDef* f) {
508   google_protobuf_FileDescriptorProto* proto =
509       google_protobuf_FileDescriptorProto_new(ctx->arena);
510   CHK_OOM(proto);
511 
512   google_protobuf_FileDescriptorProto_set_name(proto,
513                                       strviewdup(ctx, upb_FileDef_Name(f)));
514 
515   const char* package = upb_FileDef_Package(f);
516   if (package) {
517     size_t n = strlen(package);
518     if (n) {
519       google_protobuf_FileDescriptorProto_set_package(proto, strviewdup(ctx, package));
520     }
521   }
522 
523   if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) {
524     google_protobuf_FileDescriptorProto_set_edition(proto, upb_FileDef_Edition(f));
525   }
526 
527   if (upb_FileDef_Syntax(f) == kUpb_Syntax_Proto3) {
528     google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "proto3"));
529   } else if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) {
530     google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "editions"));
531   }
532 
533   size_t n;
534   n = upb_FileDef_DependencyCount(f);
535   upb_StringView* deps =
536       google_protobuf_FileDescriptorProto_resize_dependency(proto, n, ctx->arena);
537   for (size_t i = 0; i < n; i++) {
538     deps[i] = strviewdup(ctx, upb_FileDef_Name(upb_FileDef_Dependency(f, i)));
539   }
540 
541   n = upb_FileDef_PublicDependencyCount(f);
542   int32_t* public_deps =
543       google_protobuf_FileDescriptorProto_resize_public_dependency(proto, n, ctx->arena);
544   const int32_t* public_dep_nums = _upb_FileDef_PublicDependencyIndexes(f);
545   if (n) memcpy(public_deps, public_dep_nums, n * sizeof(int32_t));
546 
547   n = upb_FileDef_WeakDependencyCount(f);
548   int32_t* weak_deps =
549       google_protobuf_FileDescriptorProto_resize_weak_dependency(proto, n, ctx->arena);
550   const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f);
551   if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t));
552 
553   n = upb_FileDef_TopLevelMessageCount(f);
554   google_protobuf_DescriptorProto** msgs =
555       google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena);
556   for (size_t i = 0; i < n; i++) {
557     msgs[i] = msgdef_toproto(ctx, upb_FileDef_TopLevelMessage(f, i));
558   }
559 
560   n = upb_FileDef_TopLevelEnumCount(f);
561   google_protobuf_EnumDescriptorProto** enums =
562       google_protobuf_FileDescriptorProto_resize_enum_type(proto, n, ctx->arena);
563   for (size_t i = 0; i < n; i++) {
564     enums[i] = enumdef_toproto(ctx, upb_FileDef_TopLevelEnum(f, i));
565   }
566 
567   n = upb_FileDef_ServiceCount(f);
568   google_protobuf_ServiceDescriptorProto** services =
569       google_protobuf_FileDescriptorProto_resize_service(proto, n, ctx->arena);
570   for (size_t i = 0; i < n; i++) {
571     services[i] = servicedef_toproto(ctx, upb_FileDef_Service(f, i));
572   }
573 
574   n = upb_FileDef_TopLevelExtensionCount(f);
575   google_protobuf_FieldDescriptorProto** exts =
576       google_protobuf_FileDescriptorProto_resize_extension(proto, n, ctx->arena);
577   for (size_t i = 0; i < n; i++) {
578     exts[i] = fielddef_toproto(ctx, upb_FileDef_TopLevelExtension(f, i));
579   }
580 
581   if (upb_FileDef_HasOptions(f)) {
582     SET_OPTIONS(proto, FileDescriptorProto, FileOptions,
583                 upb_FileDef_Options(f));
584   }
585 
586   return proto;
587 }
588 
upb_ToProto_ConvertMessageDef(upb_ToProto_Context * const ctx,const upb_MessageDef * const m)589 static google_protobuf_DescriptorProto* upb_ToProto_ConvertMessageDef(
590     upb_ToProto_Context* const ctx, const upb_MessageDef* const m) {
591   if (UPB_SETJMP(ctx->err)) return NULL;
592   return msgdef_toproto(ctx, m);
593 }
594 
upb_MessageDef_ToProto(const upb_MessageDef * m,upb_Arena * a)595 google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m,
596                                                upb_Arena* a) {
597   upb_ToProto_Context ctx = {a};
598   return upb_ToProto_ConvertMessageDef(&ctx, m);
599 }
600 
upb_ToProto_ConvertEnumDef(upb_ToProto_Context * const ctx,const upb_EnumDef * const e)601 google_protobuf_EnumDescriptorProto* upb_ToProto_ConvertEnumDef(
602     upb_ToProto_Context* const ctx, const upb_EnumDef* const e) {
603   if (UPB_SETJMP(ctx->err)) return NULL;
604   return enumdef_toproto(ctx, e);
605 }
606 
upb_EnumDef_ToProto(const upb_EnumDef * e,upb_Arena * a)607 google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e,
608                                                 upb_Arena* a) {
609   upb_ToProto_Context ctx = {a};
610   return upb_ToProto_ConvertEnumDef(&ctx, e);
611 }
612 
upb_ToProto_ConvertEnumValueDef(upb_ToProto_Context * const ctx,const upb_EnumValueDef * e)613 google_protobuf_EnumValueDescriptorProto* upb_ToProto_ConvertEnumValueDef(
614     upb_ToProto_Context* const ctx, const upb_EnumValueDef* e) {
615   if (UPB_SETJMP(ctx->err)) return NULL;
616   return enumvaldef_toproto(ctx, e);
617 }
618 
upb_EnumValueDef_ToProto(const upb_EnumValueDef * e,upb_Arena * a)619 google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto(
620     const upb_EnumValueDef* e, upb_Arena* a) {
621   upb_ToProto_Context ctx = {a};
622   return upb_ToProto_ConvertEnumValueDef(&ctx, e);
623 }
624 
upb_ToProto_ConvertFieldDef(upb_ToProto_Context * const ctx,const upb_FieldDef * f)625 google_protobuf_FieldDescriptorProto* upb_ToProto_ConvertFieldDef(
626     upb_ToProto_Context* const ctx, const upb_FieldDef* f) {
627   if (UPB_SETJMP(ctx->err)) return NULL;
628   return fielddef_toproto(ctx, f);
629 }
630 
upb_FieldDef_ToProto(const upb_FieldDef * f,upb_Arena * a)631 google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto(const upb_FieldDef* f,
632                                                   upb_Arena* a) {
633   upb_ToProto_Context ctx = {a};
634   return upb_ToProto_ConvertFieldDef(&ctx, f);
635 }
636 
upb_ToProto_ConvertOneofDef(upb_ToProto_Context * const ctx,const upb_OneofDef * o)637 google_protobuf_OneofDescriptorProto* upb_ToProto_ConvertOneofDef(
638     upb_ToProto_Context* const ctx, const upb_OneofDef* o) {
639   if (UPB_SETJMP(ctx->err)) return NULL;
640   return oneofdef_toproto(ctx, o);
641 }
642 
upb_OneofDef_ToProto(const upb_OneofDef * o,upb_Arena * a)643 google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto(const upb_OneofDef* o,
644                                                   upb_Arena* a) {
645   upb_ToProto_Context ctx = {a};
646   return upb_ToProto_ConvertOneofDef(&ctx, o);
647 }
648 
upb_ToProto_ConvertFileDef(upb_ToProto_Context * const ctx,const upb_FileDef * const f)649 google_protobuf_FileDescriptorProto* upb_ToProto_ConvertFileDef(
650     upb_ToProto_Context* const ctx, const upb_FileDef* const f) {
651   if (UPB_SETJMP(ctx->err)) return NULL;
652   return filedef_toproto(ctx, f);
653 }
654 
upb_FileDef_ToProto(const upb_FileDef * f,upb_Arena * a)655 google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f,
656                                                 upb_Arena* a) {
657   upb_ToProto_Context ctx = {a};
658   return upb_ToProto_ConvertFileDef(&ctx, f);
659 }
660 
upb_ToProto_ConvertMethodDef(upb_ToProto_Context * const ctx,const upb_MethodDef * m)661 google_protobuf_MethodDescriptorProto* upb_ToProto_ConvertMethodDef(
662     upb_ToProto_Context* const ctx, const upb_MethodDef* m) {
663   if (UPB_SETJMP(ctx->err)) return NULL;
664   return methoddef_toproto(ctx, m);
665 }
666 
upb_MethodDef_ToProto(const upb_MethodDef * const m,upb_Arena * a)667 google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto(
668     const upb_MethodDef* const m, upb_Arena* a) {
669   upb_ToProto_Context ctx = {a};
670   return upb_ToProto_ConvertMethodDef(&ctx, m);
671 }
672 
upb_ToProto_ConvertServiceDef(upb_ToProto_Context * const ctx,const upb_ServiceDef * const s)673 google_protobuf_ServiceDescriptorProto* upb_ToProto_ConvertServiceDef(
674     upb_ToProto_Context* const ctx, const upb_ServiceDef* const s) {
675   if (UPB_SETJMP(ctx->err)) return NULL;
676   return servicedef_toproto(ctx, s);
677 }
678 
upb_ServiceDef_ToProto(const upb_ServiceDef * s,upb_Arena * a)679 google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto(const upb_ServiceDef* s,
680                                                       upb_Arena* a) {
681   upb_ToProto_Context ctx = {a};
682   return upb_ToProto_ConvertServiceDef(&ctx, s);
683 }
684