Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / upb / upb / def.c
1
2 #include "upb/def.h"
3
4 #include <ctype.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include "google/protobuf/descriptor.upb.h"
9
10 #include "upb/port_def.inc"
11
12 typedef struct {
13   size_t len;
14   char str[1];  /* Null-terminated string data follows. */
15 } str_t;
16
17 static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) {
18   str_t *ret = upb_malloc(alloc, sizeof(*ret) + len);
19   if (!ret) return NULL;
20   ret->len = len;
21   memcpy(ret->str, data, len);
22   ret->str[len] = '\0';
23   return ret;
24 }
25
26 struct upb_fielddef {
27   const upb_filedef *file;
28   const upb_msgdef *msgdef;
29   const char *full_name;
30   union {
31     int64_t sint;
32     uint64_t uint;
33     double dbl;
34     float flt;
35     bool boolean;
36     str_t *str;
37   } defaultval;
38   const upb_oneofdef *oneof;
39   union {
40     const upb_msgdef *msgdef;
41     const upb_enumdef *enumdef;
42     const google_protobuf_FieldDescriptorProto *unresolved;
43   } sub;
44   uint32_t number_;
45   uint32_t index_;
46   uint32_t selector_base;  /* Used to index into a upb::Handlers table. */
47   bool is_extension_;
48   bool lazy_;
49   bool packed_;
50   upb_descriptortype_t type_;
51   upb_label_t label_;
52 };
53
54 struct upb_msgdef {
55   const upb_filedef *file;
56   const char *full_name;
57   uint32_t selector_count;
58   uint32_t submsg_field_count;
59
60   /* Tables for looking up fields by number and name. */
61   upb_inttable itof;
62   upb_strtable ntof;
63
64   const upb_fielddef *fields;
65   const upb_oneofdef *oneofs;
66   int field_count;
67   int oneof_count;
68
69   /* Is this a map-entry message? */
70   bool map_entry;
71   upb_wellknowntype_t well_known_type;
72
73   /* TODO(haberman): proper extension ranges (there can be multiple). */
74 };
75
76 struct upb_enumdef {
77   const upb_filedef *file;
78   const char *full_name;
79   upb_strtable ntoi;
80   upb_inttable iton;
81   int32_t defaultval;
82 };
83
84 struct upb_oneofdef {
85   const upb_msgdef *parent;
86   const char *full_name;
87   uint32_t index;
88   upb_strtable ntof;
89   upb_inttable itof;
90 };
91
92 struct upb_filedef {
93   const char *name;
94   const char *package;
95   const char *phpprefix;
96   const char *phpnamespace;
97   upb_syntax_t syntax;
98
99   const upb_filedef **deps;
100   const upb_msgdef *msgs;
101   const upb_enumdef *enums;
102   const upb_fielddef *exts;
103
104   int dep_count;
105   int msg_count;
106   int enum_count;
107   int ext_count;
108 };
109
110 struct upb_symtab {
111   upb_arena *arena;
112   upb_strtable syms;  /* full_name -> packed def ptr */
113   upb_strtable files;  /* file_name -> upb_filedef* */
114 };
115
116 /* Inside a symtab we store tagged pointers to specific def types. */
117 typedef enum {
118   UPB_DEFTYPE_MSG = 0,
119   UPB_DEFTYPE_ENUM = 1,
120   UPB_DEFTYPE_FIELD = 2,
121   UPB_DEFTYPE_ONEOF = 3
122 } upb_deftype_t;
123
124 static const void *unpack_def(upb_value v, upb_deftype_t type) {
125   uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
126   return (num & 3) == type ? (const void*)(num & ~3) : NULL;
127 }
128
129 static upb_value pack_def(const void *ptr, upb_deftype_t type) {
130   uintptr_t num = (uintptr_t)ptr | type;
131   return upb_value_constptr((const void*)num);
132 }
133
134 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
135 static bool upb_isbetween(char c, char low, char high) {
136   return c >= low && c <= high;
137 }
138
139 static bool upb_isletter(char c) {
140   return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
141 }
142
143 static bool upb_isalphanum(char c) {
144   return upb_isletter(c) || upb_isbetween(c, '0', '9');
145 }
146
147 static bool upb_isident(upb_strview name, bool full, upb_status *s) {
148   const char *str = name.data;
149   size_t len = name.size;
150   bool start = true;
151   size_t i;
152   for (i = 0; i < len; i++) {
153     char c = str[i];
154     if (c == '.') {
155       if (start || !full) {
156         upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
157         return false;
158       }
159       start = true;
160     } else if (start) {
161       if (!upb_isletter(c)) {
162         upb_status_seterrf(
163             s, "invalid name: path components must start with a letter (%s)",
164             str);
165         return false;
166       }
167       start = false;
168     } else {
169       if (!upb_isalphanum(c)) {
170         upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
171                            str);
172         return false;
173       }
174     }
175   }
176   return !start;
177 }
178
179 static const char *shortdefname(const char *fullname) {
180   const char *p;
181
182   if (fullname == NULL) {
183     return NULL;
184   } else if ((p = strrchr(fullname, '.')) == NULL) {
185     /* No '.' in the name, return the full string. */
186     return fullname;
187   } else {
188     /* Return one past the last '.'. */
189     return p + 1;
190   }
191 }
192
193 /* All submessage fields are lower than all other fields.
194  * Secondly, fields are increasing in order. */
195 uint32_t field_rank(const upb_fielddef *f) {
196   uint32_t ret = upb_fielddef_number(f);
197   const uint32_t high_bit = 1 << 30;
198   UPB_ASSERT(ret < high_bit);
199   if (!upb_fielddef_issubmsg(f))
200     ret |= high_bit;
201   return ret;
202 }
203
204 int cmp_fields(const void *p1, const void *p2) {
205   const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
206   const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
207   return field_rank(f1) - field_rank(f2);
208 }
209
210 /* A few implementation details of handlers.  We put these here to avoid
211  * a def -> handlers dependency. */
212
213 #define UPB_STATIC_SELECTOR_COUNT 3  /* Warning: also in upb/handlers.h. */
214
215 static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
216   return upb_fielddef_isseq(f) ? 2 : 0;
217 }
218
219 static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
220   uint32_t ret = 1;
221   if (upb_fielddef_isseq(f)) ret += 2;    /* STARTSEQ/ENDSEQ */
222   if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
223   if (upb_fielddef_issubmsg(f)) {
224     /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
225     ret += 0;
226     if (upb_fielddef_lazy(f)) {
227       /* STARTSTR/ENDSTR/STRING (for lazy) */
228       ret += 3;
229     }
230   }
231   return ret;
232 }
233
234 static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
235   /* Sort fields.  upb internally relies on UPB_TYPE_MESSAGE fields having the
236    * lowest indexes, but we do not publicly guarantee this. */
237   upb_msg_field_iter j;
238   upb_msg_oneof_iter k;
239   int i;
240   uint32_t selector;
241   int n = upb_msgdef_numfields(m);
242   upb_fielddef **fields;
243
244   if (n == 0) {
245     m->selector_count = UPB_STATIC_SELECTOR_COUNT;
246     m->submsg_field_count = 0;
247     return true;
248   }
249
250   fields = upb_gmalloc(n * sizeof(*fields));
251   if (!fields) {
252     upb_status_setoom(s);
253     return false;
254   }
255
256   m->submsg_field_count = 0;
257   for(i = 0, upb_msg_field_begin(&j, m);
258       !upb_msg_field_done(&j);
259       upb_msg_field_next(&j), i++) {
260     upb_fielddef *f = upb_msg_iter_field(&j);
261     UPB_ASSERT(f->msgdef == m);
262     if (upb_fielddef_issubmsg(f)) {
263       m->submsg_field_count++;
264     }
265     fields[i] = f;
266   }
267
268   qsort(fields, n, sizeof(*fields), cmp_fields);
269
270   selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
271   for (i = 0; i < n; i++) {
272     upb_fielddef *f = fields[i];
273     f->index_ = i;
274     f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
275     selector += upb_handlers_selectorcount(f);
276   }
277   m->selector_count = selector;
278
279   for(upb_msg_oneof_begin(&k, m), i = 0;
280       !upb_msg_oneof_done(&k);
281       upb_msg_oneof_next(&k), i++) {
282     upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k);
283     o->index = i;
284   }
285
286   upb_gfree(fields);
287   return true;
288 }
289
290 static void assign_msg_wellknowntype(upb_msgdef *m) {
291   const char *name = upb_msgdef_fullname(m);
292   if (name == NULL) {
293     m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
294     return;
295   }
296   if (!strcmp(name, "google.protobuf.Any")) {
297     m->well_known_type = UPB_WELLKNOWN_ANY;
298   } else if (!strcmp(name, "google.protobuf.FieldMask")) {
299     m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
300   } else if (!strcmp(name, "google.protobuf.Duration")) {
301     m->well_known_type = UPB_WELLKNOWN_DURATION;
302   } else if (!strcmp(name, "google.protobuf.Timestamp")) {
303     m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
304   } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
305     m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
306   } else if (!strcmp(name, "google.protobuf.FloatValue")) {
307     m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
308   } else if (!strcmp(name, "google.protobuf.Int64Value")) {
309     m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
310   } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
311     m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
312   } else if (!strcmp(name, "google.protobuf.Int32Value")) {
313     m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
314   } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
315     m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
316   } else if (!strcmp(name, "google.protobuf.BoolValue")) {
317     m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
318   } else if (!strcmp(name, "google.protobuf.StringValue")) {
319     m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
320   } else if (!strcmp(name, "google.protobuf.BytesValue")) {
321     m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
322   } else if (!strcmp(name, "google.protobuf.Value")) {
323     m->well_known_type = UPB_WELLKNOWN_VALUE;
324   } else if (!strcmp(name, "google.protobuf.ListValue")) {
325     m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
326   } else if (!strcmp(name, "google.protobuf.Struct")) {
327     m->well_known_type = UPB_WELLKNOWN_STRUCT;
328   } else {
329     m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
330   }
331 }
332
333
334 /* upb_enumdef ****************************************************************/
335
336 const char *upb_enumdef_fullname(const upb_enumdef *e) {
337   return e->full_name;
338 }
339
340 const char *upb_enumdef_name(const upb_enumdef *e) {
341   return shortdefname(e->full_name);
342 }
343
344 const upb_filedef *upb_enumdef_file(const upb_enumdef *e) {
345   return e->file;
346 }
347
348 int32_t upb_enumdef_default(const upb_enumdef *e) {
349   UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
350   return e->defaultval;
351 }
352
353 int upb_enumdef_numvals(const upb_enumdef *e) {
354   return upb_strtable_count(&e->ntoi);
355 }
356
357 void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
358   /* We iterate over the ntoi table, to account for duplicate numbers. */
359   upb_strtable_begin(i, &e->ntoi);
360 }
361
362 void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
363 bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
364
365 bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
366                       size_t len, int32_t *num) {
367   upb_value v;
368   if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
369     return false;
370   }
371   if (num) *num = upb_value_getint32(v);
372   return true;
373 }
374
375 const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
376   upb_value v;
377   return upb_inttable_lookup32(&def->iton, num, &v) ?
378       upb_value_getcstr(v) : NULL;
379 }
380
381 const char *upb_enum_iter_name(upb_enum_iter *iter) {
382   return upb_strtable_iter_key(iter);
383 }
384
385 int32_t upb_enum_iter_number(upb_enum_iter *iter) {
386   return upb_value_getint32(upb_strtable_iter_value(iter));
387 }
388
389
390 /* upb_fielddef ***************************************************************/
391
392 const char *upb_fielddef_fullname(const upb_fielddef *f) {
393   return f->full_name;
394 }
395
396 upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
397   switch (f->type_) {
398     case UPB_DESCRIPTOR_TYPE_DOUBLE:
399       return UPB_TYPE_DOUBLE;
400     case UPB_DESCRIPTOR_TYPE_FLOAT:
401       return UPB_TYPE_FLOAT;
402     case UPB_DESCRIPTOR_TYPE_INT64:
403     case UPB_DESCRIPTOR_TYPE_SINT64:
404     case UPB_DESCRIPTOR_TYPE_SFIXED64:
405       return UPB_TYPE_INT64;
406     case UPB_DESCRIPTOR_TYPE_INT32:
407     case UPB_DESCRIPTOR_TYPE_SFIXED32:
408     case UPB_DESCRIPTOR_TYPE_SINT32:
409       return UPB_TYPE_INT32;
410     case UPB_DESCRIPTOR_TYPE_UINT64:
411     case UPB_DESCRIPTOR_TYPE_FIXED64:
412       return UPB_TYPE_UINT64;
413     case UPB_DESCRIPTOR_TYPE_UINT32:
414     case UPB_DESCRIPTOR_TYPE_FIXED32:
415       return UPB_TYPE_UINT32;
416     case UPB_DESCRIPTOR_TYPE_ENUM:
417       return UPB_TYPE_ENUM;
418     case UPB_DESCRIPTOR_TYPE_BOOL:
419       return UPB_TYPE_BOOL;
420     case UPB_DESCRIPTOR_TYPE_STRING:
421       return UPB_TYPE_STRING;
422     case UPB_DESCRIPTOR_TYPE_BYTES:
423       return UPB_TYPE_BYTES;
424     case UPB_DESCRIPTOR_TYPE_GROUP:
425     case UPB_DESCRIPTOR_TYPE_MESSAGE:
426       return UPB_TYPE_MESSAGE;
427   }
428   UPB_UNREACHABLE();
429 }
430
431 upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
432   return f->type_;
433 }
434
435 uint32_t upb_fielddef_index(const upb_fielddef *f) {
436   return f->index_;
437 }
438
439 upb_label_t upb_fielddef_label(const upb_fielddef *f) {
440   return f->label_;
441 }
442
443 uint32_t upb_fielddef_number(const upb_fielddef *f) {
444   return f->number_;
445 }
446
447 bool upb_fielddef_isextension(const upb_fielddef *f) {
448   return f->is_extension_;
449 }
450
451 bool upb_fielddef_lazy(const upb_fielddef *f) {
452   return f->lazy_;
453 }
454
455 bool upb_fielddef_packed(const upb_fielddef *f) {
456   return f->packed_;
457 }
458
459 const char *upb_fielddef_name(const upb_fielddef *f) {
460   return shortdefname(f->full_name);
461 }
462
463 uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
464   return f->selector_base;
465 }
466
467 size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
468   const char *name = upb_fielddef_name(f);
469   size_t src, dst = 0;
470   bool ucase_next = false;
471
472 #define WRITE(byte) \
473   ++dst; \
474   if (dst < len) buf[dst - 1] = byte; \
475   else if (dst == len) buf[dst - 1] = '\0'
476
477   if (!name) {
478     WRITE('\0');
479     return 0;
480   }
481
482   /* Implement the transformation as described in the spec:
483    *   1. upper case all letters after an underscore.
484    *   2. remove all underscores.
485    */
486   for (src = 0; name[src]; src++) {
487     if (name[src] == '_') {
488       ucase_next = true;
489       continue;
490     }
491
492     if (ucase_next) {
493       WRITE(toupper(name[src]));
494       ucase_next = false;
495     } else {
496       WRITE(name[src]);
497     }
498   }
499
500   WRITE('\0');
501   return dst;
502
503 #undef WRITE
504 }
505
506 const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
507   return f->msgdef;
508 }
509
510 const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
511   return f->oneof;
512 }
513
514 static void chkdefaulttype(const upb_fielddef *f, int ctype) {
515   UPB_UNUSED(f);
516   UPB_UNUSED(ctype);
517 }
518
519 int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
520   chkdefaulttype(f, UPB_TYPE_INT64);
521   return f->defaultval.sint;
522 }
523
524 int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
525   chkdefaulttype(f, UPB_TYPE_INT32);
526   return f->defaultval.sint;
527 }
528
529 uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
530   chkdefaulttype(f, UPB_TYPE_UINT64);
531   return f->defaultval.uint;
532 }
533
534 uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
535   chkdefaulttype(f, UPB_TYPE_UINT32);
536   return f->defaultval.uint;
537 }
538
539 bool upb_fielddef_defaultbool(const upb_fielddef *f) {
540   chkdefaulttype(f, UPB_TYPE_BOOL);
541   return f->defaultval.boolean;
542 }
543
544 float upb_fielddef_defaultfloat(const upb_fielddef *f) {
545   chkdefaulttype(f, UPB_TYPE_FLOAT);
546   return f->defaultval.flt;
547 }
548
549 double upb_fielddef_defaultdouble(const upb_fielddef *f) {
550   chkdefaulttype(f, UPB_TYPE_DOUBLE);
551   return f->defaultval.dbl;
552 }
553
554 const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
555   str_t *str = f->defaultval.str;
556   UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING ||
557          upb_fielddef_type(f) == UPB_TYPE_BYTES ||
558          upb_fielddef_type(f) == UPB_TYPE_ENUM);
559   if (str) {
560     if (len) *len = str->len;
561     return str->str;
562   } else {
563     if (len) *len = 0;
564     return NULL;
565   }
566 }
567
568 const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
569   UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
570   return f->sub.msgdef;
571 }
572
573 const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
574   UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_ENUM);
575   return f->sub.enumdef;
576 }
577
578 bool upb_fielddef_issubmsg(const upb_fielddef *f) {
579   return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
580 }
581
582 bool upb_fielddef_isstring(const upb_fielddef *f) {
583   return upb_fielddef_type(f) == UPB_TYPE_STRING ||
584          upb_fielddef_type(f) == UPB_TYPE_BYTES;
585 }
586
587 bool upb_fielddef_isseq(const upb_fielddef *f) {
588   return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
589 }
590
591 bool upb_fielddef_isprimitive(const upb_fielddef *f) {
592   return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
593 }
594
595 bool upb_fielddef_ismap(const upb_fielddef *f) {
596   return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
597          upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
598 }
599
600 bool upb_fielddef_hassubdef(const upb_fielddef *f) {
601   return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
602 }
603
604 bool upb_fielddef_haspresence(const upb_fielddef *f) {
605   if (upb_fielddef_isseq(f)) return false;
606   if (upb_fielddef_issubmsg(f)) return true;
607   return f->file->syntax == UPB_SYNTAX_PROTO2;
608 }
609
610 static bool between(int32_t x, int32_t low, int32_t high) {
611   return x >= low && x <= high;
612 }
613
614 bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
615 bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
616 bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
617
618 bool upb_fielddef_checkdescriptortype(int32_t type) {
619   return between(type, 1, 18);
620 }
621
622 /* upb_msgdef *****************************************************************/
623
624 const char *upb_msgdef_fullname(const upb_msgdef *m) {
625   return m->full_name;
626 }
627
628 const upb_filedef *upb_msgdef_file(const upb_msgdef *m) {
629   return m->file;
630 }
631
632 const char *upb_msgdef_name(const upb_msgdef *m) {
633   return shortdefname(m->full_name);
634 }
635
636 upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
637   return m->file->syntax;
638 }
639
640 size_t upb_msgdef_selectorcount(const upb_msgdef *m) {
641   return m->selector_count;
642 }
643
644 uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) {
645   return m->submsg_field_count;
646 }
647
648 const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
649   upb_value val;
650   return upb_inttable_lookup32(&m->itof, i, &val) ?
651       upb_value_getconstptr(val) : NULL;
652 }
653
654 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
655                                     size_t len) {
656   upb_value val;
657
658   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
659     return NULL;
660   }
661
662   return unpack_def(val, UPB_DEFTYPE_FIELD);
663 }
664
665 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
666                                     size_t len) {
667   upb_value val;
668
669   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
670     return NULL;
671   }
672
673   return unpack_def(val, UPB_DEFTYPE_ONEOF);
674 }
675
676 bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
677                            const upb_fielddef **f, const upb_oneofdef **o) {
678   upb_value val;
679
680   if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
681     return false;
682   }
683
684   *o = unpack_def(val, UPB_DEFTYPE_ONEOF);
685   *f = unpack_def(val, UPB_DEFTYPE_FIELD);
686   UPB_ASSERT((*o != NULL) ^ (*f != NULL));  /* Exactly one of the two should be set. */
687   return true;
688 }
689
690 int upb_msgdef_numfields(const upb_msgdef *m) {
691   /* The number table contains only fields. */
692   return upb_inttable_count(&m->itof);
693 }
694
695 int upb_msgdef_numoneofs(const upb_msgdef *m) {
696   /* The name table includes oneofs, and the number table does not. */
697   return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
698 }
699
700 bool upb_msgdef_mapentry(const upb_msgdef *m) {
701   return m->map_entry;
702 }
703
704 upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) {
705   return m->well_known_type;
706 }
707
708 bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) {
709   upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
710   return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
711          type <= UPB_WELLKNOWN_UINT32VALUE;
712 }
713
714 void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
715   upb_inttable_begin(iter, &m->itof);
716 }
717
718 void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
719
720 bool upb_msg_field_done(const upb_msg_field_iter *iter) {
721   return upb_inttable_done(iter);
722 }
723
724 upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
725   return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
726 }
727
728 void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
729   upb_inttable_iter_setdone(iter);
730 }
731
732 bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,
733                                 const upb_msg_field_iter * iter2) {
734   return upb_inttable_iter_isequal(iter1, iter2);
735 }
736
737 void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
738   upb_strtable_begin(iter, &m->ntof);
739   /* We need to skip past any initial fields. */
740   while (!upb_strtable_done(iter) &&
741          !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) {
742     upb_strtable_next(iter);
743   }
744 }
745
746 void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
747   /* We need to skip past fields to return only oneofs. */
748   do {
749     upb_strtable_next(iter);
750   } while (!upb_strtable_done(iter) &&
751            !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF));
752 }
753
754 bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
755   return upb_strtable_done(iter);
756 }
757
758 const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
759   return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF);
760 }
761
762 void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
763   upb_strtable_iter_setdone(iter);
764 }
765
766 bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
767                                 const upb_msg_oneof_iter *iter2) {
768   return upb_strtable_iter_isequal(iter1, iter2);
769 }
770
771 /* upb_oneofdef ***************************************************************/
772
773 const char *upb_oneofdef_name(const upb_oneofdef *o) {
774   return shortdefname(o->full_name);
775 }
776
777 const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
778   return o->parent;
779 }
780
781 int upb_oneofdef_numfields(const upb_oneofdef *o) {
782   return upb_strtable_count(&o->ntof);
783 }
784
785 uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
786   return o->index;
787 }
788
789 const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
790                                       const char *name, size_t length) {
791   upb_value val;
792   return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
793       upb_value_getptr(val) : NULL;
794 }
795
796 const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
797   upb_value val;
798   return upb_inttable_lookup32(&o->itof, num, &val) ?
799       upb_value_getptr(val) : NULL;
800 }
801
802 void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
803   upb_inttable_begin(iter, &o->itof);
804 }
805
806 void upb_oneof_next(upb_oneof_iter *iter) {
807   upb_inttable_next(iter);
808 }
809
810 bool upb_oneof_done(upb_oneof_iter *iter) {
811   return upb_inttable_done(iter);
812 }
813
814 upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
815   return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter));
816 }
817
818 void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
819   upb_inttable_iter_setdone(iter);
820 }
821
822 /* Code to build defs from descriptor protos. *********************************/
823
824 /* There is a question of how much validation to do here.  It will be difficult
825  * to perfectly match the amount of validation performed by proto2.  But since
826  * this code is used to directly build defs from Ruby (for example) we do need
827  * to validate important constraints like uniqueness of names and numbers. */
828
829 #define CHK(x) if (!(x)) { return false; }
830 #define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; }
831
832 typedef struct {
833   const upb_symtab *symtab;
834   upb_filedef *file;  /* File we are building. */
835   upb_alloc *alloc;    /* Allocate defs here. */
836   upb_alloc *tmp;      /* Alloc for addtab and any other tmp data. */
837   upb_strtable *addtab;  /* full_name -> packed def ptr for new defs. */
838   upb_status *status;  /* Record errors here. */
839 } symtab_addctx;
840
841 static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
842   return upb_strdup2(view.data, view.size, ctx->alloc);
843 }
844
845 static bool streql2(const char *a, size_t n, const char *b) {
846   return n == strlen(b) && memcmp(a, b, n) == 0;
847 }
848
849 static bool streql_view(upb_strview view, const char *b) {
850   return streql2(view.data, view.size, b);
851 }
852
853 static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
854                                 upb_strview name) {
855   if (prefix) {
856     /* ret = prefix + '.' + name; */
857     size_t n = strlen(prefix);
858     char *ret = upb_malloc(ctx->alloc, n + name.size + 2);
859     CHK_OOM(ret);
860     strcpy(ret, prefix);
861     ret[n] = '.';
862     memcpy(&ret[n + 1], name.data, name.size);
863     ret[n + 1 + name.size] = '\0';
864     return ret;
865   } else {
866     return strviewdup(ctx, name);
867   }
868 }
869
870 static bool symtab_add(const symtab_addctx *ctx, const char *name,
871                        upb_value v) {
872   upb_value tmp;
873   if (upb_strtable_lookup(ctx->addtab, name, &tmp) ||
874       upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) {
875     upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name);
876     return false;
877   }
878
879   CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp));
880   return true;
881 }
882
883 /* Given a symbol and the base symbol inside which it is defined, find the
884  * symbol's definition in t. */
885 static bool resolvename(const upb_strtable *t, const upb_fielddef *f,
886                         const char *base, upb_strview sym,
887                         upb_deftype_t type, upb_status *status,
888                         const void **def) {
889   if(sym.size == 0) return NULL;
890   if(sym.data[0] == '.') {
891     /* Symbols starting with '.' are absolute, so we do a single lookup.
892      * Slice to omit the leading '.' */
893     upb_value v;
894     if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
895       return false;
896     }
897
898     *def = unpack_def(v, type);
899
900     if (!*def) {
901       upb_status_seterrf(status,
902                          "type mismatch when resolving field %s, name %s",
903                          f->full_name, sym.data);
904       return false;
905     }
906
907     return true;
908   } else {
909     /* Remove components from base until we find an entry or run out.
910      * TODO: This branch is totally broken, but currently not used. */
911     (void)base;
912     UPB_ASSERT(false);
913     return false;
914   }
915 }
916
917 const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f,
918                            const char *base, upb_strview sym,
919                            upb_deftype_t type) {
920   const void *ret;
921   if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) &&
922       !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) {
923     if (upb_ok(ctx->status)) {
924       upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data);
925     }
926     return false;
927   }
928   return ret;
929 }
930
931 static bool create_oneofdef(
932     const symtab_addctx *ctx, upb_msgdef *m,
933     const google_protobuf_OneofDescriptorProto *oneof_proto) {
934   upb_oneofdef *o;
935   upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
936   upb_value v;
937
938   o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
939   o->parent = m;
940   o->full_name = makefullname(ctx, m->full_name, name);
941
942   v = pack_def(o, UPB_DEFTYPE_ONEOF);
943   CHK_OOM(symtab_add(ctx, o->full_name, v));
944   CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
945
946   CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
947   CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
948
949   return true;
950 }
951
952 static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
953                           upb_fielddef *f) {
954   char *end;
955   char nullz[64];
956   errno = 0;
957
958   switch (upb_fielddef_type(f)) {
959     case UPB_TYPE_INT32:
960     case UPB_TYPE_INT64:
961     case UPB_TYPE_UINT32:
962     case UPB_TYPE_UINT64:
963     case UPB_TYPE_DOUBLE:
964     case UPB_TYPE_FLOAT:
965       /* Standard C number parsing functions expect null-terminated strings. */
966       if (len >= sizeof(nullz) - 1) {
967         return false;
968       }
969       memcpy(nullz, str, len);
970       nullz[len] = '\0';
971       str = nullz;
972       break;
973     default:
974       break;
975   }
976
977   switch (upb_fielddef_type(f)) {
978     case UPB_TYPE_INT32: {
979       long val = strtol(str, &end, 0);
980       CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end);
981       f->defaultval.sint = val;
982       break;
983     }
984     case UPB_TYPE_ENUM: {
985       const upb_enumdef *e = f->sub.enumdef;
986       int32_t val;
987       CHK(upb_enumdef_ntoi(e, str, len, &val));
988       f->defaultval.sint = val;
989       break;
990     }
991     case UPB_TYPE_INT64: {
992       /* XXX: Need to write our own strtoll, since it's not available in c89. */
993       long long val = strtol(str, &end, 0);
994       CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
995       f->defaultval.sint = val;
996       break;
997     }
998     case UPB_TYPE_UINT32: {
999       unsigned long val = strtoul(str, &end, 0);
1000       CHK(val <= UINT32_MAX && errno != ERANGE && !*end);
1001       f->defaultval.uint = val;
1002       break;
1003     }
1004     case UPB_TYPE_UINT64: {
1005       /* XXX: Need to write our own strtoull, since it's not available in c89. */
1006       unsigned long long val = strtoul(str, &end, 0);
1007       CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
1008       f->defaultval.uint = val;
1009       break;
1010     }
1011     case UPB_TYPE_DOUBLE: {
1012       double val = strtod(str, &end);
1013       CHK(errno != ERANGE && !*end);
1014       f->defaultval.dbl = val;
1015       break;
1016     }
1017     case UPB_TYPE_FLOAT: {
1018       /* XXX: Need to write our own strtof, since it's not available in c89. */
1019       float val = strtod(str, &end);
1020       CHK(errno != ERANGE && !*end);
1021       f->defaultval.flt = val;
1022       break;
1023     }
1024     case UPB_TYPE_BOOL: {
1025       if (streql2(str, len, "false")) {
1026         f->defaultval.boolean = false;
1027       } else if (streql2(str, len, "true")) {
1028         f->defaultval.boolean = true;
1029       } else {
1030         return false;
1031       }
1032     }
1033     case UPB_TYPE_STRING:
1034       f->defaultval.str = newstr(ctx->alloc, str, len);
1035       break;
1036     case UPB_TYPE_BYTES:
1037       /* XXX: need to interpret the C-escaped value. */
1038       f->defaultval.str = newstr(ctx->alloc, str, len);
1039       break;
1040     case UPB_TYPE_MESSAGE:
1041       /* Should not have a default value. */
1042       return false;
1043   }
1044   return true;
1045 }
1046
1047 static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) {
1048   switch (upb_fielddef_type(f)) {
1049     case UPB_TYPE_INT32:
1050     case UPB_TYPE_INT64:
1051     case UPB_TYPE_ENUM:
1052       f->defaultval.sint = 0;
1053       break;
1054     case UPB_TYPE_UINT64:
1055     case UPB_TYPE_UINT32:
1056       f->defaultval.uint = 0;
1057       break;
1058     case UPB_TYPE_DOUBLE:
1059     case UPB_TYPE_FLOAT:
1060       f->defaultval.dbl = 0;
1061       break;
1062     case UPB_TYPE_STRING:
1063     case UPB_TYPE_BYTES:
1064       f->defaultval.str = newstr(ctx->alloc, NULL, 0);
1065       break;
1066     case UPB_TYPE_BOOL:
1067       f->defaultval.boolean = false;
1068       break;
1069     case UPB_TYPE_MESSAGE:
1070       break;
1071   }
1072 }
1073
1074 static bool create_fielddef(
1075     const symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
1076     const google_protobuf_FieldDescriptorProto *field_proto) {
1077   upb_alloc *alloc = ctx->alloc;
1078   upb_fielddef *f;
1079   const google_protobuf_FieldOptions *options;
1080   upb_strview name;
1081   const char *full_name;
1082   const char *shortname;
1083   uint32_t field_number;
1084
1085   if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
1086     upb_status_seterrmsg(ctx->status, "field has no name");
1087     return false;
1088   }
1089
1090   name = google_protobuf_FieldDescriptorProto_name(field_proto);
1091   CHK(upb_isident(name, false, ctx->status));
1092   full_name = makefullname(ctx, prefix, name);
1093   shortname = shortdefname(full_name);
1094
1095   field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
1096
1097   if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
1098     upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number);
1099     return false;
1100   }
1101
1102   if (m) {
1103     /* direct message field. */
1104     upb_value v, packed_v;
1105
1106     f = (upb_fielddef*)&m->fields[m->field_count++];
1107     f->msgdef = m;
1108     f->is_extension_ = false;
1109
1110     packed_v = pack_def(f, UPB_DEFTYPE_FIELD);
1111     v = upb_value_constptr(f);
1112
1113     if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) {
1114       upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname);
1115       return false;
1116     }
1117
1118     if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) {
1119       upb_status_seterrf(ctx->status, "duplicate field number (%u)",
1120                          field_number);
1121       return false;
1122     }
1123   } else {
1124     /* extension field. */
1125     f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count];
1126     f->is_extension_ = true;
1127     CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)));
1128   }
1129
1130   f->full_name = full_name;
1131   f->file = ctx->file;
1132   f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
1133   f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
1134   f->number_ = field_number;
1135   f->oneof = NULL;
1136
1137   /* We can't resolve the subdef or (in the case of extensions) the containing
1138    * message yet, because it may not have been defined yet.  We stash a pointer
1139    * to the field_proto until later when we can properly resolve it. */
1140   f->sub.unresolved = field_proto;
1141
1142   if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
1143     upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)",
1144                        f->full_name);
1145     return false;
1146   }
1147
1148   if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
1149     int oneof_index =
1150         google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
1151     upb_oneofdef *oneof;
1152     upb_value v = upb_value_constptr(f);
1153
1154     if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
1155       upb_status_seterrf(ctx->status,
1156                          "fields in oneof must have OPTIONAL label (%s)",
1157                          f->full_name);
1158       return false;
1159     }
1160
1161     if (!m) {
1162       upb_status_seterrf(ctx->status,
1163                          "oneof_index provided for extension field (%s)",
1164                          f->full_name);
1165       return false;
1166     }
1167
1168     if (oneof_index >= m->oneof_count) {
1169       upb_status_seterrf(ctx->status, "oneof_index out of range (%s)",
1170                          f->full_name);
1171       return false;
1172     }
1173
1174     oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
1175     f->oneof = oneof;
1176
1177     CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
1178     CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
1179   } else {
1180     f->oneof = NULL;
1181   }
1182
1183   if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) {
1184     options = google_protobuf_FieldDescriptorProto_options(field_proto);
1185     f->lazy_ = google_protobuf_FieldOptions_lazy(options);
1186     f->packed_ = google_protobuf_FieldOptions_packed(options);
1187   } else {
1188     f->lazy_ = false;
1189     f->packed_ = false;
1190   }
1191
1192   return true;
1193 }
1194
1195 static bool create_enumdef(
1196     const symtab_addctx *ctx, const char *prefix,
1197     const google_protobuf_EnumDescriptorProto *enum_proto) {
1198   upb_enumdef *e;
1199   const google_protobuf_EnumValueDescriptorProto *const *values;
1200   upb_strview name;
1201   size_t i, n;
1202
1203   name = google_protobuf_EnumDescriptorProto_name(enum_proto);
1204   CHK(upb_isident(name, false, ctx->status));
1205
1206   e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
1207   e->full_name = makefullname(ctx, prefix, name);
1208   CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)));
1209
1210   CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc));
1211   CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
1212
1213   e->file = ctx->file;
1214   e->defaultval = 0;
1215
1216   values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
1217
1218   if (n == 0) {
1219     upb_status_seterrf(ctx->status,
1220                        "enums must contain at least one value (%s)",
1221                        e->full_name);
1222     return false;
1223   }
1224
1225   for (i = 0; i < n; i++) {
1226     const google_protobuf_EnumValueDescriptorProto *value = values[i];
1227     upb_strview name = google_protobuf_EnumValueDescriptorProto_name(value);
1228     char *name2 = strviewdup(ctx, name);
1229     int32_t num = google_protobuf_EnumValueDescriptorProto_number(value);
1230     upb_value v = upb_value_int32(num);
1231
1232     if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
1233       upb_status_seterrf(ctx->status,
1234                          "for proto3, the first enum value must be zero (%s)",
1235                          e->full_name);
1236       return false;
1237     }
1238
1239     if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
1240       upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2);
1241       return false;
1242     }
1243
1244     CHK_OOM(name2)
1245     CHK_OOM(
1246         upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
1247
1248     if (!upb_inttable_lookup(&e->iton, num, NULL)) {
1249       upb_value v = upb_value_cstr(name2);
1250       CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
1251     }
1252   }
1253
1254   upb_inttable_compact2(&e->iton, ctx->alloc);
1255
1256   return true;
1257 }
1258
1259 static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
1260                           const google_protobuf_DescriptorProto *msg_proto) {
1261   upb_msgdef *m;
1262   const google_protobuf_MessageOptions *options;
1263   const google_protobuf_OneofDescriptorProto *const *oneofs;
1264   const google_protobuf_FieldDescriptorProto *const *fields;
1265   const google_protobuf_EnumDescriptorProto *const *enums;
1266   const google_protobuf_DescriptorProto *const *msgs;
1267   size_t i, n;
1268   upb_strview name;
1269
1270   name = google_protobuf_DescriptorProto_name(msg_proto);
1271   CHK(upb_isident(name, false, ctx->status));
1272
1273   m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
1274   m->full_name = makefullname(ctx, prefix, name);
1275   CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)));
1276
1277   CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
1278   CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
1279
1280   m->file = ctx->file;
1281   m->map_entry = false;
1282
1283   options = google_protobuf_DescriptorProto_options(msg_proto);
1284
1285   if (options) {
1286     m->map_entry = google_protobuf_MessageOptions_map_entry(options);
1287   }
1288
1289   oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
1290   m->oneof_count = 0;
1291   m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
1292   for (i = 0; i < n; i++) {
1293     CHK(create_oneofdef(ctx, m, oneofs[i]));
1294   }
1295
1296   fields = google_protobuf_DescriptorProto_field(msg_proto, &n);
1297   m->field_count = 0;
1298   m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n);
1299   for (i = 0; i < n; i++) {
1300     CHK(create_fielddef(ctx, m->full_name, m, fields[i]));
1301   }
1302
1303   CHK(assign_msg_indices(m, ctx->status));
1304   assign_msg_wellknowntype(m);
1305   upb_inttable_compact2(&m->itof, ctx->alloc);
1306
1307   /* This message is built.  Now build nested messages and enums. */
1308
1309   enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
1310   for (i = 0; i < n; i++) {
1311     CHK(create_enumdef(ctx, m->full_name, enums[i]));
1312   }
1313
1314   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
1315   for (i = 0; i < n; i++) {
1316     CHK(create_msgdef(ctx, m->full_name, msgs[i]));
1317   }
1318
1319   return true;
1320 }
1321
1322 typedef struct {
1323   int msg_count;
1324   int enum_count;
1325   int ext_count;
1326 } decl_counts;
1327
1328 static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto,
1329                                decl_counts *counts) {
1330   const google_protobuf_DescriptorProto *const *msgs;
1331   size_t i, n;
1332
1333   counts->msg_count++;
1334
1335   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
1336   for (i = 0; i < n; i++) {
1337     count_types_in_msg(msgs[i], counts);
1338   }
1339
1340   google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
1341   counts->enum_count += n;
1342
1343   google_protobuf_DescriptorProto_extension(msg_proto, &n);
1344   counts->ext_count += n;
1345 }
1346
1347 static void count_types_in_file(
1348     const google_protobuf_FileDescriptorProto *file_proto,
1349     decl_counts *counts) {
1350   const google_protobuf_DescriptorProto *const *msgs;
1351   size_t i, n;
1352
1353   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
1354   for (i = 0; i < n; i++) {
1355     count_types_in_msg(msgs[i], counts);
1356   }
1357
1358   google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
1359   counts->enum_count += n;
1360
1361   google_protobuf_FileDescriptorProto_extension(file_proto, &n);
1362   counts->ext_count += n;
1363 }
1364
1365 static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
1366                              upb_fielddef *f) {
1367   upb_strview name;
1368   const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
1369
1370   if (f->is_extension_) {
1371     if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
1372       upb_status_seterrf(ctx->status,
1373                          "extension for field '%s' had no extendee",
1374                          f->full_name);
1375       return false;
1376     }
1377
1378     name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
1379     f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
1380     CHK(f->msgdef);
1381   }
1382
1383   if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
1384       !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) {
1385     upb_status_seterrf(ctx->status, "field '%s' is missing type name",
1386                        f->full_name);
1387     return false;
1388   }
1389
1390   name = google_protobuf_FieldDescriptorProto_type_name(field_proto);
1391
1392   if (upb_fielddef_issubmsg(f)) {
1393     f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
1394     CHK(f->sub.msgdef);
1395   } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
1396     f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
1397     CHK(f->sub.enumdef);
1398   }
1399
1400   /* Have to delay resolving of the default value until now because of the enum
1401    * case, since enum defaults are specified with a label. */
1402   if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
1403     upb_strview defaultval =
1404         google_protobuf_FieldDescriptorProto_default_value(field_proto);
1405
1406     if (f->file->syntax == UPB_SYNTAX_PROTO3) {
1407       upb_status_seterrf(ctx->status,
1408                          "proto3 fields cannot have explicit defaults (%s)",
1409                          f->full_name);
1410       return false;
1411     }
1412
1413     if (upb_fielddef_issubmsg(f)) {
1414       upb_status_seterrf(ctx->status,
1415                          "message fields cannot have explicit defaults (%s)",
1416                          f->full_name);
1417       return false;
1418     }
1419
1420     if (!parse_default(ctx, defaultval.data, defaultval.size, f)) {
1421       upb_status_seterrf(ctx->status,
1422                          "couldn't parse default '" UPB_STRVIEW_FORMAT
1423                          "' for field (%s)",
1424                          UPB_STRVIEW_ARGS(defaultval), f->full_name);
1425       return false;
1426     }
1427   } else {
1428     set_default_default(ctx, f);
1429   }
1430
1431   return true;
1432 }
1433
1434 static bool build_filedef(
1435     const symtab_addctx *ctx, upb_filedef *file,
1436     const google_protobuf_FileDescriptorProto *file_proto) {
1437   upb_alloc *alloc = ctx->alloc;
1438   const google_protobuf_FileOptions *file_options_proto;
1439   const google_protobuf_DescriptorProto *const *msgs;
1440   const google_protobuf_EnumDescriptorProto *const *enums;
1441   const google_protobuf_FieldDescriptorProto *const *exts;
1442   const upb_strview* strs;
1443   size_t i, n;
1444   decl_counts counts = {0};
1445
1446   count_types_in_file(file_proto, &counts);
1447
1448   file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count);
1449   file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count);
1450   file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count);
1451
1452   CHK_OOM(counts.msg_count == 0 || file->msgs);
1453   CHK_OOM(counts.enum_count == 0 || file->enums);
1454   CHK_OOM(counts.ext_count == 0 || file->exts);
1455
1456   /* We increment these as defs are added. */
1457   file->msg_count = 0;
1458   file->enum_count = 0;
1459   file->ext_count = 0;
1460
1461   if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
1462     upb_status_seterrmsg(ctx->status, "File has no name");
1463     return false;
1464   }
1465
1466   file->name =
1467       strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
1468   file->phpprefix = NULL;
1469   file->phpnamespace = NULL;
1470
1471   if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
1472     upb_strview package =
1473         google_protobuf_FileDescriptorProto_package(file_proto);
1474     CHK(upb_isident(package, true, ctx->status));
1475     file->package = strviewdup(ctx, package);
1476   } else {
1477     file->package = NULL;
1478   }
1479
1480   if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) {
1481     upb_strview syntax =
1482         google_protobuf_FileDescriptorProto_syntax(file_proto);
1483
1484     if (streql_view(syntax, "proto2")) {
1485       file->syntax = UPB_SYNTAX_PROTO2;
1486     } else if (streql_view(syntax, "proto3")) {
1487       file->syntax = UPB_SYNTAX_PROTO3;
1488     } else {
1489       upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax);
1490       return false;
1491     }
1492   } else {
1493     file->syntax = UPB_SYNTAX_PROTO2;
1494   }
1495
1496   /* Read options. */
1497   file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
1498   if (file_options_proto) {
1499     if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) {
1500       file->phpprefix = strviewdup(
1501           ctx,
1502           google_protobuf_FileOptions_php_class_prefix(file_options_proto));
1503     }
1504     if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) {
1505       file->phpnamespace = strviewdup(
1506           ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
1507     }
1508   }
1509
1510   /* Verify dependencies. */
1511   strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
1512   file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ;
1513   CHK_OOM(n == 0 || file->deps);
1514
1515   for (i = 0; i < n; i++) {
1516     upb_strview dep_name = strs[i];
1517     upb_value v;
1518     if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
1519                               dep_name.size, &v)) {
1520       upb_status_seterrf(ctx->status,
1521                          "Depends on file '" UPB_STRVIEW_FORMAT
1522                          "', but it has not been loaded",
1523                          UPB_STRVIEW_ARGS(dep_name));
1524       return false;
1525     }
1526     file->deps[i] = upb_value_getconstptr(v);
1527   }
1528
1529   /* Create messages. */
1530   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
1531   for (i = 0; i < n; i++) {
1532     CHK(create_msgdef(ctx, file->package, msgs[i]));
1533   }
1534
1535   /* Create enums. */
1536   enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
1537   for (i = 0; i < n; i++) {
1538     CHK(create_enumdef(ctx, file->package, enums[i]));
1539   }
1540
1541   /* Create extensions. */
1542   exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
1543   file->exts = upb_malloc(alloc, sizeof(*file->exts) * n);
1544   CHK_OOM(n == 0 || file->exts);
1545   for (i = 0; i < n; i++) {
1546     CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
1547   }
1548
1549   /* Now that all names are in the table, resolve references. */
1550   for (i = 0; i < file->ext_count; i++) {
1551     CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
1552   }
1553
1554   for (i = 0; i < file->msg_count; i++) {
1555     const upb_msgdef *m = &file->msgs[i];
1556     int j;
1557     for (j = 0; j < m->field_count; j++) {
1558       CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]));
1559     }
1560   }
1561
1562   return true;
1563  }
1564
1565 static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx,
1566                                  upb_status *status) {
1567   const upb_filedef *file = ctx->file;
1568   upb_alloc *alloc = upb_arena_alloc(s->arena);
1569   upb_strtable_iter iter;
1570
1571   CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name),
1572                                upb_value_constptr(file), alloc));
1573
1574   upb_strtable_begin(&iter, ctx->addtab);
1575   for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
1576     const char *key = upb_strtable_iter_key(&iter);
1577     size_t keylen = upb_strtable_iter_keylength(&iter);
1578     upb_value value = upb_strtable_iter_value(&iter);
1579     CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc));
1580   }
1581
1582   return true;
1583 }
1584
1585 /* upb_filedef ****************************************************************/
1586
1587 const char *upb_filedef_name(const upb_filedef *f) {
1588   return f->name;
1589 }
1590
1591 const char *upb_filedef_package(const upb_filedef *f) {
1592   return f->package;
1593 }
1594
1595 const char *upb_filedef_phpprefix(const upb_filedef *f) {
1596   return f->phpprefix;
1597 }
1598
1599 const char *upb_filedef_phpnamespace(const upb_filedef *f) {
1600   return f->phpnamespace;
1601 }
1602
1603 upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
1604   return f->syntax;
1605 }
1606
1607 int upb_filedef_msgcount(const upb_filedef *f) {
1608   return f->msg_count;
1609 }
1610
1611 int upb_filedef_depcount(const upb_filedef *f) {
1612   return f->dep_count;
1613 }
1614
1615 int upb_filedef_enumcount(const upb_filedef *f) {
1616   return f->enum_count;
1617 }
1618
1619 const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
1620   return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
1621 }
1622
1623 const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
1624   return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
1625 }
1626
1627 const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
1628   return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
1629 }
1630
1631 void upb_symtab_free(upb_symtab *s) {
1632   upb_arena_free(s->arena);
1633   upb_gfree(s);
1634 }
1635
1636 upb_symtab *upb_symtab_new(void) {
1637   upb_symtab *s = upb_gmalloc(sizeof(*s));
1638   upb_alloc *alloc;
1639
1640   if (!s) {
1641     return NULL;
1642   }
1643
1644   s->arena = upb_arena_new();
1645   alloc = upb_arena_alloc(s->arena);
1646
1647   if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) ||
1648       !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) {
1649     upb_arena_free(s->arena);
1650     upb_gfree(s);
1651     s = NULL;
1652   }
1653   return s;
1654 }
1655
1656 const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
1657   upb_value v;
1658   return upb_strtable_lookup(&s->syms, sym, &v) ?
1659       unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
1660 }
1661
1662 const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
1663                                         size_t len) {
1664   upb_value v;
1665   return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
1666       unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
1667 }
1668
1669 const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
1670   upb_value v;
1671   return upb_strtable_lookup(&s->syms, sym, &v) ?
1672       unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
1673 }
1674
1675 const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
1676   upb_value v;
1677   return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
1678                                                   : NULL;
1679 }
1680
1681 const upb_filedef *upb_symtab_addfile(
1682     upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
1683     upb_status *status) {
1684   upb_arena *tmparena = upb_arena_new();
1685   upb_strtable addtab;
1686   upb_alloc *alloc = upb_arena_alloc(s->arena);
1687   upb_filedef *file = upb_malloc(alloc, sizeof(*file));
1688   bool ok;
1689   symtab_addctx ctx;
1690
1691   ctx.file = file;
1692   ctx.symtab = s;
1693   ctx.alloc = alloc;
1694   ctx.tmp = upb_arena_alloc(tmparena);
1695   ctx.addtab = &addtab;
1696   ctx.status = status;
1697
1698   ok = file &&
1699       upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) &&
1700       build_filedef(&ctx, file, file_proto) &&
1701       upb_symtab_addtotabs(s, &ctx, status);
1702
1703   upb_arena_free(tmparena);
1704   return ok ? file : NULL;
1705 }
1706
1707 /* Include here since we want most of this file to be stdio-free. */
1708 #include <stdio.h>
1709
1710 bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
1711   /* Since this function should never fail (it would indicate a bug in upb) we
1712    * print errors to stderr instead of returning error status to the user. */
1713   upb_def_init **deps = init->deps;
1714   google_protobuf_FileDescriptorProto *file;
1715   upb_arena *arena;
1716   upb_status status;
1717
1718   upb_status_clear(&status);
1719
1720   if (upb_strtable_lookup(&s->files, init->filename, NULL)) {
1721     return true;
1722   }
1723
1724   arena = upb_arena_new();
1725
1726   for (; *deps; deps++) {
1727     if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
1728   }
1729
1730   file = google_protobuf_FileDescriptorProto_parse(
1731       init->descriptor.data, init->descriptor.size, arena);
1732
1733   if (!file) {
1734     upb_status_seterrf(
1735         &status,
1736         "Failed to parse compiled-in descriptor for file '%s'. This should "
1737         "never happen.",
1738         init->filename);
1739     goto err;
1740   }
1741
1742   if (!upb_symtab_addfile(s, file, &status)) goto err;
1743
1744   upb_arena_free(arena);
1745   return true;
1746
1747 err:
1748   fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
1749           upb_status_errmsg(&status));
1750   upb_arena_free(arena);
1751   return false;
1752 }
1753
1754 #undef CHK
1755 #undef CHK_OOM